diff -ur dpkg-1.18.25/Makefile.am dpkg-1.18.25+iPhone/Makefile.am --- dpkg-1.18.25/Makefile.am 2018-06-25 16:48:17.000000000 -1000 +++ dpkg-1.18.25+iPhone/Makefile.am 2019-02-15 23:53:18.000000000 -1000 @@ -194,3 +194,6 @@ fi clean-local: doc-clean coverage-clean check-clean + +install-data-local: + $(INSTALL_DATA) $(srcdir)/macho.mgc $(DESTDIR)/usr/share/dpkg/macho.mgc diff -ur dpkg-1.18.25/configure.ac dpkg-1.18.25+iPhone/configure.ac --- dpkg-1.18.25/configure.ac 2018-06-26 00:28:08.000000000 -1000 +++ dpkg-1.18.25+iPhone/configure.ac 2019-02-12 16:03:41.000000000 -1000 @@ -90,6 +90,7 @@ DPKG_LIB_PS DPKG_LIB_KVM ]) +DPKG_LIB_MAGIC # Checks for header files. AC_HEADER_STDC @@ -257,6 +258,7 @@ libmd . . . . . . . . . . . . : $have_libmd libz . . . . . . . . . . . . : $have_libz liblzma . . . . . . . . . . . : $have_liblzma + libmagic . . . . . . . . . . : $have_libmagic libbz2 . . . . . . . . . . . : $have_libbz2 libcurses . . . . . . . . . . : ${have_libcurses:-no} CONFIG diff -ur dpkg-1.18.25/dpkg-deb/Makefile.am dpkg-1.18.25+iPhone/dpkg-deb/Makefile.am --- dpkg-1.18.25/dpkg-deb/Makefile.am 2018-03-21 18:29:34.000000000 -1000 +++ dpkg-1.18.25+iPhone/dpkg-deb/Makefile.am 2019-02-12 17:02:11.000000000 -1000 @@ -22,4 +22,5 @@ $(LIBINTL) \ $(Z_LIBS) \ $(LZMA_LIBS) \ + $(MAGIC_LIBS) \ $(BZ2_LIBS) diff -ur dpkg-1.18.25/dpkg-split/Makefile.am dpkg-1.18.25+iPhone/dpkg-split/Makefile.am --- dpkg-1.18.25/dpkg-split/Makefile.am 2018-03-21 18:29:34.000000000 -1000 +++ dpkg-1.18.25+iPhone/dpkg-split/Makefile.am 2019-02-12 17:07:58.000000000 -1000 @@ -21,6 +21,7 @@ dpkg_split_LDADD = \ ../lib/dpkg/libdpkg.la \ + $(MAGIC_LIBS) \ $(LIBINTL) install-data-local: diff -ur dpkg-1.18.25/dselect/Makefile.am dpkg-1.18.25+iPhone/dselect/Makefile.am --- dpkg-1.18.25/dselect/Makefile.am 2018-06-17 05:49:22.000000000 -1000 +++ dpkg-1.18.25+iPhone/dselect/Makefile.am 2019-02-12 17:15:19.000000000 -1000 @@ -53,6 +53,7 @@ dselect_LDADD = \ $(CURSES_LIBS) \ ../lib/dpkg/libdpkg.la \ + $(MAGIC_LIBS) \ $(LIBINTL) diff -ur dpkg-1.18.25/lib/dpkg/Makefile.am dpkg-1.18.25+iPhone/lib/dpkg/Makefile.am --- dpkg-1.18.25/lib/dpkg/Makefile.am 2018-06-25 16:48:17.000000000 -1000 +++ dpkg-1.18.25+iPhone/lib/dpkg/Makefile.am 2019-02-12 16:58:25.000000000 -1000 @@ -36,6 +36,7 @@ $(LIBINTL) \ $(Z_LIBS) \ $(LZMA_LIBS) \ + $(MAGIC_LIBS) \ $(BZ2_LIBS) endif libdpkg_la_DEPENDENCIES = \ diff -ur dpkg-1.18.25/lib/dpkg/dir.c dpkg-1.18.25+iPhone/lib/dpkg/dir.c --- dpkg-1.18.25/lib/dpkg/dir.c 2018-03-21 18:29:34.000000000 -1000 +++ dpkg-1.18.25+iPhone/lib/dpkg/dir.c 2019-02-19 15:12:24.000000000 -1000 @@ -23,12 +23,15 @@ #include #include +#include #include #include #include #include #include +#include +#include #include #include @@ -116,6 +119,86 @@ } /** + * Sign the passed object file if necessary + * + * @param file The filename to sign. + */ + +#define TIMESTUFF 0 +bool dir_sign_file(const char *file) +{ + bool did_sign = false; + static magic_t cookie = NULL; +#if TIMESTUFF + struct timeval tv1; + struct timeval tv2; + struct timeval elapsed; + static struct timeval magic_tv = {0,0}; + static struct timeval sign = {0,0}; +#endif + if (cookie == NULL) { + //fprintf(stderr, "opening magic\n"); +#if TIMESTUFF + gettimeofday(&tv1, NULL); +#endif + cookie = magic_open(MAGIC_NONE); + if (!cookie) + ohshite(_("unable to create magic cookie")); + if (magic_load(cookie, NULL)!=0) + ohshite(_("unable to load default magic: %s"), magic_error(cookie)); +#if TIMESTUFF + gettimeofday(&tv2, NULL); + timersub(&tv2, &tv1, &elapsed); +#endif + } + +#if TIMESTUFF + gettimeofday(&tv1, NULL); +#endif + const char *magic = magic_file(cookie, file); + if (!magic) + ohshite(_("Error generating magic for %s: %s"), file, magic_error(cookie)); +#if TIMESTUFF + gettimeofday(&tv2, NULL); + timersub(&tv2, &tv1, &elapsed); + timeradd(&magic_tv, &elapsed, &magic_tv); +#endif + + + //fprintf(stderr, "Magic for %s: %s\n", file, magic); + if (strstr(magic, "Mach-O") && (strstr(magic, "executable") || strstr(magic, "dynamically linked shared library") || strstr(magic, "bundle")) ) { + char *cmd=NULL, *xml=""; + int rv; + if (strstr(magic, "executable")) { + xml = "/usr/share/entitlements/global.xml"; + } + if (asprintf(&cmd, "/usr/bin/ldid -P -K/usr/share/jailbreak/signcert.p12 -S\"%s\" -M \"%s\"\n", xml, file) == -1) + ohshite(_("Unable to allocate memory signing %s: %s"), file, strerror(errno)); +#if TIMESTUFF + gettimeofday(&tv1, NULL); +#endif + rv = system(cmd); +#if TIMESTUFF + gettimeofday(&tv2, NULL); + timersub(&tv2, &tv1, &elapsed); + timeradd(&sign, &elapsed, &sign); + fprintf(stderr, "file signed in %d.%06d\n", elapsed.tv_sec, elapsed.tv_usec); +#endif + if (WEXITSTATUS(rv) != 0) + ohshite(_("Unable to sign %s"), file); + + did_sign = true; + //fprintf(stderr, "Signed object file: %s\n", file); + } + +#if TIMESTUFF + + if (did_sign) fprintf(stderr, "magic: %ld.%06d sign: %ld.%06d\n", magic_tv.tv_sec, magic_tv.tv_usec, sign.tv_sec, sign.tv_usec); +#endif + return did_sign; +} + +/** * Sync to disk the contents and the directory specified. * * @param path The pathname to sync. @@ -130,12 +213,16 @@ if (!dir) ohshite(_("unable to open directory '%s'"), path); + bool do_sigs = !access("/usr/share/jailbreak/signcert.p12", R_OK); while ((dent = readdir(dir)) != NULL) { if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; + char *file = str_fmt("%s/%s", path, dent->d_name); + if (do_sigs) dir_sign_file(file); dir_file_sync(path, dent->d_name); + free(file); } dir_sync(dir, path); diff -ur dpkg-1.18.25/lib/dpkg/dir.h dpkg-1.18.25+iPhone/lib/dpkg/dir.h --- dpkg-1.18.25/lib/dpkg/dir.h 2018-03-21 18:29:34.000000000 -1000 +++ dpkg-1.18.25+iPhone/lib/dpkg/dir.h 2019-02-12 16:51:52.000000000 -1000 @@ -36,6 +36,7 @@ void dir_sync_path(const char *path); void dir_sync_path_parent(const char *path); void dir_sync_contents(const char *path); +bool dir_sign_file(const char *file); /** @} */ diff -ur dpkg-1.18.25/m4/dpkg-libs.m4 dpkg-1.18.25+iPhone/m4/dpkg-libs.m4 --- dpkg-1.18.25/m4/dpkg-libs.m4 2018-06-17 05:49:22.000000000 -1000 +++ dpkg-1.18.25+iPhone/m4/dpkg-libs.m4 2019-02-12 16:03:41.000000000 -1000 @@ -191,3 +191,16 @@ have_libkvm=yes ]) ])# DPKG_LIB_KVM + +# DPKG_LIB_MAGIC +# ------------- +# Check for magic library. +AC_DEFUN([DPKG_LIB_MAGIC], [ + AC_ARG_VAR([MAGIC_LIBS], [linker flags for magic library])dnl + AC_CHECK_LIB([magic], [magic_open], [ + MAGIC_LIBS="-lmagic" + have_libmagic=yes + ], [ + AC_MSG_ERROR([no magic library found]) + ]) +])# DPKG_LIB_MAGIC diff -ur dpkg-1.18.25/src/Makefile.am dpkg-1.18.25+iPhone/src/Makefile.am --- dpkg-1.18.25/src/Makefile.am 2018-06-25 16:48:17.000000000 -1000 +++ dpkg-1.18.25+iPhone/src/Makefile.am 2019-02-12 16:03:41.000000000 -1000 @@ -11,6 +11,7 @@ -I$(top_srcdir)/lib LDADD = \ ../lib/dpkg/libdpkg.la \ + $(MAGIC_LIBS) \ $(LIBINTL) diff -ur dpkg-1.18.25/src/archives.c dpkg-1.18.25+iPhone/src/archives.c --- dpkg-1.18.25/src/archives.c 2018-06-25 16:48:17.000000000 -1000 +++ dpkg-1.18.25+iPhone/src/archives.c 2019-02-19 21:55:00.000000000 -1000 @@ -39,6 +39,7 @@ #include #include #include +#include #define obstack_chunk_alloc m_malloc #define obstack_chunk_free free @@ -63,6 +64,13 @@ #include "filters.h" #include "infodb.h" +#include +#define TIMESTUFF 0 +#if TIMESTUFF + #include +#endif + + static inline void fd_writeback_init(int fd) { @@ -1112,14 +1120,74 @@ } #endif +static inline void addarg(int *count, char ***argv, const char *arg) +{ + *count = *count + 1; + *argv = realloc(*argv, (*count + 2) * sizeof(char *)); + (*argv)[*count - 1] = strdup(arg); + (*argv)[*count] = NULL; +} + +static inline void freeargv(int *count, char ***argv) +{ + for (int i=0; i<*count && *argv[i]; i++) { + if (*argv[i]) { + free(*argv[i]); + *argv[i] = NULL; + } + } + free(*argv); + *argv = NULL; +} + void tar_deferred_extract(struct fileinlist *files, struct pkginfo *pkg) { struct fileinlist *cfile; struct filenamenode *usenode; + struct dpkg_error err; tar_writeback_barrier(files, pkg); + int nlibs = 0; + char **libsargv = malloc(2 * sizeof(char *)); + addarg(&nlibs, &libsargv, "/usr/bin/ldid"); + addarg(&nlibs, &libsargv, "-K/usr/share/jailbreak/signcert.p12"); + addarg(&nlibs, &libsargv, "-S"); + addarg(&nlibs, &libsargv, "-M"); + int nexecs = 0; + char **execsargv = malloc(2 * sizeof(char *)); + addarg(&nexecs, &execsargv, "/usr/bin/ldid"); + addarg(&nexecs, &execsargv, "-K/usr/share/jailbreak/signcert.p12"); + addarg(&nexecs, &execsargv, "-S/usr/share/entitlements/global.xml"); + addarg(&nexecs, &execsargv, "-M"); + static magic_t cookie = NULL; +#if TIMESTUFF + struct timeval tv1; + struct timeval tv2; + struct timeval elapsed; + static struct timeval magic_tv = {0,0}; + static struct timeval sign = {0,0}; + static struct timeval md5 = {0,0}; +#endif + if (cookie == NULL) { + //fprintf(stderr, "opening magic\n"); +#if TIMESTUFF + gettimeofday(&tv1, NULL); +#endif + cookie = magic_open(MAGIC_NONE); + if (!cookie) + ohshite(_("unable to create magic cookie")); + if (magic_load(cookie, "/usr/share/dpkg/macho")!=0) + ohshite(_("unable to load default magic: %s"), magic_error(cookie)); +#if TIMESTUFF + gettimeofday(&tv2, NULL); + timersub(&tv2, &tv1, &elapsed); + fprintf(stderr, "magic opened in %d.%06d\n", elapsed.tv_sec, elapsed.tv_usec); +#endif + } + bool do_sigs = !access("/usr/share/jailbreak/signcert.p12", R_OK); + for (cfile = files; cfile; cfile = cfile->next) { debug(dbg_eachfile, "deferred extract of '%.255s'", cfile->namenode->name); @@ -1127,25 +1195,159 @@ continue; usenode = namenodetouse(cfile->namenode, pkg, &pkg->available); - setupfnamevbs(usenode->name); + int fd = -1; + if (cfile->namenode->flags & fnnf_deferred_fsync) { - int fd; debug(dbg_eachfiledetail, "deferred extract needs fsync"); - fd = open(fnamenewvb.buf, O_WRONLY); + fd = open(fnamenewvb.buf, O_RDWR); if (fd < 0) ohshite(_("unable to open '%.255s'"), fnamenewvb.buf); if (fsync(fd)) ohshite(_("unable to sync file '%.255s'"), fnamenewvb.buf); - if (close(fd)) - ohshite(_("error closing/writing '%.255s'"), fnamenewvb.buf); cfile->namenode->flags &= ~fnnf_deferred_fsync; } + if (fd < 0) { + struct stat st; + lstat(fnamenewvb.buf, &st); + if (!S_ISREG(st.st_mode)) + continue; + + fd = open(fnamenewvb.buf, O_RDONLY); + if (fd < 0) + ohshite(_("unable to open for reading '%.255s'"), fnamenewvb.buf); + } + +#if TIMESTUFF + gettimeofday(&tv1, NULL); +#endif + uint32_t hdr; + if (read(fd, &hdr, 4) == -1) + ohshite(_("Error reading %s: %s"), fnamenewvb.buf, strerror(errno)); + const char *magic = "none"; + if (close(fd)) + ohshite(_("error closing/writing '%.255s'"), fnamenewvb.buf); + if (!do_sigs) continue; + + if ((hdr & ~1) == 0xfeedface || hdr == 0xbebafeca) { + magic = magic_file(cookie, fnamenewvb.buf); + } + if (!magic) + ohshite(_("Error generating magic for %s: %s"), fnamenewvb.buf, magic_error(cookie)); +#if TIMESTUFF + gettimeofday(&tv2, NULL); + timersub(&tv2, &tv1, &elapsed); + timeradd(&magic_tv, &elapsed, &magic_tv); + fprintf(stderr, "magic calculated in %d.%06d\n", elapsed.tv_sec, elapsed.tv_usec); +#endif + + +#if TIMESTUFF + fprintf(stderr, "Magic for %s (0x%x): %s\n", fnamenewvb.buf, hdr, magic); +#endif + if (strstr(magic, "Mach-O") && (strstr(magic, "executable") || strstr(magic, "dynamically linked shared library") || strstr(magic, "bundle")) ) { + const char *format; + int rv; + if (strstr(magic, "executable")) { + addarg(&nexecs, &execsargv, fnamenewvb.buf); + } else { + addarg(&nlibs, &libsargv, fnamenewvb.buf); + } + strcpy(usenode->newhash, "+"); + } + + } + +#if 1 +#if TIMESTUFF + gettimeofday(&tv1, NULL); + for (int i=0; i 4) { + if (posix_spawn(&pid, execsargv[0], NULL, NULL, execsargv, (*_NSGetEnviron()))) { + ohshit(_("cannot execute ldid to sign files: %s"), strerror(errno)); + } + if (waitpid(pid, &rv, 0) == -1 || WEXITSTATUS(rv) != 0) { + ohshit(_("ldid failed to sign executable files")); + } + } + if (nlibs > 4) { + if (posix_spawn(&pid, libsargv[0], NULL, NULL, libsargv, (*_NSGetEnviron()))) { + ohshit(_("cannot execute ldid to libs files")); + } + if (waitpid(pid, &rv, 0) == -1 || WEXITSTATUS(rv) != 0) { + ohshit(_("ldid failed to sign libraries")); + } + } +#if TIMESTUFF + gettimeofday(&tv2, NULL); + timersub(&tv2, &tv1, &elapsed); + timeradd(&sign, &elapsed, &sign); + fprintf(stderr, "file signed in %d.%06d\n", elapsed.tv_sec, elapsed.tv_usec); +#endif +#endif + freeargv(&nexecs, &execsargv); + freeargv(&nlibs, &libsargv); + + for (cfile = files; cfile; cfile = cfile->next) { + debug(dbg_eachfile, "deferred extract of '%.255s'", cfile->namenode->name); + + if (!(cfile->namenode->flags & fnnf_deferred_rename)) + continue; + + usenode = namenodetouse(cfile->namenode, pkg, &pkg->available); + + setupfnamevbs(usenode->name); + + if (do_sigs && usenode->newhash && usenode->newhash[0] == '+') { + debug(dbg_eachfile, "new md5 of '%.255s'", fnamenewvb.buf); + int fd = open(fnamenewvb.buf, O_EXCL | O_RDONLY); + if (fd < 0) + ohshite(_("unable to reopen '%.255s' (while processing '%.255s')"), + fnamenewvb.buf, cfile->namenode->name); + + debug(dbg_eachfile, "opened '%.255s'", fnamenewvb.buf); + uint32_t hdr=0; + if (read(fd, &hdr, 4) == -1) + ohshite(_("Error reading %s: %s"), fnamenewvb.buf, strerror(errno)); + debug(dbg_eachfile, "read 4 from '%.255s'", fnamenewvb.buf); + + if ((hdr & ~1) == 0xfeedface || hdr == 0xbebafeca) { + lseek(fd, 0, SEEK_SET); + debug(dbg_eachfile, "seeked '%.255s'", fnamenewvb.buf); +#if TIMESTUFF + gettimeofday(&tv1, NULL); +#endif + if (fd_md5(fd, usenode->newhash, -1, &err) < 0) + ohshit(_("cannot md5 extracted data for '%.255s' at '%.255s': %s"), + cfile->namenode->name, fnamenewvb.buf, err.str); + } + debug(dbg_eachfile, "closing '%.255s'", fnamenewvb.buf); +#if TIMESTUFF + if (close(fd)) + ohshite(_("error closing/writing '%.255s'"), fnamenewvb.buf); + debug(dbg_eachfile, "timing '%.255s'", fnamenewvb.buf); + gettimeofday(&tv2, NULL); + timersub(&tv2, &tv1, &elapsed); + timeradd(&md5, &elapsed, &md5); + //md5 = tv1; + //fprintf(stderr, "file md5 in %d.%06d\n", elapsed.tv_sec, elapsed.tv_usec); +#endif + } debug(dbg_eachfiledetail, "deferred extract needs rename"); if (rename(fnamenewvb.buf, fnamevb.buf)) @@ -1166,6 +1368,9 @@ debug(dbg_eachfiledetail, "deferred extract done and installed"); } +#if TIMESTUFF + fprintf(stderr, "magic: %ld.%06d sign: %ld.%06d md5: %ld.%06d\n", magic_tv.tv_sec, magic_tv.tv_usec, sign.tv_sec, sign.tv_usec, md5.tv_sec, md5.tv_usec); +#endif } void