Browse Source

added bump feature that literally just bumps a package version and also validates any dylibs inside to make sure they have a valid code signature

Kevin Bradley 5 years ago
parent
commit
c52aabc54d

BIN
bootstrapTool.xcodeproj/project.xcworkspace/xcuserdata/kevinbradley.xcuserdatad/UserInterfaceState.xcuserstate


+ 1 - 1
bootstrapTool/Classes/HelperClass.h

@@ -7,5 +7,5 @@
 + (NSString *)octalFromSymbols:(NSString *)theSymbols;
 + (NSArray <StatusPackageModel*>*)statusInstalledPackagesFromFile:(NSString *)statusFile;
 + (NSString *)singleLineReturnForProcess:(NSString *)call;
-
++ (NSArray *)arrayReturnForTask:(NSString *)taskBinary withArguments:(NSArray *)taskArguments;
 @end

+ 28 - 0
bootstrapTool/Classes/HelperClass.m

@@ -63,6 +63,34 @@
     
 }
 
++ (NSArray *)arrayReturnForTask:(NSString *)taskBinary withArguments:(NSArray *)taskArguments
+{
+    NSLog(@"%@ %@", taskBinary, [taskArguments componentsJoinedByString:@" "]);
+    NSTask *task = [[NSTask alloc] init];
+    NSPipe *pipe = [[NSPipe alloc] init];
+    NSFileHandle *handle = [pipe fileHandleForReading];
+    
+    [task setLaunchPath:taskBinary];
+    [task setArguments:taskArguments];
+    [task setStandardOutput:pipe];
+    [task setStandardError:pipe];
+    
+    [task launch];
+    
+    NSData *outData = nil;
+    NSString *temp = nil;
+    while((outData = [handle readDataToEndOfFile]) && [outData length])
+    {
+        temp = [[NSString alloc] initWithData:outData encoding:NSASCIIStringEncoding];
+        
+    }
+    [handle closeFile];
+    task = nil;
+    
+    return [temp componentsSeparatedByString:@"\n"];
+    
+}
+
 + (NSString *)singleLineReturnForProcess:(NSString *)call
 {
     return [[self returnForProcess:call] componentsJoinedByString:@"\n"];

+ 1 - 0
bootstrapTool/Classes/InputPackage.h

@@ -11,6 +11,7 @@
 @property (nonatomic, strong) NSString *version;
 @property (nonatomic, strong) NSString *path;
 
+- (void)bumpVersionInCurrentDirectory;
 - (void)repackageInCurrentDirectoryWithArch:(NSString *)newArch;
 - (int)installToBootstrapPath:(NSString *)bootstrapPath;
 - (ErrorReturn *)errorReturnForBootstrap:(NSString *)bootstrapPath;

+ 152 - 4
bootstrapTool/Classes/InputPackage.m

@@ -95,7 +95,7 @@
     }
     
     NSString *pwd = [[HelperClass returnForProcess:@"/bin/pwd"] componentsJoinedByString:@"\n"];
-
+    
     NSFileManager *man = [NSFileManager defaultManager];
     NSString *tmpPath = [pwd stringByAppendingPathComponent:self.packageName];
     NSString *debian = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
@@ -159,7 +159,7 @@
             newPath = [newPath stringByAppendingPathComponent:fileName];
             //DLog(@"newPath: %@", newPath);
             [man copyItemAtPath:fullPath toPath:newPath error:nil];
-       
+            
         } else {
             
             NSMutableString *controlFile = [[NSMutableString alloc] initWithContentsOfFile:fullPath encoding:NSASCIIStringEncoding error:nil];
@@ -234,8 +234,156 @@
     
 }
 
-- (void)repackageInCurrentDirectoryWithArch:(NSString *)newArch {
+- (void)codesignIfNecessary:(NSString *)file {
+    
+    if (![[[file pathExtension] lowercaseString] isEqualToString:@"dylib"]){
+        return;
+    }
+    
+    NSString *jtp = [HelperClass singleLineReturnForProcess:@"/usr/bin/which jtool"];
+    if (jtp){
+        
+        NSString *proc = [[HelperClass arrayReturnForTask:jtp withArguments:@[@"--sig", file]] componentsJoinedByString:@"\n"];
+        
+        NSLog(@"proc: %@", proc);
+        
+        if ([proc containsString:@"No Code Signing blob detected in this file"]){
+        
+            NSString *runCommand = [NSString stringWithFormat:@"%@ --sign platform %@ --inplace", jtp, file];
+            
+            NSLog(@"running codesign command: %@", runCommand);
+            
+           NSString *returnValue = [HelperClass singleLineReturnForProcess:runCommand];
+            
+            NSLog(@"returnValue: %@", returnValue);
+        }
+    }
+}
 
+- (void)validateSignaturesInPath:(NSString *)thePath {
+    
+    [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+       
+        NSString *file = [thePath stringByAppendingPathComponent:obj.path];
+        
+        NSLog(@"check sig file: %@", file);
+        [self codesignIfNecessary:file];
+        
+        
+    }];
+    
+}
+
+- (void)bumpVersionInCurrentDirectory {
+    
+    NSString *fakeRoot = [HelperClass singleLineReturnForProcess:@"/usr/bin/which fakeroot"];
+    NSString *pwd = [HelperClass singleLineReturnForProcess:@"/bin/pwd"];
+    DLog(@"\nProcessing file: %@\n", self.path);
+    InputPackage *output = self;
+    
+    DLog(@"\nFound package: '%@' at version: '%@'...\n", output.packageName, output.version );
+    
+    NSString *tmpPath = [pwd stringByAppendingPathComponent:output.packageName];
+    NSString *debian = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
+    [FM createDirectoryAtPath:tmpPath withIntermediateDirectories:TRUE attributes:nil error:nil];
+    DLog(@"\nExtracting package contents for processing...\n");
+    [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", self.path, tmpPath]];
+    [FM createDirectoryAtPath:debian withIntermediateDirectories:TRUE attributes:nil error:nil];
+    DLog(@"\nExtracting DEBIAN files for processing...\n");
+    [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -e %@ %@", self.path, debian]];
+    
+    
+    NSString *controlPath = [debian stringByAppendingPathComponent:@"control"];
+    
+    NSMutableString *controlFile = [[NSMutableString alloc] initWithContentsOfFile:controlPath encoding:NSASCIIStringEncoding error:nil];
+    //@"appletvos-arm64"
+    [controlFile replaceOccurrencesOfString:self.version withString:[self.version nextVersionNumber] options:NSLiteralSearch range:NSMakeRange(0, [controlFile length])];
+    
+    [controlFile writeToFile:controlPath atomically:TRUE];
+    
+    //at this point we have the files extracted, time to determine what needs to be changed
+    
+    NSArray *ignoreFiles = @[@".fauxsu", @".DS_Store"];
+    NSArray *forbiddenRoots = @[@"etc", @"var", @"tmp"];
+    
+    [self validateSignaturesInPath:tmpPath];
+    
+    //__block NSMutableArray *_overwriteArray = [NSMutableArray new];
+    [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        if (obj.type == BSPackageFileTypeFile || obj.type == BSPackageFileTypeDirectory){
+            
+            //DLog(@"processing path: %@", obj.path);
+            if ([obj.path isEqualToString:@"/private/var/mobile/Applications/"]){
+                
+                NSString *badPath = [tmpPath stringByAppendingPathComponent:obj.path];
+                NSString *newPath = [tmpPath stringByAppendingPathComponent:@"Applications"];
+                DLog(@"\n [INFO] Moving %@ to %@...", badPath, newPath);
+                [FM moveItemAtPath:badPath toPath:newPath error:nil];
+                [FM removeItemAtPath:[tmpPath stringByAppendingPathComponent:@"private"] error:nil];
+                *stop = TRUE;
+            }
+            
+            NSString *fullPath = [tmpPath stringByAppendingPathComponent:obj.path];
+            
+            if ([ignoreFiles containsObject:obj.path.lastPathComponent]){
+                
+                DLog(@"in ignore file list, purge");
+                [FM removeItemAtPath:fullPath error:nil];
+                
+            }
+            
+            NSArray *pathComponents = [obj.path pathComponents];
+            if ([pathComponents count] > 1)
+            {
+                
+                NSString *rootPath = [pathComponents objectAtIndex:1];
+                //DLog(@"\n Checking root path: %@ for file %@\n", rootPath, obj.path);
+                if ([forbiddenRoots containsObject:rootPath])
+                {
+                    DLog(@"\n [WARNING] package file: '%@' would overwrite symbolic link at '%@'\n", obj.path, rootPath);
+                    NSString *privateDir = [tmpPath stringByAppendingPathComponent:@"private"];
+                    if (![FM fileExistsAtPath:privateDir]){
+                        [FM createDirectoryAtPath:privateDir withIntermediateDirectories:TRUE attributes:nil error:nil];
+                        
+                    }
+                    //take <package_name>/[rootPath] (could be etc, var, tmp) and move to <package_name>/private/[rootPath]
+                    NSString *badPath = [tmpPath stringByAppendingPathComponent:rootPath];
+                    NSString *newPath = [privateDir stringByAppendingPathComponent:rootPath];
+                    DLog(@"\n [INFO] Moving %@ to %@...", badPath, newPath);
+                    [FM moveItemAtPath:badPath toPath:newPath error:nil];
+                    
+                    
+                }
+            }
+            
+            
+        }
+        
+        
+    }];
+    
+    
+    NSString *depArchiveInfo = [NSString stringWithFormat:@"/usr/local/bin/dpkg -b %@", self.packageName];
+    
+    if (fakeRoot) {
+        
+        depArchiveInfo = [NSString stringWithFormat:@"%@ /usr/local/bin/dpkg -b %@", fakeRoot, self.packageName];
+        
+        
+    }
+    
+    [[HelperClass returnForProcess:depArchiveInfo] componentsJoinedByString:@"\n"];
+    
+    
+    
+    DLog(@"\nDone!\n\n");
+    
+    //return er;
+}
+
+- (void)repackageInCurrentDirectoryWithArch:(NSString *)newArch {
+    
     NSString *fakeRoot = [HelperClass singleLineReturnForProcess:@"/usr/bin/which fakeroot"];
     NSString *pwd = [HelperClass singleLineReturnForProcess:@"/bin/pwd"];
     DLog(@"\nProcessing file: %@\n", self.path);
@@ -313,7 +461,7 @@
                     DLog(@"\n [INFO] Moving %@ to %@...", badPath, newPath);
                     [FM moveItemAtPath:badPath toPath:newPath error:nil];
                     
-
+                    
                 }
             }
             

+ 1 - 1
bootstrapTool/Classes/NSString+Additions.h

@@ -3,6 +3,6 @@
 @interface NSString (Additions)
 
 - (void)writeToFileWithoutAttributes:(NSString *)theFile;
-
+- (NSString *)nextVersionNumber;
 
 @end

+ 16 - 0
bootstrapTool/Classes/NSString+Additions.m

@@ -4,6 +4,22 @@
 
 @implementation NSString (Additions)
 
+- (NSString *)nextVersionNumber {
+    
+    NSArray *comp = [self componentsSeparatedByString:@"-"];
+    if (comp.count > 1){
+        
+        NSString *first = comp[0];
+        NSInteger bumpVersion = [[comp lastObject] integerValue]+1;
+        
+        return [NSString stringWithFormat:@"%@-%lu", first, bumpVersion];
+        
+    } else {
+        return nil;
+    }
+    return nil;
+}
+
 - (void)writeToFileWithoutAttributes:(NSString *)theFile {
     
     if ([FM fileExistsAtPath:theFile]){

+ 27 - 1
bootstrapTool/main.m

@@ -19,7 +19,7 @@
 #import "HelperClass.h"
 
 
-#define OPTION_FLAGS "o:i:ld:hcr"
+#define OPTION_FLAGS "o:i:ld:hcrb"
 
 
 char *progname;
@@ -33,6 +33,7 @@ static struct option longopts[] = {
     { "help",                      no_argument,            NULL,   'h' },
     { "clean",                     no_argument,            NULL,   'c' },
     { "repackage",                 no_argument,            NULL,   'r' },
+    { "bump",                      no_argument,            NULL,   'b' },
     { NULL,                        0,                      NULL,    0  }
 };
 
@@ -46,6 +47,7 @@ void cmd_help(){
     printf("  -l, --list\t\t\tlist all the packages installed on this bootstrap\n");
     printf("  -c, --clean\t\t\tclean a bad status file from duplicate entries\n");
     printf("  -r, --repackage\t\trepackage to fix bad locations and to change architecture\n");
+    printf("  -b, --bump\t\trepackage and bump by one - number (ie 1.0-1 -> 1.0-2)\n");
     printf("\n");
 }
 
@@ -63,6 +65,7 @@ int main(int argc, const char * argv[]) {
         NSString *deletePackage = nil;
         BOOL listPackage = FALSE;
         BOOL repackage = FALSE;
+        BOOL bump = FALSE;
         BOOL clean = FALSE;
         while ((flag = getopt_long(argc, argv, OPTION_FLAGS, longopts, NULL)) != -1) {
             switch(flag) {
@@ -85,6 +88,12 @@ int main(int argc, const char * argv[]) {
                     deletePackage = [NSString stringWithUTF8String:optarg];
                     break;
                     
+                case 'b':
+                    
+                    bump = TRUE;
+                    
+                    break;
+                    
                 case 'r':
                     
                     repackage = TRUE;
@@ -111,6 +120,14 @@ int main(int argc, const char * argv[]) {
             //return 0;
         }
         
+        if (bump == TRUE && debFile) {
+            
+            DLog(@"\n [INFO] Bumping version number for file: %@...\n", debFile);
+            InputPackage *output = [HelperClass packageForDeb:debFile];
+            [output bumpVersionInCurrentDirectory];
+            return 0;
+        }
+        
         if (repackage == TRUE && debFile) {
             
             DLog(@"\n [INFO] Repackaging file: %@...\n", debFile);
@@ -119,6 +136,7 @@ int main(int argc, const char * argv[]) {
             return 0;
         }
         
+        
         //DLog(@"folder: %@ project: %@", folder, project);
         
         if (clean && bootstrapPath) {
@@ -324,6 +342,14 @@ int main(int argc, const char * argv[]) {
         
         if (octalFile) {
             
+            if([[NSFileManager defaultManager] fileExistsAtPath:octalFile]) {
+                
+               NSDictionary *attrs = [FM attributesOfItemAtPath:octalFile error:nil];
+                NSNumber *posixPerms = attrs[NSFilePosixPermissions];
+                DLog(@"perms: %@", posixPerms);
+                return 0;
+                
+            }
             NSString *octal = [HelperClass octalFromSymbols:octalFile];
             DLog(@"%@", octal);
             return 0;