CFArrayRef copyTrustedAppListFromBundle(CFStringRef bundlePath, CFStringRef trustedAppListFileName)
{
	CFStringRef errorString = nil;
    CFURLRef bundleURL,trustedAppsURL = NULL;
    CFBundleRef secBundle = NULL;
	CFPropertyListRef trustedAppsPlist = NULL;
	CFDataRef xmlDataRef = NULL;
	SInt32 errorCode;
    CFArrayRef trustedAppList = NULL;
	CFMutableStringRef trustedAppListFileNameWithoutExtension = NULL;

    // Make a CFURLRef from the CFString representation of the bundleÕs path.
    bundleURL = CFURLCreateWithFileSystemPath(
        kCFAllocatorDefault,bundlePath,kCFURLPOSIXPathStyle,true);

	CFRange wholeStrRange;

	if (!bundleURL)
        goto xit;

    // Make a bundle instance using the URLRef.
    secBundle = CFBundleCreate(kCFAllocatorDefault,bundleURL);
    if (!secBundle)
        goto xit;

	trustedAppListFileNameWithoutExtension =
		CFStringCreateMutableCopy(NULL,CFStringGetLength(trustedAppListFileName),trustedAppListFileName);
	wholeStrRange = CFStringFind(trustedAppListFileName,CFSTR(".plist"),0);

	CFStringDelete(trustedAppListFileNameWithoutExtension,wholeStrRange);

    // Look for a resource in the bundle by name and type
    trustedAppsURL = CFBundleCopyResourceURL(secBundle,trustedAppListFileNameWithoutExtension,CFSTR("plist"),NULL);
    if (!trustedAppsURL)
        goto xit;

    if ( trustedAppListFileNameWithoutExtension )
		CFRelease(trustedAppListFileNameWithoutExtension);

	if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,trustedAppsURL,&xmlDataRef,NULL,NULL,&errorCode))
        goto xit;

	trustedAppsPlist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,xmlDataRef,kCFPropertyListImmutable,&errorString);
    trustedAppList = (CFArrayRef)trustedAppsPlist;

xit:
    if (bundleURL)
        CFRelease(bundleURL);
    if (secBundle)
        CFRelease(secBundle);
    if (trustedAppsURL)
        CFRelease(trustedAppsURL);
    if (xmlDataRef)
        CFRelease(xmlDataRef);
    if (errorString)
        CFRelease(errorString);

    return trustedAppList;
}
static void secNormalize(CFMutableStringRef theString, CFLocaleRef theLocale)
{
	CFRange theRange;
	
	CFStringFold(theString, kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive, theLocale);
	CFStringNormalize(theString, kCFStringNormalizationFormKC);
	CFStringTrimWhitespace(theString);
	while(CFStringFindCharacterFromSet(theString, CFCharacterSetGetPredefined(kCFCharacterSetWhitespace), CFRangeMake(0, CFStringGetLength(theString)), kCFCompareBackwards, &theRange))
		CFStringDelete(theString, theRange);
}
Exemplo n.º 3
0
/*
 * Function: parse_component
 * Purpose:
 *   Given a string 'key' and a string prefix 'prefix',
 *   return the next component in the slash '/' separated
 *   key.
 *
 * Examples:
 * 1. key = "a/b/c" prefix = "a/"
 *    returns "b"
 * 2. key = "a/b/c" prefix = "a/b/"
 *    returns "c"
 */
static CFStringRef
parse_component(CFStringRef key, CFStringRef prefix)
{
	CFMutableStringRef	comp;
	CFRange			range;

	if (CFStringHasPrefix(key, prefix) == FALSE) {
		return NULL;
	}
	comp = CFStringCreateMutableCopy(NULL, 0, key);
	CFStringDelete(comp, CFRangeMake(0, CFStringGetLength(prefix)));
	range = CFStringFind(comp, CFSTR("/"), 0);
	if (range.location == kCFNotFound) {
		return comp;
	}
	range.length = CFStringGetLength(comp) - range.location;
	CFStringDelete(comp, range);
	return comp;
}
Exemplo n.º 4
0
static void
CFStringTruncateToUTF8Length(CFMutableStringRef str, ssize_t utf8LengthLimit)
    // Truncates a CFString such that it's UTF-8 representation will have 
    // utf8LengthLimit or less characters (not including the terminating 
    // null character).  Handles UTF-16 surrogates and trims whitespace 
    // from the end of the resulting string.
{
    CFIndex             shortLen;
    CFIndex             convertedLen;
    CFIndex             originalLen;
    CFIndex             utf8Length;
    CFCharacterSetRef   whiteCharSet;
    UniChar             thisChar;
    CFIndex             trailingCharsToDelete;
    
    // Keep converting successively smaller strings until the UTF-8 string is suitably 
    // short.  Note that utf8LengthLimit must be non-negative, so this loop will 
    // always terminate before we run off the front of the string.
    
    originalLen = CFStringGetLength(str);
    shortLen = originalLen;
    do {
        // Because the buffer parameter is NULL, CFStringGetBytes returns the size of 
        // buffer required for the range of characters.  This doesn't include the 
        // trailing null byte traditionally associated with UTF-8 C strings, which 
        // is cool because that's what our caller is expecting.
        
        convertedLen = CFStringGetBytes(str, CFRangeMake(0, shortLen), kCFStringEncodingUTF8, 0, false, NULL, 0, &utf8Length);
        assert( (convertedLen == shortLen) || (convertedLen == (shortLen - 1)) );
        shortLen = convertedLen;
        
        if (utf8Length <= utf8LengthLimit) {
            break;
        }
        shortLen -= 1;
    } while (true);
    
    whiteCharSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespaceAndNewline);
    assert(whiteCharSet != NULL);
    
    do {
        if ( shortLen == 0 ) {
            break;
        }
        thisChar = CFStringGetCharacterAtIndex(str, shortLen - 1);
        if ( ! CFCharacterSetIsCharacterMember(whiteCharSet, thisChar) ) {
            break;
        }
        shortLen -= 1;
    } while (true);    
    
    trailingCharsToDelete = originalLen - shortLen;
    CFStringDelete(str, CFRangeMake(originalLen - trailingCharsToDelete, trailingCharsToDelete));
}
CF_PRIVATE Boolean _CFAppendPathExtension2(CFMutableStringRef path, CFStringRef extension) {
    if (!path) {
        return false;
    }
    
    if (0 < CFStringGetLength(extension) && IS_SLASH(CFStringGetCharacterAtIndex(extension, 0))) {
        return false;
    }
    if (1 < CFStringGetLength(extension)) {
        if (_hasDrive(extension)) return false;
    }
    
    Boolean destHasDrive = (1 < CFStringGetLength(path)) && _hasDrive(path);
    while (((destHasDrive && 3 < CFStringGetLength(path)) || (!destHasDrive && 1 < CFStringGetLength(path))) && IS_SLASH(CFStringGetCharacterAtIndex(path, CFStringGetLength(path) - 1))) {
        CFStringDelete(path, CFRangeMake(CFStringGetLength(path) - 1, 1));
    }

    if (CFStringGetLength(path) == 0) {
        return false;
    }
    
    UniChar firstChar = CFStringGetCharacterAtIndex(path, 0);
    CFIndex newLength = CFStringGetLength(path);
    switch (newLength) {
        case 0:
            return false;
        case 1:
            if (IS_SLASH(firstChar) || firstChar == '~') {
                return false;
            }
            break;
        case 2:
            if (_hasDrive(path) || _hasNet(path)) {
                return false;
            }
            break;
        case 3:
            if (IS_SLASH(CFStringGetCharacterAtIndex(path, 2)) && _hasDrive(path)) {
                return false;
            }
            break;
    }
    if (0 < newLength && firstChar == '~') {
        // Make sure we have a slash in the string
        if (!CFStringFindWithOptions(path, CFPreferredSlashStr, CFRangeMake(1, newLength - 1), 0, NULL)) {
            return false;
        }
    }
    static const UniChar dotChar = '.';
    CFStringAppendCharacters(path, &dotChar, 1);
    CFStringAppend(path, extension);
    return true;
}
Exemplo n.º 6
0
static void _CFAppendXMLEpilog(CFMutableStringRef str, CFXMLTreeRef tree) {
    CFXMLNodeTypeCode typeID = CFXMLNodeGetTypeCode(CFXMLTreeGetNode(tree));
    if (typeID == kCFXMLNodeTypeElement) {
        if (((CFXMLElementInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)))->isEmpty) return;
        CFStringAppendFormat(str, NULL, CFSTR("</%@>"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
    } else if (typeID == kCFXMLNodeTypeDocumentType) {
        CFIndex len = CFStringGetLength(str);
        if (CFStringHasSuffix(str, CFSTR(" ["))) {
            // There were no in-line DTD elements
            CFStringDelete(str, CFRangeMake(len-2, 2));
        } else {
            CFStringAppendCString(str, "]", kCFStringEncodingASCII);
        }
        CFStringAppendCString(str, ">", kCFStringEncodingASCII);
    }
}
CFStringRef 
SecCreateRecoveryPassword(void)
{
	CFStringRef result = NULL;
	CFErrorRef error = NULL;
 	CFDataRef encodedData = NULL;
    CFDataRef randData = getRandomBytes(16);
	int i;
	
	// base32FDE is a "private" base32 encoding, it has no 0/O or L/l/1 in it (it uses 8 and 9).
	SecTransformRef	encodeTrans = SecEncodeTransformCreate(CFSTR("base32FDE"), &error);
    if(error == NULL) {
		SecTransformSetAttribute(encodeTrans, kSecTransformInputAttributeName, randData, &error);
		if(error == NULL) encodedData = SecTransformExecute(encodeTrans, &error);
     	CFRelease(encodeTrans);
   	}
    CFRelease(randData);

	if(encodedData != NULL && error == NULL) {
        CFStringRef	b32string = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, encodedData, kCFStringEncodingMacRoman);
        CFMutableStringRef encodedString = CFStringCreateMutableCopy(kCFAllocatorDefault, 64, b32string);
       
        // Add some hyphens to make the generated password easier to use
        for(i = 4; i < 34; i += 5)  CFStringInsert(encodedString, i, CFSTR("-"));
        // Trim so the last section is 4 characters long
		CFStringDelete(encodedString, CFRangeMake(29,CFStringGetLength(encodedString)-29));
        result = CFStringCreateCopy(kCFAllocatorDefault, encodedString);
        CFRelease(encodedString);
        CFRelease(b32string);
        CFRelease(encodedData);
	} else {
        secDebug(ASL_LEVEL_ERR, "Failed to base32 encode random data for recovery password\n", NULL);
    }

	return result;
	
}
Exemplo n.º 8
0
void
__NCReplaceFormatToken(
  CFMutableStringRef    string,
  CFIndex               start,
  CFIndex               end
)
{
  CFRange       cmpRange;
  int           code = -1;
  int           lo,hi,idx;
  UniChar       charToMatch = CFStringGetCharacterAtIndex(string,start + 2);
  Boolean       didLoEqualHiAlready = FALSE;
  
  //  From start+2 to end-1 is the format directive:
  cmpRange.location = start + 2;
  cmpRange.length = end - start - 2;
  
  //  We do a binary search for the token in the table:
  lo = 0;
  hi = _formatTokenCount;
  while ( (lo < hi) && (code == -1) ) {
    int         diff;
    
    idx = (hi + lo) / 2;
    diff = charToMatch - __formatTokenTable[idx].ctoken[0];
    
    //  Positive 'diff' means string is above this one;
    //  Negative 'diff' means string should be below it;
    //  Zero means we matched the first character, so we
    //  do a standard string compare to see if we got it.
    if (diff > 0)
      lo = idx;
    else if (diff < 0)
      hi = idx;
    else {
      CFComparisonResult    cmpResult;
      
      if (__formatTokenTable[idx].cftoken == NULL)
        __formatTokenTable[idx].cftoken = CFStringCreateWithCStringNoCopy(
                                                kCFAllocatorDefault,
                                                __formatTokenTable[idx].ctoken,
                                                CFCStringGetDefaultEncoding(),
                                                kCFAllocatorNull);
      cmpResult = CFStringCompareWithOptions(
                      string,
                      __formatTokenTable[idx].cftoken,
                      cmpRange,
                      0);
      switch (cmpResult) {
        case kCFCompareEqualTo:
          code = __formatTokenTable[idx].code;
          break;
        case kCFCompareLessThan:
          hi = idx;
          break;
        case kCFCompareGreaterThan:
          lo = idx;
          break;
      }
    }
    if (hi == lo) {
      if (didLoEqualHiAlready)
        break;
      else
        didLoEqualHiAlready = TRUE;
    }
  }
  
  //  Replace the full range:
  cmpRange = CFRangeMake(start,end - start + 1);
  
  if (code == -1 || !NCANSIOutputEnable) {
    //  Just remove the thing:
    CFStringDelete(string,cmpRange);
  } else {
    //  Create the ANSI sequence:
    CFStringRef     replacement;
    
    if (replacement = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("\033[%dm"),code)) {
      CFStringReplace(string,cmpRange,replacement);
      CFRelease(replacement);
    } else
      CFStringDelete(string,cmpRange);
  }
}
/* ------------------------------------------------------------------------------------------------------

SetDateValueFromFITSHeader: read FITS header and set striped string value to attribute name.

------------------------------------------------------------------------------------------------------ */
void SetDateValueFromFITSHeader(const char* filename, 
				CFMutableDictionaryRef attributes, 
				const char* importerAttrName, 
				char* mainKeyword, 
				char* secondaryKeyword1,
				char* secondaryKeyword2)
{
	CFMutableStringRef headerValue = CFStringCreateMutable(kCFAllocatorDefault, (CFIndex)80);

	CFStringRef value1 = getCleanedHeaderValue(filename, mainKeyword);
	if (value1 != NULL) {
		CFIndex valueLength1 = CFStringGetLength(value1);
		if ((valueLength1 >= 19) || (valueLength1 == 10)) {
			CFStringAppend(headerValue, value1); // value of mainKeyword looks OK.
		}
		CFRelease(value1);
	}

	CFStringRef value2 = getCleanedHeaderValue(filename, secondaryKeyword1);
	if (value2 != NULL) {
		CFIndex valueLength2 = CFStringGetLength(value2);
		CFIndex headerValueLength = CFStringGetLength(headerValue);
		if (headerValueLength == 0 && valueLength2 >= 10) {
			CFStringAppend(headerValueLength, value2); // Append value of secondaryKeyword1
		}
		else if (headerValueLength < 19 && valueLength2 >= 19) {
			CFRange range = CFRangeMake(0, headerValueLength);
			CFStringDelete(headerValue, range);
			CFStringAppend(headerValue, value2); // Replace value of current headerValue by value of secondaryKeyword1
		}
		CFRelease(value2);
	}

	CFStringRef value3 = getCleanedHeaderValue(filename, secondaryKeyword2);
	if (value3 != NULL) {
		CFRange r = CFStringFind(value3, CFSTR(":"), 0);
		CFIndex headerValueLength = CFStringGetLength(headerValue);
		if (headerValueLength == 10 && r.location != kCFNotFound) {
			CFStringAppend(headerValue, CFSTR("T"));
			CFStringAppend(headerValue, value3);
		}
		CFRelease(value3);
	}

	CFIndex headerValueLength = CFStringGetLength(headerValue);
	if (headerValueLength > 0) {
		
		CFArrayRef tArray   = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, headerValue, CFSTR("T"));
		CFArrayRef ymdArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, CFArrayGetValueAtIndex(tArray, 0), CFSTR("-"));

		CFGregorianDate gregDate;
		gregDate.year   = 0;
		gregDate.month  = 0;
		gregDate.day    = 0.;
		
		if (CFStringGetLength(CFArrayGetValueAtIndex(ymdArray, 0)) > 0) {
			gregDate.year   = CFStringGetIntValue(CFArrayGetValueAtIndex(ymdArray, 0));
		}
		if (CFStringGetLength(CFArrayGetValueAtIndex(ymdArray, 1)) > 0) {
			gregDate.month  = CFStringGetIntValue(CFArrayGetValueAtIndex(ymdArray, 1));
		}
		if (CFStringGetLength(CFArrayGetValueAtIndex(ymdArray, 2)) > 0) {
			gregDate.day    = CFStringGetIntValue(CFArrayGetValueAtIndex(ymdArray, 2));
		}
		CFRelease(ymdArray);

		gregDate.hour   = 0;
		gregDate.minute = 0;
		gregDate.second = 0.;
		
		CFIndex arraySize = CFArrayGetCount(tArray);
		if (arraySize == 2) {
			CFArrayRef hmsArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, CFArrayGetValueAtIndex(tArray, 1), CFSTR(":"));
			if (CFStringGetLength(CFArrayGetValueAtIndex(hmsArray, 0)) > 0) {
				gregDate.hour   = CFStringGetIntValue(CFArrayGetValueAtIndex(hmsArray, 0));
			}
			if (CFStringGetLength(CFArrayGetValueAtIndex(hmsArray, 1)) > 0) {
				gregDate.minute = CFStringGetIntValue(CFArrayGetValueAtIndex(hmsArray, 1));
			}
			if (CFStringGetLength(CFArrayGetValueAtIndex(hmsArray, 2)) > 0) {
				gregDate.second = CFStringGetDoubleValue(CFArrayGetValueAtIndex(hmsArray, 2));			
			}
			CFRelease(hmsArray);
		}

		CFRelease(tArray);

//		printf("%i %i %i %i %i %f\n\n", gregDate.year, gregDate.month, gregDate.day, gregDate.hour, gregDate.minute, gregDate.second);

		if ((gregDate.year > 0) && (gregDate.month > 0) && (gregDate.day > 0)) {
			CFTimeZoneRef timeZone = CFTimeZoneCreateWithName(kCFAllocatorDefault, CFSTR("GMT"), true);
			CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime(gregDate, timeZone);
			CFDateRef date = CFDateCreate(kCFAllocatorDefault, absTime);

			if (timeZone != NULL) {
				CFRelease(timeZone);
			}

			CFStringRef cfImporterAttrName = CFStringCreateWithCString(kCFAllocatorDefault, importerAttrName, kCFStringEncodingUTF8);
			CFDictionaryAddValue(attributes, cfImporterAttrName, date);
			CFRelease(cfImporterAttrName);
			CFRelease(date);
		}
	}

	CFRelease(headerValue);
}
Exemplo n.º 10
0
static CFStringRef
copy_default_name(void)
{
	CFStringRef		model;
	size_t			n;
	CFMutableStringRef	str;

	// get HW model name
	model = _SC_hw_model(TRUE);
	if (model == NULL) {
		return NULL;
	}

	// start off with the [trunated] HW model
	str = CFStringCreateMutable(NULL, 0);
	CFStringAppend(str, model);

	// truncate as needed
	n = CFStringGetLength(str);
	if (n > (NETBIOS_NAME_LEN - 1)) {
		CFStringReplace(str,
				CFRangeMake(NETBIOS_NAME_LEN, n - (NETBIOS_NAME_LEN - 1)),
				CFSTR(""));
		n = NETBIOS_NAME_LEN - 1;
	}

	//
	// if there is room for at least one byte (two hex characters)
	// of the MAC address than append that to the NetBIOS name.
	//
	//    NETBIOS_NAME_LEN	max length
	//      -1		the last byte is reserved
	//      -3		"-XX"
	//
	if (n < (NETBIOS_NAME_LEN - 1 - 3)) {
		SCNetworkInterfaceRef	interface;

		interface = _SCNetworkInterfaceCreateWithBSDName(NULL, CFSTR("en0"),
								 kIncludeNoVirtualInterfaces);
		if (interface != NULL) {
			CFMutableStringRef	en0_MAC;

			en0_MAC = (CFMutableStringRef)SCNetworkInterfaceGetHardwareAddressString(interface);
			if (en0_MAC != NULL) {
				CFIndex	en0_MAC_len;

				// remove ":" characters from MAC address string
				en0_MAC = CFStringCreateMutableCopy(NULL, 0, en0_MAC);
				CFStringFindAndReplace(en0_MAC,
						       CFSTR(":"),
						       CFSTR(""),
						       CFRangeMake(0, CFStringGetLength(en0_MAC)),
						       0);

				//
				// compute how may bytes (characters) to append
				//    ... and limit that number to 6
				//
				//    NETBIOS_NAME_LEN	max length
				//      -1		the last byte is reserved
				//	-n		"iMac"
				//      -1		"-"
				//
				n = ((NETBIOS_NAME_LEN - 1 - n - 1) / 2) * 2;
				if (n > 6) {
					n = 6;
				}

				// remove what we don't want
				en0_MAC_len = CFStringGetLength(en0_MAC);
				if (en0_MAC_len > n) {
					CFStringDelete(en0_MAC, CFRangeMake(0, en0_MAC_len - n));
				}

				// append
				CFStringAppendFormat(str, NULL, CFSTR("-%@"), en0_MAC);
				CFRelease(en0_MAC);
			}

			CFRelease(interface);
		}
	}

	CFStringUppercase(str, NULL);
	return str;
}
Exemplo n.º 11
0
static void
ptr_query_callback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info)
{
	CFDictionaryRef		dict;
	CFStringRef		name;
	CFMutableDictionaryRef	newDict;
	struct timeval		ptrQueryComplete;
	struct timeval		ptrQueryElapsed;

	(void) gettimeofday(&ptrQueryComplete, NULL);
	timersub(&ptrQueryComplete, &ptrQueryStart, &ptrQueryElapsed);
	my_log(LOG_INFO, "NetBIOS name: ptr query complete%s (query time = %ld.%3.3d)",
	       (flags & kSCNetworkReachabilityFlagsReachable) ? "" : ", host not found",
	       ptrQueryElapsed.tv_sec,
	       ptrQueryElapsed.tv_usec / 1000);

	// get network configuration
	dict = smb_copy_global_configuration(store);

	// use NetBIOS name from network configuration (if available)
	name = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSName);
	if ((name != NULL) && _SC_CFStringIsValidNetBIOSName(name)) {
		my_log(LOG_INFO, "NetBIOS name (network configuration) = %@", name);
		goto setDict;
	}

	// use reverse DNS name, if available

	name = NULL;
	if (flags & kSCNetworkReachabilityFlagsReachable) {
		int		error_num;
		CFArrayRef	hosts;

		/*
		 * if [reverse] DNS query was successful
		 */
		hosts = SCNetworkReachabilityCopyResolvedAddress(target, &error_num);
		if (hosts != NULL) {
			if (CFArrayGetCount(hosts) > 0) {
				CFIndex			ptrLen;
				CFMutableStringRef	ptrName;
				CFRange			range;

				name = CFArrayGetValueAtIndex(hosts, 0);
				ptrName = CFStringCreateMutableCopy(NULL, 0, name);
				ptrLen = CFStringGetLength(ptrName);
				if (CFStringFindWithOptions(ptrName,
							    CFSTR("."),
							    CFRangeMake(0, ptrLen),
							    0,
							    &range)) {
					CFStringDelete(ptrName,
						       CFRangeMake(range.location, ptrLen - range.location));
				}
				name = ptrName;
			}
			CFRelease(hosts);
		}
	}
	if (name != NULL) {
		if (_SC_CFStringIsValidNetBIOSName(name)) {
			my_log(LOG_INFO, "NetBIOS name (reverse DNS query) = %@", name);
			goto setName;
		}
		CFRelease(name);
	}

	// try local (multicast DNS) name, if available
	name = SCDynamicStoreCopyLocalHostName(store);
	if (name != NULL) {
		if (_SC_CFStringIsValidNetBIOSName(name)) {
			my_log(LOG_INFO, "NetBIOS name (multicast DNS) = %@", name);
			goto setName;
		}
		CFRelease(name);
	}

	// use "default" name
	name = copy_default_name();
	if (name != NULL) {
		my_log(LOG_INFO, "NetBIOS name (default) = %@", name);
		goto setName;
	}

	goto setDict;

    setName :

	newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
	CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
	CFRelease(dict);
	dict = newDict;
	CFRelease(name);

    setDict :

	// update SMB configuration
	smb_set_configuration(store, dict);
	CFRelease(dict);

	ptr_query_stop();

