mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
* Adding error handling and returning correct error codes * * Handling auth cancellation a few other error cases * Adding some logging for EAP (Using NSLogs temporarily. DONOT MERGE) * Add in a setter for clientID to allow overrides (#5514) * Add in a setter for clientID to allow overrides * Update styling * Adding some result parsing logs * Fixing code hash logging * Add FirebaseAppDistribution to ZipBuilder * * Making sure keychain is accesible after first unlock even if app is backgrounded (#5563) * Fix auth persistence logging and invalid type casting (#5631) * Logging app id requesting releases (#5655) * AppDistribution keychain access fixes (#5683) * Using the GULKeychainUtils instead of custom keychain utility. Also added better logging * Updating keychain name and fixing tests * Code review feedback updates * Making serviceID unique per app * Adding gmp app id to the keychain along with the bundle id * Moving Keychain Utility functions in the AuthPersistence class and deleting the utility class * Lazy initialize auth state (#5755) * Lazy initialize auth state * Making sure we dont log an error is auth state is not persisted in the keychain * Switch from NSLog to FIRFADLogger (#5756) * Add FIRLogger * Switch from NSLog to FIRFADLogger * * Use FIS Auth for authenticating the tester * Remove AppAuth and start wiring up interceptor to do sign in * Extracting registration flow UI in interceptor * Adding support for iOS 9 and 10 * Create app distribution api service to handle tester api calls. (#6060) * Pull out calls to the FAD API to make them reuseable * Fix tests and run styl updates * Uncomment FIRFADLog Statements * Use [] accessor rather than . accessor * Re-running style updates * Trying to get these checks to pass the first time around * App distribution signin persist (#6063) * Pull out calls to the FAD API to make them reuseable * Fix tests and run styl updates * Add in UserDefaults storage after a tester has signed in * Add testing for the main AppDistribution file * Ran style.sh * Remove FIRFADLocalStorage and call GULUserDefaults directly. Update tests to stop mocking on teardown. * Add support for dynamic url schemes and fix two crashes (#6081) * Add support for dynamic url schemes and fix two crashes * Add support for dynamic url schemes in the format appdistribution-<app id without colons> * Fix crash when launching an app directly via a URL scheme * Fix a crash on iOS 10 simulator caused by calling NSLogv twice * Remove uses of NSLog * Fix warnings * Switch encodedAppId to be a class method * Fix styles * Create changelog and readme in preparation for release. (#6095) Just changing markdown files so will not wait for gha checks. * Change slices property from copy to strong (#6097) Fix lint warning * Change error handlers to return bool values instead of void (#6101) * Mapping sign in flow errors to app distribution errors. Also renaming AppDelegateInterceptor to FIRAppDistributionUIService (#6099) * Add github action for App Distribution (#6094) * Updating app distribution deployment target to iOS 9 (#6118) * Making sure we return granular errors during sign in persistence. Also fixing some naming and comment issues (#6117) * Encoding colons to dashes in the app id (#6119) * Move Internal headers to Sources (#6106) * Move Internal headers to Sources/ folder * PR feedback * Remove appDistribution from zip builder * Respond to code review feedback (#6138) * Initializing UIWindow using initWithWindowScene for ios 13 and removing UI code from main FIRAppDistribution.m (#6144) * Initializing UIWindow using initWithWindowScene for ios 13. Also making sure we only reset window in the App delegate if a registration flow is in progress. * Remove UI code from main class, add unit tests, and clean up UIService * stylish * Remove defines in favor of solely 'if (@available(iOS 13.0, *))' * Respond to code review feedback Co-authored-by: Cleo Schneider <cleoschneider@google.com> Co-authored-by: Pranav Rajgopal <pranavrajgopal@google.com> Co-authored-by: Cleo Schneider <cleoschneider@google.com>
157 lines
5.0 KiB
Objective-C
157 lines
5.0 KiB
Objective-C
/*
|
|
* Copyright 2019 Google
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#import "FirebaseAppDistribution/Sources/FIRAppDistributionMachO.h"
|
|
#import <CommonCrypto/CommonHMAC.h>
|
|
#include <mach-o/arch.h>
|
|
#import <mach-o/fat.h>
|
|
#import <mach-o/loader.h>
|
|
#import "FirebaseAppDistribution/Sources/FIRAppDistributionMachOSlice.h"
|
|
|
|
@interface FIRAppDistributionMachO ()
|
|
@property(nonatomic, copy) NSFileHandle* file;
|
|
@property(nonatomic, strong) NSMutableArray* slices;
|
|
@end
|
|
|
|
@implementation FIRAppDistributionMachO
|
|
|
|
- (instancetype)initWithPath:(NSString*)path {
|
|
self = [super init];
|
|
|
|
if (self) {
|
|
_file = [NSFileHandle fileHandleForReadingAtPath:path];
|
|
_slices = [NSMutableArray new];
|
|
[self extractSlices];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)extractSlices {
|
|
uint32_t magicValue;
|
|
|
|
struct fat_header fheader;
|
|
NSData* data = [self.file readDataOfLength:sizeof(fheader)];
|
|
[data getBytes:&fheader length:sizeof(fheader)];
|
|
|
|
magicValue = CFSwapInt32BigToHost(fheader.magic);
|
|
|
|
// Check to see if the file is a FAT binary (has multiple architectures)
|
|
if (magicValue == FAT_MAGIC) {
|
|
uint32_t archCount = CFSwapInt32BigToHost(fheader.nfat_arch);
|
|
NSUInteger archOffsets[archCount];
|
|
|
|
// Gather the offsets for each architecture
|
|
for (uint32_t i = 0; i < archCount; i++) {
|
|
struct fat_arch arch;
|
|
|
|
data = [self.file readDataOfLength:sizeof(arch)];
|
|
[data getBytes:&arch length:sizeof(arch)];
|
|
|
|
archOffsets[i] = CFSwapInt32BigToHost(arch.offset);
|
|
}
|
|
|
|
// Iterate the slices based on the offsets we extracted above
|
|
for (uint32_t i = 0; i < archCount; i++) {
|
|
FIRAppDistributionMachOSlice* slice = [self extractSliceAtOffset:archOffsets[i]];
|
|
|
|
if (slice) [_slices addObject:slice];
|
|
}
|
|
} else {
|
|
// If the binary is not FAT, we're dealing with a single architecture
|
|
FIRAppDistributionMachOSlice* slice = [self extractSliceAtOffset:0];
|
|
|
|
if (slice) [_slices addObject:slice];
|
|
}
|
|
}
|
|
|
|
- (FIRAppDistributionMachOSlice*)extractSliceAtOffset:(NSUInteger)offset {
|
|
[self.file seekToFileOffset:offset];
|
|
|
|
struct mach_header header;
|
|
|
|
NSData* data = [self.file readDataOfLength:sizeof(header)];
|
|
[data getBytes:&header length:sizeof(header)];
|
|
uint32_t magicValue = CFSwapInt32BigToHost(header.magic);
|
|
|
|
// If we didn't read a valid magic value, something is wrong
|
|
// Bail out immediately to prevent reading random data
|
|
if (magicValue != MH_CIGAM_64 && magicValue != MH_CIGAM) {
|
|
return nil;
|
|
}
|
|
|
|
// If the binary is 64-bit, read the reserved bit and discard it
|
|
if (magicValue == MH_CIGAM_64) {
|
|
uint32_t reserved;
|
|
|
|
[self.file readDataOfLength:sizeof(reserved)];
|
|
}
|
|
|
|
for (uint32_t i = 0; i < header.ncmds; i++) {
|
|
struct load_command lc;
|
|
|
|
data = [self.file readDataOfLength:sizeof(lc)];
|
|
[data getBytes:&lc length:sizeof(lc)];
|
|
|
|
if (lc.cmd != LC_UUID) {
|
|
// Move to the next load command
|
|
[self.file seekToFileOffset:[self.file offsetInFile] + lc.cmdsize - sizeof(lc)];
|
|
continue;
|
|
}
|
|
|
|
// Re-read the load command, but this time as a UUID command
|
|
// so we can easily fetch the UUID
|
|
[self.file seekToFileOffset:[self.file offsetInFile] - sizeof(lc)];
|
|
struct uuid_command uc;
|
|
data = [self.file readDataOfLength:sizeof(uc)];
|
|
[data getBytes:&uc length:sizeof(uc)];
|
|
|
|
NSUUID* uuid = [[NSUUID alloc] initWithUUIDBytes:uc.uuid];
|
|
const NXArchInfo* arch = NXGetArchInfoFromCpuType(header.cputype, header.cpusubtype);
|
|
|
|
return [[FIRAppDistributionMachOSlice alloc] initWithArch:arch uuid:uuid];
|
|
}
|
|
|
|
// If we got here, something is wrong. We iterated the load commands
|
|
// and didn't find a UUID load command. This means the binary is corrupt.
|
|
return nil;
|
|
}
|
|
|
|
- (NSString*)codeHash {
|
|
NSMutableString* prehashedString = [NSMutableString new];
|
|
|
|
NSArray* sortedSlices =
|
|
[_slices sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
|
return [[obj1 architectureName] compare:[obj2 architectureName]];
|
|
}];
|
|
|
|
for (FIRAppDistributionMachOSlice* slice in sortedSlices) {
|
|
[prehashedString appendString:[slice uuidString]];
|
|
}
|
|
|
|
return [self sha1:prehashedString];
|
|
}
|
|
|
|
- (NSString*)sha1:(NSString*)prehashedString {
|
|
NSData* data = [prehashedString dataUsingEncoding:NSUTF8StringEncoding];
|
|
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
|
|
CC_SHA1(data.bytes, (int)data.length, digest);
|
|
NSMutableString* hashedString = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
|
|
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) [hashedString appendFormat:@"%02x", digest[i]];
|
|
|
|
return hashedString;
|
|
}
|
|
@end
|