Ignore:
Timestamp:
Dec 22, 2013, 12:40:04 AM (5 years ago)
Author:
landonf@…
Message:

Add support for Mac OS X 10.4.

Location:
trunk/dports/security/certsync
Files:
1 added
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/dports/security/certsync/Portfile

    r115008 r115009  
    55name                    certsync
    66version                 1.0.6
    7 revision                1
     7revision                2
    88categories              security
    99conflicts               curl-ca-bundle
     
    2222extract.mkdir           yes
    2323post-extract {
    24         xinstall -m 644 -W ${filespath} certsync.m certsync.plist update-ca-certificates ${worksrcpath}
     24        xinstall -m 644 -W ${filespath} certsync.m compat.h certsync.plist update-ca-certificates ${worksrcpath}
    2525}
    2626
     
    4444        system -W ${worksrcpath} "${configure.objc} \
    4545                ${configure.objcflags} \
    46                 -mmacosx-version-min=10.5 \
     46                -mmacosx-version-min=10.4 \
    4747                -Wall \
    4848                certsync.m -o certsync \
  • trunk/dports/security/certsync/files/certsync.m

    r115008 r115009  
    2727
    2828#import <Foundation/Foundation.h>
    29 #import <AvailabilityMacros.h>
     29#import <Security/Security.h>
    3030
    3131#import <unistd.h>
    3232#import <stdio.h>
    3333
    34 #import <objc/message.h>
    35 
    36 /* Allow building with SDKs < 10.6 */
    37 #ifndef MAC_OS_X_VERSION_10_6
    38 #define MAC_OS_X_VERSION_10_6 1060
    39 #endif /* !MAC_OS_X_VERSION_10_6 */
    40 
    41 /* Allow building with SDKs < 10.5 */
    42 #ifndef MAC_OS_X_VERSION_10_5
    43 #define MAC_OS_X_VERSION_10_5 1050
    44 #endif /* !MAC_OS_X_VERSION_10_5 */
    45 
    46 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
    47 /* errSecSuccess was not defined until 10.6 */
    48 #define errSecSuccess noErr
    49 
    50 /* NSDataWritingAtomic was not defined until 10.6 */
    51 #define NSDataWritingAtomic NSAtomicWrite
    52 #endif
     34#import "compat.h"
    5335
    5436/* A wrapper class that may be used to pass configuration through the
     
    124106static NSArray *certificatesForTrustDomain (SecTrustSettingsDomain domain, NSError **outError) {
    125107    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     108    NSArray *trusted = nil;
    126109    CFArrayRef certs = nil;
    127110    OSStatus err;
    128111   
    129     /* Fetch all certificates in the given domain */
    130     err = SecTrustSettingsCopyCertificates(domain, &certs);
    131     if (err == errSecSuccess) {
    132         PLCFAutorelease(certs);
    133     } else if (err == errSecNoTrustSettings ) {
    134         /* No data */
    135        
    136         [pool release];
    137         return [NSArray array];
    138     } else if (err != errSecSuccess) {
    139         /* Lookup failed */
    140         if (outError != NULL)
    141             *outError = [[NSError errorWithDomain: NSOSStatusErrorDomain code: err userInfo:nil] retain];
    142        
    143         [pool release];
    144         [*outError autorelease];
    145         return nil;
    146     }
    147    
    148     /* Extract trusted roots */
    149     NSMutableArray *results = [NSMutableArray arrayWithCapacity: CFArrayGetCount(certs)];
    150     for (id certObj in (NSArray *) certs) {
    151         SecCertificateRef cert = (SecCertificateRef) certObj;
    152        
    153         /* Fetch the trust settings */
    154         CFArrayRef trustSettings = nil;
    155         err = SecTrustSettingsCopyTrustSettings(cert, domain, &trustSettings);
    156         if (err != errSecSuccess) {
    157             /* Shouldn't happen */
    158             nsfprintf(stderr, @"Failed to fetch trust settings\n");
    159             continue;
    160         } else {
    161             PLCFAutorelease(trustSettings);
    162         }
    163        
    164         /* If empty, trust for everything (as per the Security Framework documentation) */
    165         if (CFArrayGetCount(trustSettings) == 0) {
    166             [results addObject: certObj];
    167         } else {
    168             /* Otherwise, walk the properties and evaluate the trust settings result */
    169             for (NSDictionary *trustProps in (NSArray *) trustSettings) {
    170                 CFNumberRef settingsResultNum;
    171                 SInt32 settingsResult;
     112    /* Mac OS X >= 10.5 provides SecTrustSettingsCopyCertificates() */
     113    if (SecTrustSettingsCopyCertificates != NULL) {
     114        /* Fetch all certificates in the given domain */
     115        err = SecTrustSettingsCopyCertificates(domain, &certs);
     116        if (err == errSecSuccess) {
     117            PLCFAutorelease(certs);
     118        } else if (err == errSecNoTrustSettings ) {
     119            /* No data */
     120       
     121            [pool release];
     122            return [NSArray array];
     123        } else if (err != errSecSuccess) {
     124            /* Lookup failed */
     125            if (outError != NULL)
     126                *outError = [[NSError errorWithDomain: NSOSStatusErrorDomain code: err userInfo:nil] retain];
     127       
     128            [pool release];
     129            [*outError autorelease];
     130            return nil;
     131        }
     132   
     133        /* Extract trusted roots */
     134        NSMutableArray *results = [NSMutableArray arrayWithCapacity: CFArrayGetCount(certs)];
     135        trusted = results;
     136       
     137        NSEnumerator *resultEnumerator = [(NSArray *)certs objectEnumerator];
     138        id certObj;
     139        while ((certObj = [resultEnumerator nextObject]) != nil) {
     140            SecCertificateRef cert = (SecCertificateRef) certObj;
     141       
     142            /* Fetch the trust settings */
     143            CFArrayRef trustSettings = nil;
     144            err = SecTrustSettingsCopyTrustSettings(cert, domain, &trustSettings);
     145            if (err != errSecSuccess) {
     146                /* Shouldn't happen */
     147                nsfprintf(stderr, @"Failed to fetch trust settings\n");
     148                continue;
     149            } else {
     150                PLCFAutorelease(trustSettings);
     151            }
     152       
     153            /* If empty, trust for everything (as per the Security Framework documentation) */
     154            if (CFArrayGetCount(trustSettings) == 0) {
     155                [results addObject: certObj];
     156            } else {
     157                /* Otherwise, walk the properties and evaluate the trust settings result */
     158                NSEnumerator *trustEnumerator = [(NSArray *)trustSettings objectEnumerator];
     159                NSDictionary *trustProps;
     160                while ((trustProps = [trustEnumerator nextObject]) != nil) {
     161                    CFNumberRef settingsResultNum;
     162                    SInt32 settingsResult;
    172163               
    173                 settingsResultNum = (CFNumberRef) [trustProps objectForKey: (id) kSecTrustSettingsResult];
    174                 CFNumberGetValue(settingsResultNum, kCFNumberSInt32Type, &settingsResult);
     164                    settingsResultNum = (CFNumberRef) [trustProps objectForKey: (id) kSecTrustSettingsResult];
     165                    CFNumberGetValue(settingsResultNum, kCFNumberSInt32Type, &settingsResult);
    175166               
    176                 /* If a root, add to the result set */
    177                 if (settingsResult == kSecTrustSettingsResultTrustRoot || settingsResult == kSecTrustSettingsResultTrustAsRoot) {
    178                     [results addObject: certObj];
    179                     break;
     167                    /* If a root, add to the result set */
     168                    if (settingsResult == kSecTrustSettingsResultTrustRoot || settingsResult == kSecTrustSettingsResultTrustAsRoot) {
     169                        [results addObject: certObj];
     170                        break;
     171                    }
    180172                }
    181173            }
    182174        }
    183     }
    184 
    185     [results retain];
     175    } else {
     176        /* Fetch all certificates in the given domain */
     177        err = SecTrustCopyAnchorCertificates(&certs);
     178        if (err == noErr) {
     179            PLCFAutorelease(certs);
     180        } else if (err == errSecTrustNotAvailable) {
     181            /* No data */
     182            [pool release];
     183            return [NSArray array];
     184        } else if (err != noErr) {
     185            /* Lookup failed */
     186            if (outError != NULL)
     187                *outError = [[NSError errorWithDomain: NSOSStatusErrorDomain code: err userInfo:nil] retain];
     188
     189            [pool release];
     190            [*outError autorelease];
     191            return nil;
     192        }
     193
     194        /* All certs are trusted */
     195        trusted = (NSArray *) certs;
     196    }
     197   
     198    [trusted retain];
    186199    [pool release];
    187     return [results autorelease];
     200    return [trusted autorelease];
    188201}
    189202
     
    232245    }
    233246   
    234     for (id certObj in result) {
    235         CFErrorRef cferror = NULL;
    236         CFStringRef subject;
    237 
    238 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6
    239         if (SecCertificateCopyShortDescription != NULL) {
    240             subject = PLCFAutorelease(SecCertificateCopyShortDescription(NULL, (SecCertificateRef) certObj, &cferror));
    241         } else {
     247    NSEnumerator *resultEnumerator = [result objectEnumerator];
     248    id certObj;
     249    while ((certObj = [resultEnumerator nextObject]) != nil) {
     250        NSError *subjectError = NULL;
     251        CFStringRef subject = NULL;
     252        BOOL subjectUnsupported = NO;
     253
     254        if (SecCertificateCopyShortDescription != NULL /* 10.7 */) {
     255            subject = PLCFAutorelease(SecCertificateCopyShortDescription(NULL, (SecCertificateRef) certObj, (CFErrorRef *) &subjectError));
     256           
     257        } else if (SecCertificateCopySubjectSummary != NULL /* 10.6 */) {
    242258            subject = PLCFAutorelease(SecCertificateCopySubjectSummary((SecCertificateRef) certObj));
    243         }
    244 #elif MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_6
    245         subject = PLCFAutorelease(SecCertificateCopySubjectSummary((SecCertificateRef) certObj));
    246 #elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
    247         if ((err = SecCertificateCopyCommonName((SecCertificateRef) certObj, &subject)) == errSecSuccess && subject != NULL) {
    248             PLCFAutorelease(subject);
    249         } else {
    250             /* In the case that the CN is simply unavailable, provide a more useful error code */
    251             if (err == errSecSuccess)
    252                 err = errSecNoSuchAttr;
    253    
    254             NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: @"SecCertificateCopyCommonName() failed", NSLocalizedDescriptionKey, nil];
    255             cferror = (CFErrorRef) [NSError errorWithDomain: NSOSStatusErrorDomain code: err userInfo: userInfo];
    256             subject = NULL;
    257         }
    258 #endif
     259           
     260        } else if (SecCertificateCopyCommonName != NULL /* 10.5 */) {
     261            if ((err = SecCertificateCopyCommonName((SecCertificateRef) certObj, &subject)) == errSecSuccess && subject != NULL) {
     262                PLCFAutorelease(subject);
     263            } else {
     264                /* In the case that the CN is simply unavailable, provide a more useful error code */
     265                if (err == errSecSuccess)
     266                    err = errSecNoSuchAttr;
     267
     268                NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: @"SecCertificateCopyCommonName() failed", NSLocalizedDescriptionKey, nil];
     269                subjectError = [NSError errorWithDomain: NSOSStatusErrorDomain code: err userInfo: userInfo];
     270                subject = NULL;
     271            }
     272        } else /* <= 10.4 */ {
     273            subjectUnsupported = YES;
     274        }
    259275
    260276        if (subject == NULL) {
    261             nsfprintf(stderr, @"Failed to extract certificate description: %@\n", cferror);
     277            /* Don't print an error if fetching the subject is unsupported on the platform (eg, <= 10.4) */
     278            if (!subjectUnsupported)
     279                nsfprintf(stderr, @"Failed to extract certificate description: %@\n", subjectError);
    262280        } else {
    263281            nsfprintf(stderr, @"Found %@\n", subject);
     
    272290    /* Prefer the non-deprecated SecItemExport on Mac OS X >= 10.7. We use an ifdef to keep the code buildable with earlier SDKs, too. */
    273291    nsfprintf(stderr, @"Exporting certificates from the keychain\n");
    274 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6
    275292    if (SecItemExport != NULL) {
    276293        err = SecItemExport((CFArrayRef) anchors, kSecFormatPEMSequence, kSecItemPemArmour, NULL, &pemData);
     
    278295        err = SecKeychainItemExport((CFArrayRef) anchors, kSecFormatPEMSequence, kSecItemPemArmour, NULL, &pemData);
    279296    }
    280 #else
    281     err = SecKeychainItemExport((CFArrayRef) anchors, kSecFormatPEMSequence, kSecItemPemArmour, NULL, &pemData);
    282 #endif
    283297    PLCFAutorelease(pemData);
    284298
Note: See TracChangeset for help on using the changeset viewer.