#ifdef	MAIN
	CFRunLoopStop(rl);
#endif	// MAIN

	return;
}
Exemplo n.º 12
0
CF_INLINE void _fillStringWithCharacters(CFMutableStringRef string, UniChar *characters, CFIndex numChars) {
    CFStringDelete(string, CFRangeMake(0, CFStringGetLength(string)));
    if (numChars) {
        CFStringAppendCharacters(string, characters, numChars);
    }
}
Exemplo n.º 13
0
Arquivo: parse_url.c Projeto: aosm/smb
/*
 * We need to create the from name. The from name is just a URL without the scheme. We 
 * never put the password in the from name, but if they have an empty password then we
 * need to make sure that it's included.
 *
 * Examples: 
 *	URL "smb://username:@server/share" - Empty password, just remove the scheme.
 *	URL "smb://*****:*****@server/share" - Need to remove the password and the scheme.
 *	URL "smb://username@server" - Need to add the share and remove the scheme.
 *	URL "smb://server" - Need to add the username and share and remove the scheme.
 *	URL "smb://server/share/path" - Need to add the usernameand remove the scheme.
 */
void CreateSMBFromName(struct smb_ctx *ctx, char *fromname, int maxlen)
{
	CFMutableStringRef urlStringM = NULL;
	CFMutableStringRef newUrlStringM = NULL;
	CFMutableDictionaryRef mutableDict = NULL;
	CFStringRef Password = NULL;
	int SchemeLength = 0;
	int error = 0;;
	
	/* Always start with the original url and a cleaned out the from name */
	bzero(fromname, maxlen);
	SchemeLength = SMBSchemeLength(ctx->ct_url);
	urlStringM = CFStringCreateMutableCopy(NULL, 0, CFURLGetString(ctx->ct_url));
	if (urlStringM == NULL) {
		smb_log_info("Failed creating URL string, syserr = %s", ASL_LEVEL_ERR, strerror(errno));
		return;
	}
	
	error = smb_url_to_dictionary(ctx->ct_url, (CFDictionaryRef *)&mutableDict);
	if (error || (mutableDict == NULL)) {
		smb_log_info("Failed parsing URL, syserr = %s", ASL_LEVEL_DEBUG, strerror(error));
		goto WeAreDone;
	}
	UpdateDictionaryWithUserAndShare(ctx, mutableDict);
	
	Password = CFDictionaryGetValue(mutableDict, kNetFSPasswordKey);
	/* 
	 * If there is a password and its not an empty password then remove it. Never
	 * show the password in the mount from name.
	 */
	if (Password && (CFStringGetLength(Password) > 0)) {
		CFDictionaryRemoveValue(mutableDict, kNetFSPasswordKey);
	}
	/* Guest access has an empty password. */
	if (ctx->ct_setup.ioc_userflags & SMBV_GUEST_ACCESS)
		CFDictionarySetValue (mutableDict, kNetFSPasswordKey, CFSTR(""));

	/* 
	 * Recreate the URL from our new dictionary. The old code would not escape
	 * out the share/path, which can cause us issue. Now the from name can look
	 * pretty goofy, but we will always work with alias. Now this was originally
	 * done because carbon would use the last part of the mount from name as the
	 * volume name. We now return the volume name, so this is no longer an issue.
	 */
	error = smb_dictionary_to_urlstring(mutableDict, &newUrlStringM);
	if (error || (newUrlStringM == NULL)) {
		smb_log_info("Failed parsing dictionary, syserr = %s", ASL_LEVEL_DEBUG, 
					 strerror(error));
		goto WeAreDone;	
	}
	if (urlStringM)
		CFRelease(urlStringM);
	urlStringM = newUrlStringM;
	newUrlStringM = NULL;
	/* smb_dictionary_to_urlstring always uses the SMB scheme */
	SchemeLength = SMB_SCHEME_LEN;
	if (CFStringGetLength(urlStringM) < (maxlen+SchemeLength))
		goto WeAreDone;
	
	/* 
	 * At this point the URL is too big to fit in the mount from name. See if
	 * removing the username will make it fit. 
	 */
	CFDictionaryRemoveValue(mutableDict, kNetFSUserNameKey);
	CFDictionaryRemoveValue(mutableDict, kNetFSPasswordKey);
	
	
	/* 
	 * Recreate the URL from our new dictionary. The old code would not escape
	 * out the share/path, which can cause us issue. Now the from name can look
	 * pretty goofy, but we will always work with alias. Now this was originally
	 * done because carbon would use the last part of the mount from name as the
	 * volume name. We now return the volume name, so this is no longer an issue.
	 */
	error = smb_dictionary_to_urlstring(mutableDict, &newUrlStringM);
	if (error || (newUrlStringM == NULL)) {
		smb_log_info("Removing username failed parsing dictionary, syserr = %s", 
					 ASL_LEVEL_DEBUG, strerror(error));
		goto WeAreDone;
	}
	if (urlStringM)
		CFRelease(urlStringM);
	urlStringM = newUrlStringM;
	newUrlStringM = NULL;
	
WeAreDone:
	if (urlStringM && (SchemeLength > 0)) {
		/* Remove the scheme, start at the begining */
		CFRange range1 = CFRangeMake(0, SchemeLength);
		CFStringDelete(urlStringM, range1);		
	}
	if (urlStringM)
		CFStringGetCString(urlStringM, fromname, maxlen, kCFStringEncodingUTF8);
	if (error)
		smb_log_info("Mount from name is %s, syserr = %s", ASL_LEVEL_ERR, 
					 fromname, strerror(error));
	else
		smb_log_info("Mount from name is %s", ASL_LEVEL_DEBUG, fromname);
	
	if (urlStringM)
		CFRelease(urlStringM);
	if (mutableDict)
		CFRelease(mutableDict);	
}
Exemplo n.º 14
0
Boolean GetMetadataForFile(void* thisInterface, 
			   CFMutableDictionaryRef attributes, 
			   CFStringRef contentTypeUTI,
			   CFStringRef pathToFile)
{
    Boolean success = false;

	CFDictionaryRef	tempDictRef;
	CFStringRef		tempTitleRef;
	CFArrayRef		tempContentRef;

	// load the document at the specified location	
	CFURLRef		pathToFileURL;
	pathToFileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, pathToFile, kCFURLPOSIXPathStyle, false);
	tempDictRef = (CFDictionaryRef)CreatePropertiesFromXMLFile(pathToFileURL);
    CFRelease(pathToFileURL);

    if (tempDictRef)
    {
		CFStringRef	tempBrdNameRef;
		CFStringRef	tempDatNumberRef;
		CFNumberRef	tempLengthRef;
		CFDateRef	tempCreatedDateRef;
		CFDateRef	tempModifiedDateRef;

		CFDictionarySetValue(attributes, kMDItemCreator, CFSTR("BathyScaphe"));

		// set the kMDItemTitle attribute to the Title
		tempTitleRef = CFDictionaryGetValue(tempDictRef, CFSTR("Title"));
		if (tempTitleRef != NULL) {
			CFDictionarySetValue(attributes, kMDItemTitle, tempTitleRef);
			CFDictionarySetValue(attributes, kMDItemDisplayName, tempTitleRef);
		}
		
		tempBrdNameRef = CFDictionaryGetValue(tempDictRef, CFSTR("BoardName"));
		if (tempBrdNameRef != NULL)
			CFDictionarySetValue(attributes, CFSTR("jp_tsawada2_bathyscaphe_thread_BoardName"), tempBrdNameRef);

		tempDatNumberRef = CFDictionaryGetValue(tempDictRef, CFSTR("dat"));
		if (tempDatNumberRef != NULL)
			CFDictionarySetValue(attributes, CFSTR("jp_tsawada2_bathyscaphe_thread_DatNumber"), tempDatNumberRef);

		tempLengthRef = CFDictionaryGetValue(tempDictRef, CFSTR("Length"));
		if (tempLengthRef != NULL)
			CFDictionarySetValue(attributes, CFSTR("jp_tsawada2_bathyscaphe_thread_DatSize"), tempLengthRef);

		tempCreatedDateRef = CFDictionaryGetValue(tempDictRef, CFSTR("CreatedDate"));
		if (tempCreatedDateRef != NULL)
			CFDictionarySetValue(attributes, kMDItemContentCreationDate, tempCreatedDateRef);

		tempModifiedDateRef = CFDictionaryGetValue(tempDictRef, CFSTR("ModifiedDate"));
		if (tempModifiedDateRef != NULL)
			CFDictionarySetValue(attributes, kMDItemContentModificationDate, tempModifiedDateRef);

		tempContentRef = CFDictionaryGetValue(tempDictRef, CFSTR("Contents"));
		if (tempContentRef) {
			CFIndex	i, count_;
			CFNumberRef	countRef_;
			CFMutableStringRef	cont_ = CFStringCreateMutable(kCFAllocatorDefault, 0);
			CFMutableArrayRef	nameArray_ = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
			CFDictionaryRef	obj;
			CFNumberRef		statusStr;

			count_ = CFArrayGetCount(tempContentRef);

			countRef_ = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &count_);
			CFDictionarySetValue(attributes, CFSTR("jp_tsawada2_bathyscaphe_thread_ResCount"), countRef_);
			CFRelease(countRef_);
			
			for (i=0; i<count_; i++) {
				obj = CFArrayGetValueAtIndex(tempContentRef, i);

				if (obj == NULL) continue;
				statusStr = CFDictionaryGetValue(obj, CFSTR("Status"));
				if (isNotAbonedRes(statusStr)) {
					CFStringRef	msg_;
					CFStringRef	name_;

					msg_ = CFDictionaryGetValue(obj, CFSTR("Message"));
					if (msg_) {
						CFStringAppend(cont_, msg_);
					}

					name_ = CFDictionaryGetValue(obj, CFSTR("Name"));
					if (name_) {
						Boolean already_ = CFArrayContainsValue(nameArray_, CFRangeMake(0, CFArrayGetCount(nameArray_)), name_);
						if (already_ == false) CFArrayAppendValue(nameArray_, name_);
					}
				}
			}

			CFStringFindAndReplace(cont_, CFSTR(" <br> "), CFSTR(""), CFRangeMake(0, CFStringGetLength(cont_)), 0);
			CFStringTrimWhitespace(cont_);
																	
			CFIndex	len;
			CFRange	searchRange;
			CFRange	resultRange;
			CFRange	gtRange;

			len = CFStringGetLength(cont_);
			searchRange = CFRangeMake(0, len);

			while (1) {
				Boolean	found_ = CFStringFindWithOptions(cont_, CFSTR("<a "), searchRange, kCFCompareCaseInsensitive, &resultRange);
				if (found_ == false) break;
				// Start searching next to "<"
				searchRange.location = resultRange.location + resultRange.length;
				searchRange.length = (len - searchRange.location);

				found_ = CFStringFindWithOptions(cont_, CFSTR("</a>"), searchRange, kCFCompareCaseInsensitive, &gtRange);
				if (found_ == false) break;
				resultRange.length = gtRange.location + gtRange.length - resultRange.location;
				CFStringDelete(cont_, resultRange);

				searchRange.length -= resultRange.length;
				len -= resultRange.length;
				
				if (searchRange.location >= len) break;
			}

			CFDictionarySetValue(attributes, kMDItemTextContent, cont_);
			CFDictionarySetValue(attributes, kMDItemContributors, nameArray_);
			
			CFRelease(cont_);
			CFRelease(nameArray_);
		}
		// release the loaded document
		CFRelease(tempDictRef);
		// return YES so that the attributes are imported
		success = true;
    }
    return success;
}
static
CFArrayRef _SecIdentityCopyPossiblePaths(
    CFStringRef name)
{
    // utility function to build and return an array of possible paths for the given name.
    // if name is not a URL, this returns a single-element array.
    // if name is a URL, the array may contain 1..N elements, one for each level of the path hierarchy.

    CFMutableArrayRef names = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    if (!name) {
        return names;
    }
    CFIndex oldLength = CFStringGetLength(name);
    CFArrayAppendValue(names, name);

    CFURLRef url = CFURLCreateWithString(NULL, name, NULL);
    if (url) {
		if (CFURLCanBeDecomposed(url)) {
			// first, remove the query portion of this URL, if any
			CFStringRef qs = CFURLCopyQueryString(url, NULL);
			if (qs) {
				CFMutableStringRef newName = CFStringCreateMutableCopy(NULL, oldLength, name);
				if (newName) {
					CFIndex qsLength = CFStringGetLength(qs) + 1; // include the '?'
					CFStringDelete(newName, CFRangeMake(oldLength-qsLength, qsLength));
					CFRelease(url);
					url = CFURLCreateWithString(NULL, newName, NULL);
					CFArraySetValueAtIndex(names, 0, newName);
					CFRelease(newName);
				}
				CFRelease(qs);
			}
			// now add an entry for each level of the path
			while (url) {
				CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(NULL, url);
				if (parent) {
					CFStringRef parentURLString = CFURLGetString(parent);
					if (parentURLString) {
						CFIndex newLength = CFStringGetLength(parentURLString);
						// check that string length has decreased as expected; for file URLs,
						// CFURLCreateCopyDeletingLastPathComponent can insert './' or '../'
						if ((newLength >= oldLength) || (!CFStringHasPrefix(name, parentURLString))) {
							CFRelease(parent);
							CFRelease(url);
							break;
						}
						oldLength = newLength;
						CFArrayAppendValue(names, parentURLString);
					}
				}
				CFRelease(url);
				url = parent;
			}
		}
		else {
			CFRelease(url);
		}
	}
	// finally, add wildcard entries for each subdomain
	url = CFURLCreateWithString(NULL, name, NULL);
	if (url) {
		if (CFURLCanBeDecomposed(url)) {
			CFStringRef netLocString = CFURLCopyNetLocation(url);
			if (netLocString) {
				// first strip off port number, if present
				CFStringRef tmpLocString = netLocString;
				CFArrayRef hostnameArray = CFStringCreateArrayBySeparatingStrings(NULL, netLocString, CFSTR(":"));
				tmpLocString = (CFStringRef)CFRetain((CFStringRef)CFArrayGetValueAtIndex(hostnameArray, 0));
				CFRelease(netLocString);
				CFRelease(hostnameArray);
				netLocString = tmpLocString;
				// split remaining string into domain components
				hostnameArray = CFStringCreateArrayBySeparatingStrings(NULL, netLocString, CFSTR("."));
				CFIndex subdomainCount = CFArrayGetCount(hostnameArray);
				CFIndex i = 0;
				while (++i < subdomainCount) {
					CFIndex j = i;
					CFMutableStringRef wildcardString = CFStringCreateMutable(NULL, 0);
					if (wildcardString) {
						CFStringAppendCString(wildcardString, "*", kCFStringEncodingUTF8);
						while (j < subdomainCount) {
							CFStringRef domainString = (CFStringRef)CFArrayGetValueAtIndex(hostnameArray, j++);
							if (CFStringGetLength(domainString) > 0) {
								CFStringAppendCString(wildcardString, ".", kCFStringEncodingUTF8);
								CFStringAppend(wildcardString, domainString);
							}
						}
						if (CFStringGetLength(wildcardString) > 1) {
							CFArrayAppendValue(names, wildcardString);
						}
						CFRelease(wildcardString);
					}
				}
				CFRelease(hostnameArray);
				CFRelease(netLocString);
			}
		}
		CFRelease(url);
	}

    return names;
}
Exemplo n.º 16
0
Boolean APSetKey(CFStringRef key)
{
    hash = CFSTR("");
    blacklist = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    
    CFMutableStringRef mutableKey = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, key);
    CFStringRef preparedKey = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, key);
    CFLocaleRef currentLocale = CFLocaleCopyCurrent();
    CFStringLowercase(mutableKey, currentLocale);
    CFRelease(currentLocale);
    
    if (CFStringHasPrefix(mutableKey, CFSTR("0x")) && CFStringGetLength(mutableKey) > 2)
    {
        CFStringDelete(mutableKey, CFRangeMake(0, 2));
    }
    if (CFStringGetLength(mutableKey) == 1024/8*2)
    {
        CFRelease(preparedKey);
        preparedKey = APPEMKeyCreateFromHexKey(mutableKey);
    }
    CFRelease(mutableKey);
    
    
    SecItemImportExportKeyParameters params = {0};
    params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
    params.flags = kSecKeyNoAccessControl;
    SecExternalItemType itemType = kSecItemTypePublicKey;
    SecExternalFormat externalFormat = kSecFormatPEMSequence;
    CFArrayRef tempArray = NULL;
    OSStatus oserr = noErr;
    
    // Set the key as extractable. Looking through the source code in SecImportExportUtils.cpp
    // it looks like this isn't handled, yet it seems to be documented to me. One day the code
    // may catch up, so I'm leaving this here to show the intention.
    CFNumberRef attributeFlags[1];
    uint32 flag0value = CSSM_KEYATTR_EXTRACTABLE;
    CFNumberRef flag0 = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &flag0value);
    attributeFlags[0] = flag0;
    CFArrayRef keyAttributes = CFArrayCreate(kCFAllocatorDefault, (const void **)attributeFlags, 1, &kCFTypeArrayCallBacks);
    CFRelease(flag0);
    params.keyAttributes = keyAttributes;
    
    CFDataRef keyData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, preparedKey, kCFStringEncodingUTF8, 0);
    CFRelease(preparedKey);
    
    oserr = SecItemImport(keyData,
                          NULL,
                          &externalFormat,
                          &itemType,
                          0,
                          &params,
                          NULL,
                          &tempArray);
    CFRelease(keyAttributes);
    CFRelease(keyData);
    
    if (oserr != noErr) {
        CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Unable to import key. Error %d"), oserr);
        CFShow(errorString);
        CFRelease(errorString);
        return FALSE;
    }
    
    publicKeyRef = (SecKeyRef)CFArrayGetValueAtIndex(tempArray, 0);
    CFRetain(publicKeyRef);
    CFRelease(tempArray);
    
    return TRUE;
}
Exemplo n.º 17
0
int main(int argc, char * argv[]) {
    signal(SIGINT, sigint_handler);

    bool israw = false;
    bool readstdin = false;
    char* code = NULL;
    bool usecolors = true;

    int ch;
    while ((ch = getopt(argc, argv, "nirc:t:sh")) != -1) {
        switch (ch) {
            case 'n': usecolors = false; break;
            case 'i': break;
            case 'r': israw = true; break;
            case 'c': code = optarg; break;
            case 't': recvTimeout = strtod(optarg, NULL); break;
            case 's': readstdin = true; break;
            case 'h': case '?': default:
                usage(argv[0]);
        }
    }

    if (optind != argc) usage(argv[0]);

    argc -= optind;
    argv += optind;

    CFMessagePortRef port = CFMessagePortCreateRemote(NULL, CFSTR("Hammerspoon"));

    if (!port) {
        fprintf(stderr, "error: can't access Hammerspoon; is it running with the ipc module loaded?\n");
        return 1;
    }

    CFMutableStringRef str = CFStringCreateMutable(NULL, 0);

    if (readstdin) {
        target_setprefix(str, israw);

        char buffer[BUFSIZ];
        while (fgets(buffer, BUFSIZ, stdin))
            CFStringAppendCString(str, buffer, kCFStringEncodingUTF8);

        if (ferror(stdin)) {
            perror("error reading from stdin.");
            exit(3);
        }

        target_send(port, str);
    }
    else if (code) {
        target_setprefix(str, israw);
        CFStringAppendCString(str, code, kCFStringEncodingUTF8);
        target_send(port, str);
    }
    else {
        if (usecolors)
            setupcolors();

        printf("%sHammerspoon interactive prompt.%s\n", COLOR_INITIAL, COLOR_RESET);

        while (1) {
            printf("\n%s", COLOR_INPUT);
            char* input = readline("> ");
            printf("%s", COLOR_RESET);
            if (!input) { printf("\n") ; exit(0); }
            add_history(input);

            if (!CFMessagePortIsValid(port)) {
                fprintf(stderr, "%sMessage port has become invalid.  Attempting to re-establish.%s\n", COLOR_INITIAL, COLOR_RESET);
                port = CFMessagePortCreateRemote(NULL, CFSTR("Hammerspoon"));
                if (!port) {
                    fprintf(stderr, "error: can't access Hammerspoon; is it running?\n");
                    exit(1);
                }

            }

            target_setprefix(str, israw);
            CFStringAppendCString(str, input, kCFStringEncodingUTF8);
            target_send(port, str);
            CFStringDelete(str, CFRangeMake(0, CFStringGetLength(str)));

            free(input);
        }
    }

    return 0;
}
Exemplo n.º 18
0
int
main(int argc, char **argv)
{
	const char		*command	= argv[0];
	extern int		optind;
	int			opt;
	CFStringRef		current		= NULL;
	int			currentMatched	= 0;
	CFStringRef		newSet		= NULL;	/* set key */
	CFStringRef		newSetUDN	= NULL;	/* user defined name */
	CFStringRef		prefix;
	SCPreferencesRef	prefs;
	CFDictionaryRef		sets;
	CFIndex			nSets;
	const void		**setKeys	= NULL;
	const void		**setVals	= NULL;
	CFIndex			i;

#if	!TARGET_OS_IPHONE
	AuthorizationRef	authorization	= NULL;
	AuthorizationFlags	flags		= kAuthorizationFlagDefaults;
	CFMutableDictionaryRef	options;
	OSStatus		status;
#endif	// !TARGET_OS_IPHONE

	/* process any arguments */

	while ((opt = getopt_long(argc, argv, "dvn", longopts, NULL)) != -1) {
		switch(opt) {
			case 'd':
				_sc_debug = TRUE;
				_sc_log   = FALSE;	/* enable framework logging */
				break;
			case 'v':
				_sc_verbose = TRUE;
				break;
			case 'n':
				apply = FALSE;
				break;
			case '?':
			default :
				usage(command);
		}
	}
	argc -= optind;
	argv += optind;

	prefix = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/"), kSCPrefSets);

	if (argc == 1) {
		newSet = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);

		/* check if a full path to the new "set" was specified */
		if ((CFStringGetLength(newSet) > 0) && CFStringHasPrefix(newSet, prefix)) {
			CFRange			range;
			CFMutableStringRef	str;

			str = CFStringCreateMutableCopy(NULL, 0, newSet);
			CFRelease(newSet);

			CFStringDelete(str, CFRangeMake(0, CFStringGetLength(prefix)));
			newSet = CFStringCreateCopy(NULL, newSet);
			CFRelease(str);

			range = CFStringFind(newSet, CFSTR("/"), 0);
			if (range.location != kCFNotFound) {
				SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available\n."), newSet);
				exit (1);
			}
		}
	} else {
		newSet = CFRetain(CFSTR(""));
	}

