Skip to content

Instantly share code, notes, and snippets.

@t0rr3sp3dr0
Last active February 20, 2024 01:24
Show Gist options
  • Save t0rr3sp3dr0/73d2bab0eef30bbb5a682d2419aa743f to your computer and use it in GitHub Desktop.
Save t0rr3sp3dr0/73d2bab0eef30bbb5a682d2419aa743f to your computer and use it in GitHub Desktop.
exec process within a macOS download quarantine context
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
enum qtn_flags {
QTN_FLAG_DOWNLOAD = 0x0001,
};
typedef struct _qtn_proc *qtn_proc_t;
#define qtn_proc_alloc _qtn_proc_alloc
qtn_proc_t qtn_proc_alloc(void);
#define qtn_proc_apply_to_self _qtn_proc_apply_to_self
int qtn_proc_apply_to_self(qtn_proc_t);
#define qtn_proc_free _qtn_proc_free
void qtn_proc_free(qtn_proc_t);
#define qtn_proc_init _qtn_proc_init
void qtn_proc_init(qtn_proc_t);
#define qtn_proc_init_with_self _qtn_proc_init_with_self
int qtn_proc_init_with_self(qtn_proc_t);
#define qtn_proc_set_flags _qtn_proc_set_flags
int qtn_proc_set_flags(qtn_proc_t, uint32_t);
#define qtn_proc_set_identifier _qtn_proc_set_identifier
int qtn_proc_set_identifier(qtn_proc_t, const char *);
int quarantine(void) {
int ret = 0;
qtn_proc_t proc = qtn_proc_alloc();
if (!proc) {
ret = errno;
goto EXIT;
}
if (qtn_proc_init_with_self(proc)) {
qtn_proc_init(proc);
}
char *bundle_identifier = getenv("__CFBundleIdentifier");
if (bundle_identifier) {
if ((ret = qtn_proc_set_identifier(proc, bundle_identifier))) {
goto FAIL;
}
}
if ((ret = qtn_proc_set_flags(proc, QTN_FLAG_DOWNLOAD))) {
goto FAIL;
}
if ((ret = qtn_proc_apply_to_self(proc))) {
goto FAIL;
}
FAIL:
qtn_proc_free(proc);
EXIT:
return ret;
}
int main(int argc, char *argv[]) {
int ret = 0;
if (argc < 2) {
ret = -1;
printf("usage: %s file [argv ...]\n", argv[0]);
goto EXIT;
}
if ((ret = quarantine())) {
perror("quarantine");
return ret;
}
char **args = malloc(argc * sizeof(char *));
for (size_t i = 0; i < argc - 1; ++i) {
args[i] = argv[i + 1];
}
args[argc - 1] = NULL;
if ((ret = execvp(argv[1], args))) {
perror("execvp");
goto EXIT;
}
EXIT:
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment