Beispiel #1
0
func LoadInfoRaw(kextID string) (map[interface{}]interface{}, error) {
	cfKextID, err := StringToCFString(kextID)
	if cfKextID != nil {
		defer Release(C.CFTypeRef(cfKextID))
	}
	if err != nil {
		return nil, err
	}
	cfKextIDs := ArrayToCFArray([]C.CFTypeRef{C.CFTypeRef(cfKextID)})
	if cfKextIDs != nil {
		defer Release(C.CFTypeRef(cfKextIDs))
	}

	cfDict := C.KextManagerCopyLoadedKextInfo(cfKextIDs, nil)

	m, err := ConvertCFDictionary(cfDict)
	if err != nil {
		return nil, err
	}

	info, hasKey := m[kextID]
	if !hasKey {
		return nil, nil
	}

	var ret, cast = info.(map[interface{}]interface{})
	if !cast {
		return nil, fmt.Errorf("Unexpected value for kext info")
	}

	return ret, nil
}
Beispiel #2
0
// Given a PostScript font name the function will attempt to load a matching
// font and return a font object back to the caller.
//
// If no font with the given name is found a font that most closely resembles
// what was requested will be returned instead based on the platform's fallback
// mechanism.
// More details on the mechanism can be found at:
// https://developer.apple.com/library/mac/documentation/Carbon/Reference/CTFontRef/#//apple_ref/c/func/CTFontCreateWithName
//
// The function returns an error if loading the font failed for any reason.
func NewFontWithName(fontName string) (font *Font, err error) {
	cfname := GoStringToCFString(fontName)
	defer C.CFRelease(C.CFTypeRef(cfname))

	font = &Font{
		ref: C.CTFontCreateWithName(cfname, 0.0, nil),
	}

	if font.ref == nil {
		err = fmt.Errorf("CoreText failed to craete a CTFontRef object with name '%s'", fontName)
		return
	}

	runtime.SetFinalizer(font, (*Font).release)

	name := C.CTFontCopyPostScriptName(font.ref)
	defer C.CFRelease(C.CFTypeRef(name))

	family := C.CTFontCopyFamilyName(font.ref)
	defer C.CFRelease(C.CFTypeRef(family))

	display := C.CTFontCopyDisplayName(font.ref)
	defer C.CFRelease(C.CFTypeRef(display))

	font.name = CFStringToGoString(name)
	font.family = CFStringToGoString(family)
	font.display = CFStringToGoString(display)
	return
}
Beispiel #3
0
func loadSystemRoots() (*CertPool, error) {
	roots := NewCertPool()

	var data C.CFDataRef = nil
	var untrustedData C.CFDataRef = nil
	err := C.FetchPEMRoots(&data, &untrustedData)
	if err == -1 {
		// TODO: better error message
		return nil, errors.New("crypto/x509: failed to load darwin system roots with cgo")
	}

	defer C.CFRelease(C.CFTypeRef(data))
	buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
	roots.AppendCertsFromPEM(buf)
	if untrustedData == nil {
		return roots, nil
	}
	defer C.CFRelease(C.CFTypeRef(untrustedData))
	buf = C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(untrustedData)), C.int(C.CFDataGetLength(untrustedData)))
	untrustedRoots := NewCertPool()
	untrustedRoots.AppendCertsFromPEM(buf)

	trustedRoots := NewCertPool()
	for _, c := range roots.certs {
		if !untrustedRoots.contains(c) {
			trustedRoots.AddCert(c)
		}
	}
	return trustedRoots, nil
}
// ExportFromKeychain ...
func ExportFromKeychain(itemRefsToExport []C.CFTypeRef, outputFilePath string, isAskForPassword bool) error {
	passphraseCString := C.CString("")
	defer C.free(unsafe.Pointer(passphraseCString))

	var exportedData C.CFDataRef
	var exportParams C.SecItemImportExportKeyParameters
	exportParams.keyUsage = nil
	exportParams.keyAttributes = nil
	exportParams.version = C.SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION
	if isAskForPassword {
		exportParams.flags = C.kSecKeySecurePassphrase
		exportParams.passphrase = nil
		exportParams.alertTitle = nil

		promptText := C.CString("Enter a password which will be used to protect the exported items")
		defer C.free(unsafe.Pointer(promptText))
		exportParams.alertPrompt = convertCStringToCFString(promptText)
	} else {
		exportParams.flags = 0
		exportParams.passphrase = (C.CFTypeRef)(convertCStringToCFString(passphraseCString))
		exportParams.alertTitle = nil
		exportParams.alertPrompt = nil
	}

	// create a C array from the input
	ptr := (*unsafe.Pointer)(&itemRefsToExport[0])
	cfArrayForExport := C.CFArrayCreate(
		C.kCFAllocatorDefault,
		ptr,
		C.CFIndex(len(itemRefsToExport)),
		&C.kCFTypeArrayCallBacks)

	// do the export!
	status := C.SecItemExport(C.CFTypeRef(cfArrayForExport),
		C.kSecFormatPKCS12,
		0, //C.kSecItemPemArmour, // Use kSecItemPemArmour to add PEM armour - the .p12 generated by Keychain Access.app does NOT have PEM armour
		&exportParams,
		&exportedData)

	if status != C.errSecSuccess {
		return fmt.Errorf("SecItemExport: error (OSStatus): %d", status)
	}
	// exportedData now contains your PKCS12 data
	//  make sure it'll be released properly!
	defer C.CFRelease(C.CFTypeRef(exportedData))

	dataBytes := convertCFDataRefToGoBytes(exportedData)
	if dataBytes == nil || len(dataBytes) < 1 {
		return errors.New("ExportFromKeychain: failed to convert export data - nil or empty")
	}

	if err := fileutil.WriteBytesToFile(outputFilePath, dataBytes); err != nil {
		return fmt.Errorf("ExportFromKeychain: failed to write into file: %s", err)
	}

	log.Debug("Export - success")

	return nil
}
Beispiel #5
0
// ===== CFBoolean =====
func convertBoolToCFBoolean(b bool) C.CFBooleanRef {
	// I don't think the CFBoolean constants have retain counts,
	// but just in case lets call CFRetain on them
	if b {
		return C.CFBooleanRef(C.CFRetain(C.CFTypeRef(C.kCFBooleanTrue)))
	}
	return C.CFBooleanRef(C.CFRetain(C.CFTypeRef(C.kCFBooleanFalse)))
}
Beispiel #6
0
// GetAllAccountNames returns a list of all account names for the
// given service name in the default keychain.
func GetAllAccountNames(serviceName string) (accountNames []string, err error) {
	var serviceNameString C.CFStringRef
	if serviceNameString, err = _UTF8StringToCFString(serviceName); err != nil {
		return
	}
	defer C.CFRelease(C.CFTypeRef(serviceNameString))

	query := map[C.CFTypeRef]C.CFTypeRef{
		secClass:            secClassGenericPassword,
		secAttrService:      C.CFTypeRef(serviceNameString),
		secMatchLimit:       secMatchLimitAll,
		secReturnAttributes: C.CFTypeRef(C.kCFBooleanTrue),
	}
	queryDict := mapToCFDictionary(query)
	defer C.CFRelease(C.CFTypeRef(queryDict))

	var resultsRef C.CFTypeRef
	errCode := C.SecItemCopyMatching(queryDict, &resultsRef)
	err = newKeychainError(errCode)
	if err == ErrItemNotFound {
		return []string{}, nil
	} else if err != nil {
		return nil, err
	}

	defer C.CFRelease(resultsRef)

	// The resultsRef should always be an array (because kSecReturnAttributes is true)
	// but it's a good sanity check and useful if want to support kSecReturnRef in the future.
	typeID := C.CFGetTypeID(resultsRef)
	if typeID != C.CFArrayGetTypeID() {
		typeDesc := C.CFCopyTypeIDDescription(typeID)
		defer C.CFRelease(C.CFTypeRef(typeDesc))
		err = fmt.Errorf("Invalid result type: %s", _CFStringToUTF8String(typeDesc))
		return
	}

	results := _CFArrayToArray(C.CFArrayRef(resultsRef))
	for _, result := range results {
		m := _CFDictionaryToMap(C.CFDictionaryRef(result))
		resultServiceName := _CFStringToUTF8String(C.CFStringRef(m[secAttrService]))
		if resultServiceName != serviceName {
			err = fmt.Errorf("Expected service name %s, got %s", serviceName, resultServiceName)
			return
		}
		accountName := _CFStringToUTF8String(C.CFStringRef(m[secAttrAccount]))
		accountNames = append(accountNames, accountName)
	}
	return
}
Beispiel #7
0
// UpdateItem updates the queryItem with the parameters from updateItem
func UpdateItem(queryItem Item, updateItem Item) error {
	cfDict, err := ConvertMapToCFDictionary(queryItem.attr)
	if err != nil {
		return err
	}
	defer Release(C.CFTypeRef(cfDict))
	cfDictUpdate, err := ConvertMapToCFDictionary(updateItem.attr)
	if err != nil {
		return err
	}
	defer Release(C.CFTypeRef(cfDictUpdate))
	errCode := C.SecItemUpdate(cfDict, cfDictUpdate)
	err = checkError(errCode)
	return err
}
Beispiel #8
0
func NewCFError(c C.CFErrorRef) *CFError {
	e := &CFError{
		Domain: convertCFStringToString(C.CFErrorGetDomain(c)),
		Code:   int(C.CFErrorGetCode(c)),
	}
	cfDict := C.CFErrorCopyUserInfo(c)
	defer C.CFRelease(C.CFTypeRef(cfDict))
	if userInfo, err := convertCFDictionaryToMap(cfDict); err == nil {
		// on error, skip user info
		e.UserInfo = userInfo
	}
	cfStr := C.CFErrorCopyDescription(c)
	defer C.CFRelease(C.CFTypeRef(cfStr))
	e.Description = convertCFStringToString(cfStr)
	return e
}
Beispiel #9
0
func (w *Watcher) watchPath(path string, options *Options) error {
	path, _ = filepath.Abs(path)

	w.wmut.Lock()
	_, found := w.watches[path]
	w.wmut.Unlock()

	if !found {
		cPaths := C.ArrayCreateMutable(C.int(1))
		defer C.CFRelease(C.CFTypeRef(cPaths))

		cpath := C.CString(path)
		defer C.free(unsafe.Pointer(cpath))

		str := C.CFStringCreateWithCString(nil, cpath, C.kCFStringEncodingUTF8)
		C.CFArrayAppendValue(cPaths, unsafe.Pointer(str))

		context := C.FSEventStreamContext{info: unsafe.Pointer(&w.internalEvent)}
		latency := C.CFTimeInterval(0)
		if options != nil && options.Throttle {
			latency = C.CFTimeInterval(options.ThrottleDuration / time.Second)
		}
		stream := C.EventStreamCreate(&context, cPaths, C.kFSEventStreamEventIdSinceNow+(1<<64), latency)
		w.wmut.Lock()
		w.watches[path] = stream
		w.wmut.Unlock()
		C.FSEventStreamScheduleWithRunLoop(stream, w.rlref, C.kCFRunLoopDefaultMode)
		C.FSEventStreamStart(stream)
	}

	return nil
}
Beispiel #10
0
// The returned SecAccessRef, if non-nil, must be released via CFRelease.
func createEmptyAccess(label string) (C.SecAccessRef, error) {
	var err error
	var labelRef C.CFStringRef
	if labelRef, err = _UTF8StringToCFString(label); err != nil {
		return nil, err
	}
	defer C.CFRelease(C.CFTypeRef(labelRef))

	var access C.SecAccessRef
	trustedApplicationsArray := arrayToCFArray([]C.CFTypeRef{})
	defer C.CFRelease(C.CFTypeRef(trustedApplicationsArray))

	if err = newKeychainError(C.SecAccessCreate(labelRef, trustedApplicationsArray, &access)); err != nil {
		return nil, err
	}

	return access, nil
}
Beispiel #11
0
// DeleteItem removes a Item
func DeleteItem(item Item) error {
	cfDict, err := convertAttr(item.attr)
	if err != nil {
		return err
	}
	defer C.CFRelease(C.CFTypeRef(cfDict))

	errCode := C.SecItemDelete(cfDict)
	return checkError(errCode)
}
Beispiel #12
0
// DeleteItem removes a Item
func DeleteItem(item Item) error {
	cfDict, err := ConvertMapToCFDictionary(item.attr)
	if err != nil {
		return err
	}
	defer Release(C.CFTypeRef(cfDict))

	errCode := C.SecItemDelete(cfDict)
	return checkError(errCode)
}
Beispiel #13
0
func (self *Clipboard) addImage(img image.Image) (err error) {
	var i C.CGImageRef

	if i, err = CGImageCreateWithImage(img); err == nil {
		C.Clipboard_AddImage(self.ref, i)
		C.CFRelease(C.CFTypeRef(i))
	}

	return
}
Beispiel #14
0
// AddItem adds a Item
func AddItem(item Item) error {
	cfDict, err := convertAttr(item.attr)
	if err != nil {
		return err
	}
	defer C.CFRelease(C.CFTypeRef(cfDict))

	errCode := C.SecItemAdd(cfDict, nil)
	err = checkError(errCode)
	return err
}
Beispiel #15
0
// FindAndRemoveGenericPassword finds a generic password with the
// given attributes in the default keychain and removes it if
// found. If not found, an error is returned.
func FindAndRemoveGenericPassword(attributes *GenericPasswordAttributes) error {
	itemRef, err := findGenericPasswordItem(attributes)
	if err != nil {
		return err
	}

	defer C.CFRelease(C.CFTypeRef(itemRef))

	errCode := C.SecKeychainItemDelete(itemRef)
	return newKeychainError(errCode)
}
Beispiel #16
0
// Attributes provides metadata about the voice.
// The attributes for a voice are described in the documentation for [NSSpeechSynthesizer attributesForVoice].
// This functionality is undocumented in the Carbon Speech Synthesis Manager.
func (vs VoiceSpec) Attributes() (VoiceAttributes, error) {
	var va VoiceAttributes
	oserr := C.GetVoiceInfo((*C.VoiceSpec)(&vs), C.soVoiceAttributes, unsafe.Pointer(&va.cfd))
	if oserr != 0 {
		return va, osError(oserr)
	}
	runtime.SetFinalizer(&va, func(va *VoiceAttributes) {
		C.CFRelease(C.CFTypeRef(va.cfd))
	})
	return va, nil
}
Beispiel #17
0
func (ke keychainError) Error() string {
	errorMessageCFString := C.SecCopyErrorMessageString(C.OSStatus(ke), nil)
	defer C.CFRelease(C.CFTypeRef(errorMessageCFString))

	errorMessageCString := C.CFStringGetCStringPtr(errorMessageCFString, C.kCFStringEncodingASCII)

	if errorMessageCString != nil {
		return C.GoString(errorMessageCString)
	}

	return fmt.Sprintf("keychainError with unknown error code %d", C.OSStatus(ke))
}
Beispiel #18
0
func iterateDevices(action func(device C.IOHIDDeviceRef) bool) cleanupDeviceManagerFn {
	mgr := C.IOHIDManagerCreate(C.kCFAllocatorDefault, C.kIOHIDOptionsTypeNone)
	C.IOHIDManagerSetDeviceMatching(mgr, nil)
	C.IOHIDManagerOpen(mgr, C.kIOHIDOptionsTypeNone)

	allDevicesSet := C.IOHIDManagerCopyDevices(mgr)
	defer C.CFRelease(C.CFTypeRef(allDevicesSet))
	devCnt := C.CFSetGetCount(allDevicesSet)
	allDevices := make([]unsafe.Pointer, uint64(devCnt))
	C.CFSetGetValues(allDevicesSet, &allDevices[0])

	for _, pDev := range allDevices {
		if !action(C.IOHIDDeviceRef(pDev)) {
			break
		}
	}
	return func() {
		C.IOHIDManagerClose(mgr, C.kIOHIDOptionsTypeNone)
		C.CFRelease(C.CFTypeRef(mgr))
	}
}
Beispiel #19
0
// https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/Reference/reference.html#jumpTo_8
func (s Stream) Paths() []string {
	cpaths := C.FSEventStreamCopyPathsBeingWatched(s.cstream)
	defer C.CFRelease(C.CFTypeRef(cpaths))
	count := C.CFArrayGetCount(cpaths)
	paths := make([]string, count)
	var i C.CFIndex
	for ; i < count; i++ {
		cpath := C.CFStringRef(C.CFArrayGetValueAtIndex(cpaths, i))
		paths[i] = fromCFString(cpath)
	}
	return paths
}
Beispiel #20
0
// AddGenericPassword adds a generic password with the given
// attributes to the default keychain.
func AddGenericPassword(attributes *GenericPasswordAttributes) (err error) {
	if err = attributes.CheckValidity(); err != nil {
		return
	}

	var serviceNameString C.CFStringRef
	if serviceNameString, err = _UTF8StringToCFString(attributes.ServiceName); err != nil {
		return
	}
	defer C.CFRelease(C.CFTypeRef(serviceNameString))

	var accountNameString C.CFStringRef
	if accountNameString, err = _UTF8StringToCFString(attributes.AccountName); err != nil {
		return
	}
	defer C.CFRelease(C.CFTypeRef(accountNameString))

	dataBytes := bytesToCFData(attributes.Password)
	defer C.CFRelease(C.CFTypeRef(dataBytes))

	query := map[C.CFTypeRef]C.CFTypeRef{
		secClass:       secClassGenericPassword,
		secAttrService: C.CFTypeRef(serviceNameString),
		secAttrAccount: C.CFTypeRef(accountNameString),
		secValueData:   C.CFTypeRef(dataBytes),
	}

	access, err := createAccess(attributes.ServiceName, attributes.TrustedApplications)
	if err != nil {
		return
	}

	if access != nil {
		defer C.CFRelease(C.CFTypeRef(access))
		query[secAttrAccess] = C.CFTypeRef(access)
	}

	queryDict := mapToCFDictionary(query)
	defer C.CFRelease(C.CFTypeRef(queryDict))

	errCode := C.SecItemAdd(queryDict, nil)

	err = newKeychainError(errCode)
	return
}
Beispiel #21
0
func buildFont(f C.CTFontRef) []byte {
	ctags := C.CTFontCopyAvailableTables(f, C.kCTFontTableOptionExcludeSynthetic)
	tagsCount := C.CFArrayGetCount(ctags)

	var tags []uint32
	var dataRefs []C.CFDataRef
	var dataLens []uint32

	for i := C.CFIndex(0); i < tagsCount; i++ {
		tag := (C.CTFontTableTag)((uintptr)(C.CFArrayGetValueAtIndex(ctags, i)))
		dataRef := C.CTFontCopyTable(f, tag, 0) // retained
		tags = append(tags, uint32(tag))
		dataRefs = append(dataRefs, dataRef)
		dataLens = append(dataLens, uint32(C.CFDataGetLength(dataRef)))
	}

	totalLen := 0
	for _, l := range dataLens {
		totalLen += int(l)
	}

	// Big-endian output.
	buf := make([]byte, 0, 12+16*len(tags)+totalLen)
	write16 := func(x uint16) { buf = append(buf, byte(x>>8), byte(x)) }
	write32 := func(x uint32) { buf = append(buf, byte(x>>24), byte(x>>16), byte(x>>8), byte(x)) }

	// File format description: http://www.microsoft.com/typography/otspec/otff.htm
	write32(0x00010000)        // version 1.0
	write16(uint16(len(tags))) // numTables
	write16(0)                 // searchRange
	write16(0)                 // entrySelector
	write16(0)                 // rangeShift

	// Table tags, includes offsets into following data segments.
	offset := uint32(12 + 16*len(tags)) // offset starts after table tags
	for i, tag := range tags {
		write32(tag)
		write32(0)
		write32(offset)
		write32(dataLens[i])
		offset += dataLens[i]
	}

	// Data segments.
	for i, dataRef := range dataRefs {
		data := (*[1<<31 - 2]byte)((unsafe.Pointer)(C.CFDataGetBytePtr(dataRef)))[:dataLens[i]]
		buf = append(buf, data...)
		C.CFRelease(C.CFTypeRef(dataRef))
	}

	return buf
}
Beispiel #22
0
func initDefaultRoots() {
	roots := x509.NewCertPool()

	var data C.CFDataRef = nil
	err := C.FetchPEMRoots(&data)
	if err != -1 {
		defer C.CFRelease(C.CFTypeRef(data))
		buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
		roots.AppendCertsFromPEM(buf)
	}

	varDefaultRoots = roots
}
Beispiel #23
0
func Unload(kextID string) error {
	cfKextID, err := StringToCFString(kextID)
	if cfKextID != nil {
		defer Release(C.CFTypeRef(cfKextID))
	}
	if err != nil {
		return err
	}
	ret := C.KextManagerUnloadKextWithIdentifier(cfKextID)
	if ret != 0 {
		return fmt.Errorf("Error unloading kext (%d)", ret)
	}
	return nil
}
Beispiel #24
0
// Start listening to an event stream.
func (es *EventStream) Start() {
	cPaths := C.ArrayCreateMutable(C.int(len(es.Paths)))
	defer C.CFRelease(C.CFTypeRef(cPaths))

	for _, p := range es.Paths {
		p, _ = filepath.Abs(p)
		cpath := C.CString(p)
		defer C.free(unsafe.Pointer(cpath))

		str := C.CFStringCreateWithCString(nil, cpath, C.kCFStringEncodingUTF8)
		C.CFArrayAppendValue(cPaths, unsafe.Pointer(str))
	}

	since := C.FSEventStreamEventId(EventIDSinceNow)
	if es.Resume {
		since = C.FSEventStreamEventId(es.EventID)
	}

	if es.Events == nil {
		es.Events = make(chan []Event)
	}

	es.registryID = registry.Add(es)
	context := C.FSEventStreamContext{}
	info := C.uintptr_t(es.registryID)
	latency := C.CFTimeInterval(float64(es.Latency) / float64(time.Second))
	if es.Device != 0 {
		es.stream = C.EventStreamCreateRelativeToDevice(&context, info, C.dev_t(es.Device), cPaths, since, latency, C.FSEventStreamCreateFlags(es.Flags))
	} else {
		es.stream = C.EventStreamCreate(&context, info, cPaths, since, latency, C.FSEventStreamCreateFlags(es.Flags))
	}

	started := make(chan struct{})

	go func() {
		runtime.LockOSThread()
		es.rlref = C.CFRunLoopGetCurrent()
		C.FSEventStreamScheduleWithRunLoop(es.stream, es.rlref, C.kCFRunLoopDefaultMode)
		C.FSEventStreamStart(es.stream)
		close(started)
		C.CFRunLoopRun()
	}()

	if !es.hasFinalizer {
		runtime.SetFinalizer(es, finalizer)
		es.hasFinalizer = true
	}

	<-started
}
Beispiel #25
0
func (dev *osxDevice) Close() {
	if !dev.disconnected {
		C.IOHIDDeviceClose(dev.osDevice, C.kIOHIDOptionsTypeSeizeDevice)
		dev.disconnected = true
	}
	if dev.osDevice != nil {
		C.CFRelease(C.CFTypeRef(dev.osDevice))
		dev.osDevice = nil
	}
	if dev.closeDM != nil {
		dev.closeDM()
		dev.closeDM = nil
	}
}
func initSystemRoots() {
	roots := NewCertPool()

	var data C.CFDataRef = nil
	err := C.ZToolsFetchPEMRoots(&data)
	if err == -1 {
		return
	}

	defer C.CFRelease(C.CFTypeRef(data))
	buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
	roots.AppendCertsFromPEM(buf)
	systemRoots = roots
}
Beispiel #27
0
// The returned SecAccessRef, if non-nil, must be released via CFRelease.
func createAccess(label string, trustedApplications []string) (C.CFTypeRef, error) {
	if len(trustedApplications) == 0 {
		return nil, nil
	}

	// Always prepend with empty string which signifies that we
	// include a NULL application, which means ourselves.
	trustedApplications = append([]string{""}, trustedApplications...)

	var err error
	var labelRef C.CFStringRef
	if labelRef, err = StringToCFString(label); err != nil {
		return nil, err
	}
	defer C.CFRelease(C.CFTypeRef(labelRef))

	var trustedApplicationsRefs []C.CFTypeRef
	for _, trustedApplication := range trustedApplications {
		trustedApplicationRef, err := createTrustedApplication(trustedApplication)
		if err != nil {
			return nil, err
		}
		defer C.CFRelease(C.CFTypeRef(trustedApplicationRef))
		trustedApplicationsRefs = append(trustedApplicationsRefs, trustedApplicationRef)
	}

	var access C.SecAccessRef
	trustedApplicationsArray := ArrayToCFArray(trustedApplicationsRefs)
	defer C.CFRelease(C.CFTypeRef(trustedApplicationsArray))
	errCode := C.SecAccessCreate(labelRef, trustedApplicationsArray, &access)
	err = checkError(errCode)
	if err != nil {
		return nil, err
	}

	return C.CFTypeRef(access), nil
}
Beispiel #28
0
func Load(kextID string, paths []string) error {
	cfKextID, err := StringToCFString(kextID)
	if cfKextID != nil {
		defer Release(C.CFTypeRef(cfKextID))
	}
	if err != nil {
		return err
	}

	var urls []C.CFTypeRef
	for _, p := range paths {
		cfPath, err := StringToCFString(p)
		if cfPath != nil {
			defer Release(C.CFTypeRef(cfPath))
		}
		if err != nil {
			return err
		}
		cfURL := C.CFURLCreateWithFileSystemPath(nil, cfPath, 0, 1)
		if cfURL != nil {
			defer Release(C.CFTypeRef(cfURL))
		}

		urls = append(urls, C.CFTypeRef(cfURL))
	}

	cfURLs := ArrayToCFArray(urls)
	if cfURLs != nil {
		defer Release(C.CFTypeRef(cfURLs))
	}

	ret := C.KextManagerLoadKextWithIdentifier(cfKextID, cfURLs)
	if ret != 0 {
		return fmt.Errorf("Error loading kext(%d)", ret)
	}
	return nil
}
Beispiel #29
0
// QueryItem returns a list of query results.
func QueryItem(item Item) ([]QueryResult, error) {
	cfDict, err := ConvertMapToCFDictionary(item.attr)
	if err != nil {
		return nil, err
	}
	defer Release(C.CFTypeRef(cfDict))

	var resultsRef C.CFTypeRef
	errCode := C.SecItemCopyMatching(cfDict, &resultsRef)
	if Error(errCode) == ErrorItemNotFound {
		return nil, nil
	}
	err = checkError(errCode)
	if err != nil {
		return nil, err
	}
	defer Release(resultsRef)

	results := make([]QueryResult, 0, 1)

	typeID := C.CFGetTypeID(resultsRef)
	if typeID == C.CFArrayGetTypeID() {
		arr := CFArrayToArray(C.CFArrayRef(resultsRef))
		for _, dictRef := range arr {
			item, err := convertResult(C.CFDictionaryRef(dictRef))
			if err != nil {
				return nil, err
			}
			results = append(results, *item)
		}
	} else if typeID == C.CFDictionaryGetTypeID() {
		item, err := convertResult(C.CFDictionaryRef(resultsRef))
		if err != nil {
			return nil, err
		}
		results = append(results, *item)
	} else if typeID == C.CFDataGetTypeID() {
		b, err := CFDataToBytes(C.CFDataRef(resultsRef))
		if err != nil {
			return nil, err
		}
		item := QueryResult{Data: b}
		results = append(results, item)
	} else {
		return nil, fmt.Errorf("Invalid result type: %s", CFTypeDescription(resultsRef))
	}

	return results, nil
}
Beispiel #30
0
// ConvertMapToCFDictionary converts a map to a CFDictionary and if non-nil,
// must be released with Release(ref).
func ConvertMapToCFDictionary(attr map[string]interface{}) (C.CFDictionaryRef, error) {
	m := make(map[C.CFTypeRef]C.CFTypeRef)
	for key, i := range attr {
		var valueRef C.CFTypeRef
		switch val := i.(type) {
		default:
			return nil, fmt.Errorf("Unsupported value type: %v", reflect.TypeOf(i))
		case C.CFTypeRef:
			valueRef = val
		case bool:
			if val {
				valueRef = C.CFTypeRef(C.kCFBooleanTrue)
			} else {
				valueRef = C.CFTypeRef(C.kCFBooleanFalse)
			}
		case []byte:
			bytesRef, err := BytesToCFData(val)
			if err != nil {
				return nil, err
			}
			valueRef = C.CFTypeRef(bytesRef)
			defer Release(valueRef)
		case string:
			stringRef, err := StringToCFString(val)
			if err != nil {
				return nil, err
			}
			valueRef = C.CFTypeRef(stringRef)
			defer Release(valueRef)
		case Convertable:
			convertedRef, err := val.Convert()
			if err != nil {
				return nil, err
			}
			valueRef = C.CFTypeRef(convertedRef)
			defer Release(valueRef)
		}
		keyRef, err := StringToCFString(key)
		if err != nil {
			return nil, err
		}
		m[C.CFTypeRef(keyRef)] = valueRef
		defer Release(C.CFTypeRef(keyRef))
	}

	cfDict, err := MapToCFDictionary(m)
	if err != nil {
		return nil, err
	}
	return cfDict, nil
}