#if	!TARGET_OS_IPHONE
	status = AuthorizationCreate(NULL,
				     kAuthorizationEmptyEnvironment,
				     flags,
				     &authorization);
	if (status != errAuthorizationSuccess) {
		SCPrint(TRUE,
			stderr,
			CFSTR("AuthorizationCreate() failed: status = %d\n"),
			(int)status);
		exit (1);
	}

	options = CFDictionaryCreateMutable(NULL,
					    0,
					    &kCFTypeDictionaryKeyCallBacks,
					    &kCFTypeDictionaryValueCallBacks);
	CFDictionarySetValue(options, kSCPreferencesOptionChangeNetworkSet, kCFBooleanTrue);
	prefs = SCPreferencesCreateWithOptions(NULL, CFSTR("scselect"), NULL, authorization, options);
	CFRelease(options);
	if (prefs == NULL) {
		SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
		exit (1);
	}
#else	// !TARGET_OS_IPHONE
	prefs = SCPreferencesCreate(NULL, CFSTR("scselect"), NULL);
	if (prefs == NULL) {
		SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
		exit (1);
	}
#endif	// !TARGET_OS_IPHONE

	sets = SCPreferencesGetValue(prefs, kSCPrefSets);
	if (sets == NULL) {
		SCPrint(TRUE, stderr, CFSTR("No network sets defined.\n"));
		exit (1);
	}

	current = SCPreferencesGetValue(prefs, kSCPrefCurrentSet);
	if (current != NULL) {
		if (CFStringHasPrefix(current, prefix)) {
			CFMutableStringRef	tmp;

			tmp = CFStringCreateMutableCopy(NULL, 0, current);
			CFStringDelete(tmp, CFRangeMake(0, CFStringGetLength(prefix)));
			current = tmp;
		} else {
			CFRetain(current);
			currentMatched = -1;	/* not prefixed */
		}
	} else {
		current = CFRetain(CFSTR(""));
		currentMatched = -2;	/* not defined */
	}

	nSets = CFDictionaryGetCount(sets);
	if (nSets > 0) {
		setKeys = CFAllocatorAllocate(NULL, nSets * sizeof(CFStringRef), 0);
		setVals = CFAllocatorAllocate(NULL, nSets * sizeof(CFDictionaryRef), 0);
		CFDictionaryGetKeysAndValues(sets, setKeys, setVals);
	}

	/* check for set with matching name */
	for (i = 0; i < nSets; i++) {
		CFStringRef	key  = (CFStringRef)    setKeys[i];
		CFDictionaryRef	dict = (CFDictionaryRef)setVals[i];

		if ((currentMatched >= 0) && CFEqual(key, current)) {
			currentMatched++;
		}

		if (CFEqual(newSet, key)) {
			newSetUDN = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
			if (newSetUDN != NULL) CFRetain(newSetUDN);
			goto found;
		}
	}

	/* check for set with matching user-defined name */
	for (i = 0; i < nSets; i++) {
		CFStringRef	key  = (CFStringRef)    setKeys[i];
		CFDictionaryRef	dict = (CFDictionaryRef)setVals[i];

		newSetUDN = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
		if ((newSetUDN != NULL) && CFEqual(newSet, newSetUDN)) {
			CFRelease(newSet);
			newSet = CFRetain(key);
			CFRetain(newSetUDN);
			goto found;
		}
	}

	if (argc == 1) {
		SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n"), newSet);
		exit(1);
	}

	SCPrint(TRUE, stdout,
		CFSTR("Defined sets include:%s\n"),
		(currentMatched > 0) ? " (* == current set)" : "");

	for (i = 0; i < nSets; i++) {
		CFStringRef	key  = (CFStringRef)    setKeys[i];
		CFDictionaryRef	dict = (CFDictionaryRef)setVals[i];
		CFStringRef	udn  = CFDictionaryGetValue(dict, kSCPropUserDefinedName);

		SCPrint(TRUE, stdout,
			CFSTR(" %s %@\t(%@)\n"),
			((currentMatched > 0) && CFEqual(key, current)) ? "*" : " ",
			key,
			udn ? udn : CFSTR(""));
	}

	switch (currentMatched) {
		case -2 :
			SCPrint(TRUE, stdout, CFSTR("\nCurrent set not defined.\n"));
			break;
		case -1 :
			SCPrint(TRUE, stdout, CFSTR("\nCurrent set \"%@\" may not be valid\n"), current);
			break;
		case  0 :
			SCPrint(TRUE, stdout, CFSTR("\nCurrent set \"%@\" not valid\n"), current);
			break;
		default :
			break;
	}

	CFRelease(prefix);
	exit (0);

    found :

	CFRelease(current);
	current = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, newSet);

	if (!SCPreferencesSetValue(prefs, kSCPrefCurrentSet, current)) {
		SCPrint(TRUE, stderr,
			CFSTR("SCPreferencesSetValue(...,%@,%@) failed: %s\n"),
			kSCPrefCurrentSet,
			current,
			SCErrorString(SCError()));
		exit (1);
	}

	if (!SCPreferencesCommitChanges(prefs)) {
		int	sc_status	= SCError();

		if (sc_status == kSCStatusAccessError) {
			SCPrint(TRUE, stderr,
				CFSTR("Only local console users and administrators can change locations\n"));
			exit (EX_NOPERM);
		} else {
			SCPrint(TRUE, stderr,
				CFSTR("SCPreferencesCommitChanges() failed: %s\n"),
				SCErrorString(sc_status));
			exit (1);
		}
	}

	if (apply) {
		if (!SCPreferencesApplyChanges(prefs)) {
			SCPrint(TRUE, stderr,
				CFSTR("SCPreferencesApplyChanges() failed %s\n"),
				SCErrorString(SCError()));
			exit (1);
		}
	}

	SCPrint(TRUE, stdout,
		CFSTR("%@ updated to %@ (%@)\n"),
		kSCPrefCurrentSet,
		newSet,
		newSetUDN ? newSetUDN : CFSTR(""));

	CFRelease(current);
	CFRelease(newSet);
	if (newSetUDN != NULL)	CFRelease(newSetUDN);
	CFRelease(prefix);
	CFRelease(prefs);

#if	!TARGET_OS_IPHONE
	AuthorizationFree(authorization, kAuthorizationFlagDefaults);
//	AuthorizationFree(authorization, kAuthorizationFlagDestroyRights);
#endif	/* !TARGET_OS_IPHONE */

	exit (0);
	return 0;
}