Status parseApplicationAliasData(const std::string& data, std::string& result) { std::string decoded_data = base64Decode(data); if (decoded_data.empty()) { return Status(1, "Failed to base64 decode data"); } CFDataRef resourceData = CFDataCreate( nullptr, static_cast<const UInt8*>(static_cast<const void*>(decoded_data.c_str())), decoded_data.length()); if (resourceData == nullptr) { return Status(1, "Failed to allocate resource data"); } auto alias = (CFDataRef)CFPropertyListCreateWithData(kCFAllocatorDefault, resourceData, kCFPropertyListImmutable, nullptr, nullptr); CFRelease(resourceData); if (alias == nullptr) { return Status(1, "Failed to allocate alias data"); } auto bookmark = CFURLCreateBookmarkDataFromAliasRecord(kCFAllocatorDefault, alias); CFRelease(alias); if (bookmark == nullptr) { return Status(1, "Alias data is not a bookmark"); } auto url = CFURLCreateByResolvingBookmarkData( kCFAllocatorDefault, bookmark, 0, nullptr, nullptr, nullptr, nullptr); CFRelease(bookmark); if (url == nullptr) { return Status(1, "Alias data is not a URL bookmark"); } auto replaced = CFURLCreateStringByReplacingPercentEscapes( kCFAllocatorDefault, CFURLGetString(url), CFSTR("")); CFRelease(url); if (replaced == nullptr) { return Status(1, "Failed to replace percent escapes."); } // Get the URL-formatted path. result = stringFromCFString(replaced); CFRelease(replaced); if (result.empty()) { return Status(1, "Return result is zero size"); } if (result.length() > 6 && result.substr(0, 7) == "file://") { result = result.substr(7); } return Status(0, "OK"); }
SecurityTokenPointer Sandbox::openTokenFromBookmark(const QString& canonicalPath, const QString& bookmarkBase64) { #ifdef Q_OS_MAC #if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 QByteArray bookmarkBA = QByteArray::fromBase64(bookmarkBase64.toLatin1()); if (!bookmarkBA.isEmpty()) { CFDataRef bookmarkData = CFDataCreate( kCFAllocatorDefault, reinterpret_cast<const UInt8*>(bookmarkBA.constData()), bookmarkBA.length()); Boolean stale; CFErrorRef error = NULL; CFURLRef url = CFURLCreateByResolvingBookmarkData( kCFAllocatorDefault, bookmarkData, kCFURLBookmarkResolutionWithSecurityScope, NULL, NULL, &stale, &error); if (error != NULL) { if (sDebug) { qDebug() << "Error creating URL from bookmark data:" << CFStringToQString(CFErrorCopyDescription(error)); } } CFRelease(bookmarkData); if (url != NULL) { if (!CFURLStartAccessingSecurityScopedResource(url)) { if (sDebug) { qDebug() << "CFURLStartAccessingSecurityScopedResource failed for" << canonicalPath; } } else { SecurityTokenPointer pToken = SecurityTokenPointer( new SandboxSecurityToken(canonicalPath, url)); s_activeTokens[canonicalPath] = pToken; return pToken; } } else { if (sDebug) { qDebug() << "Cannot resolve security-scoped bookmark for" << canonicalPath; } } } #endif #else Q_UNUSED(canonicalPath); Q_UNUSED(bookmarkBase64); #endif return SecurityTokenPointer(); }
/// Parse a Login Items Plist Alias data for bin path Status parseAliasData(const std::string& data, std::string& result) { auto decoded = base64Decode(data); if (decoded.size() == 0) { // Base64 encoded data (from plist parsing) failed to decode. return Status(1, "Failed base64 decode"); } auto alias = CFDataCreate( kCFAllocatorDefault, (const UInt8*)decoded.c_str(), decoded.size()); if (alias == nullptr) { // Failed to create CFData object. return Status(2, "CFData allocation failed"); } auto bookmark = CFURLCreateBookmarkDataFromAliasRecord(kCFAllocatorDefault, alias); if (bookmark == nullptr) { CFRelease(alias); return Status(1, "Alias data is not a bookmark"); } auto url = CFURLCreateByResolvingBookmarkData( kCFAllocatorDefault, bookmark, 0, nullptr, nullptr, nullptr, nullptr); if (url == nullptr) { CFRelease(alias); CFRelease(bookmark); return Status(1, "Alias data is not a URL bookmark"); } // Get the URL-formatted path. result = stringFromCFString(CFURLGetString(url)); if (result.substr(0, 7) == "file://") { result = result.substr(7); } CFRelease(alias); CFRelease(bookmark); CFRelease(url); return Status(0, "OK"); }
/* * Add support for resolving Mac native alias files (not the same as unix alias files) * (what are "unix alias files"?) * returns 0 on success. */ int macxp_resolveAlias(char *path, int buflen) { #if HAVE_FEATURE_MACOSX_SANDBOX /* Avoid unnecessary messages in the system.log: * * soffice(57342) deny file-read-data /Users/tml/Documents/b.odt/..namedfork/rsrc * etc. * * Just don't bother with resolving aliases. I doubt its usefulness anyway. */ (void) path; (void) buflen; return 0; #else #if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 FSRef aFSRef; OSStatus nErr; Boolean bFolder; Boolean bAliased; #else CFStringRef cfpath; CFURLRef cfurl; CFErrorRef cferror; CFDataRef cfbookmark; #endif char *unprocessedPath = path; if ( *unprocessedPath == '/' ) unprocessedPath++; int nRet = 0; while ( !nRet && unprocessedPath && *unprocessedPath ) { unprocessedPath = strchr( unprocessedPath, '/' ); if ( unprocessedPath ) *unprocessedPath = '\0'; #if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 nErr = noErr; bFolder = FALSE; bAliased = FALSE; if ( FSPathMakeRef( (const UInt8 *)path, &aFSRef, 0 ) == noErr ) { nErr = FSResolveAliasFileWithMountFlags( &aFSRef, TRUE, &bFolder, &bAliased, kResolveAliasFileNoUI ); if ( nErr == nsvErr ) { errno = ENOENT; nRet = -1; } else if ( nErr == noErr && bAliased ) { char tmpPath[ PATH_MAX ]; if ( FSRefMakePath( &aFSRef, (UInt8 *)tmpPath, PATH_MAX ) == noErr ) { int nLen = strlen( tmpPath ) + ( unprocessedPath ? strlen( unprocessedPath + 1 ) + 1 : 0 ); if ( nLen < buflen && nLen < PATH_MAX ) { if ( unprocessedPath ) { int nTmpPathLen = strlen( tmpPath ); strcat( tmpPath, "/" ); strcat( tmpPath, unprocessedPath + 1 ); strcpy( path, tmpPath); unprocessedPath = path + nTmpPathLen; } else if ( !unprocessedPath ) { strcpy( path, tmpPath); } } else { errno = ENAMETOOLONG; nRet = -1; } } } } #else cfpath = CFStringCreateWithCString( NULL, path, kCFStringEncodingUTF8 ); cfurl = CFURLCreateWithFileSystemPath( NULL, cfpath, kCFURLPOSIXPathStyle, false ); CFRelease( cfpath ); cferror = NULL; cfbookmark = CFURLCreateBookmarkDataFromFile( NULL, cfurl, &cferror ); CFRelease( cfurl ); if ( cfbookmark == NULL ) { if(cferror) { CFRelease( cferror ); } } else { Boolean isStale; cfurl = CFURLCreateByResolvingBookmarkData( NULL, cfbookmark, kCFBookmarkResolutionWithoutUIMask, NULL, NULL, &isStale, &cferror ); CFRelease( cfbookmark ); if ( cfurl == NULL ) { CFRelease( cferror ); } else { cfpath = CFURLCopyFileSystemPath( cfurl, kCFURLPOSIXPathStyle ); CFRelease( cfurl ); if ( cfpath != NULL ) { char tmpPath[ PATH_MAX ]; if ( CFStringGetCString( cfpath, tmpPath, PATH_MAX, kCFStringEncodingUTF8 ) ) { int nLen = strlen( tmpPath ) + ( unprocessedPath ? strlen( unprocessedPath + 1 ) + 1 : 0 ); if ( nLen < buflen && nLen < PATH_MAX ) { if ( unprocessedPath ) { int nTmpPathLen = strlen( tmpPath ); strcat( tmpPath, "/" ); strcat( tmpPath, unprocessedPath + 1 ); strcpy( path, tmpPath); unprocessedPath = path + nTmpPathLen; } else if ( !unprocessedPath ) { strcpy( path, tmpPath ); } } else { errno = ENAMETOOLONG; nRet = -1; } } CFRelease( cfpath ); } } } #endif if ( unprocessedPath ) *unprocessedPath++ = '/'; } return nRet; #endif }
/* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ static void nc_show(int argc, char **argv) { SCNetworkServiceRef service = NULL; SCDynamicStoreRef store = NULL; int exit_code = 1; CFStringRef serviceID = NULL; CFStringRef iftype = NULL; CFStringRef ifsubtype = NULL; CFStringRef type_entity_key = NULL; CFStringRef subtype_entity_key = NULL; CFDictionaryRef type_entity_dict = NULL; CFDictionaryRef subtype_entity_dict = NULL; CFStringRef vpnprefpath = NULL; #if !TARGET_OS_IPHONE CFDataRef bookmarkData = NULL; CFURLRef directory = NULL; Boolean isStale = FALSE; char *path = NULL; CFIndex path_len = 0; #endif service = nc_copy_service_from_arguments(argc, argv, NULL); if (service == NULL) { SCPrint(TRUE, stderr, CFSTR("No service\n")); exit(exit_code); } serviceID = SCNetworkServiceGetServiceID(service); nc_get_service_type_and_subtype(service, &iftype, &ifsubtype); if (!CFEqual(iftype, kSCEntNetPPP) && !CFEqual(iftype, kSCEntNetIPSec) && !CFEqual(iftype, kSCEntNetVPN)) { SCPrint(TRUE, stderr, CFSTR("Not a connection oriented service: %@\n"), serviceID); goto done; } type_entity_key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, serviceID, iftype); nc_print_VPN_service(service); #if !TARGET_OS_IPHONE vpnprefpath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@"), PREF_PREFIX, ifsubtype, PREF_SUFFIX); if (vpnprefpath == NULL) { goto skipURL; } path_len = CFStringGetLength(vpnprefpath) + 1; path = malloc(path_len); if (path == NULL) { goto skipURL; } if (!CFStringGetCString(vpnprefpath, path, path_len, kCFStringEncodingASCII)) { SCPrint(TRUE, stderr, CFSTR("CFStringGetCString failed\n")); goto done; } do_prefs_init(); /* initialization */ do_prefs_open(1, &path); /* open prefs */ bookmarkData = SCPreferencesGetValue(prefs, CFSTR("ApplicationURL")); if (bookmarkData == NULL) { goto skipURL; } directory = CFURLCreateByResolvingBookmarkData(kCFAllocatorDefault, bookmarkData, 0, NULL, NULL, &isStale, NULL); if (directory == NULL) { goto skipURL; } SCPrint(TRUE, stdout, CFSTR("ApplicationURL: %@\n"), directory); skipURL: #endif store = SCDynamicStoreCreate(NULL, CFSTR("scutil --nc"), NULL, NULL); if (store == NULL) { SCPrint(TRUE, stderr, CFSTR("Unable to create dynamic store: %s\n"), SCErrorString(SCError())); goto done; } type_entity_dict = SCDynamicStoreCopyValue(store, type_entity_key); if (!type_entity_dict) { SCPrint(TRUE, stderr, CFSTR("No \"%@\" configuration available\n"), iftype); } else { SCPrint(TRUE, stdout, CFSTR("%@ %@\n"), iftype, type_entity_dict); } if (ifsubtype) { subtype_entity_key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, serviceID, ifsubtype); subtype_entity_dict = SCDynamicStoreCopyValue(store, subtype_entity_key); if (!subtype_entity_dict) { // } else { SCPrint(TRUE, stdout, CFSTR("%@ %@\n"), ifsubtype, subtype_entity_dict); } } exit_code = 0; done: my_CFRelease(&type_entity_key); my_CFRelease(&type_entity_dict); my_CFRelease(&subtype_entity_key); my_CFRelease(&subtype_entity_dict); my_CFRelease(&store); my_CFRelease(&service); my_CFRelease(&vpnprefpath); _prefs_close(); exit(exit_code); }
//static QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { #if defined(__GLIBC__) && !defined(PATH_MAX) #define PATH_CHUNK_SIZE 256 char *s = 0; int len = -1; int size = PATH_CHUNK_SIZE; while (1) { s = (char *) ::realloc(s, size); Q_CHECK_PTR(s); len = ::readlink(link.nativeFilePath().constData(), s, size); if (len < 0) { ::free(s); break; } if (len < size) { break; } size *= 2; } #else char s[PATH_MAX+1]; int len = readlink(link.nativeFilePath().constData(), s, PATH_MAX); #endif if (len > 0) { QString ret; if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) fillMetaData(link, data, QFileSystemMetaData::DirectoryType); if (data.isDirectory() && s[0] != '/') { QDir parent(link.filePath()); parent.cdUp(); ret = parent.path(); if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) ret += QLatin1Char('/'); } s[len] = '\0'; ret += QFile::decodeName(QByteArray(s)); #if defined(__GLIBC__) && !defined(PATH_MAX) ::free(s); #endif if (!ret.startsWith(QLatin1Char('/'))) { if (link.filePath().startsWith(QLatin1Char('/'))) { ret.prepend(link.filePath().left(link.filePath().lastIndexOf(QLatin1Char('/'))) + QLatin1Char('/')); } else { ret.prepend(QDir::currentPath() + QLatin1Char('/')); } } ret = QDir::cleanPath(ret); if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) ret.chop(1); return QFileSystemEntry(ret); } #if defined(Q_OS_DARWIN) { QCFString path = CFStringCreateWithFileSystemRepresentation(0, QFile::encodeName(QDir::cleanPath(link.filePath())).data()); if (!path) return QFileSystemEntry(); QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, data.hasFlags(QFileSystemMetaData::DirectoryType)); if (!url) return QFileSystemEntry(); QCFType<CFDataRef> bookmarkData = CFURLCreateBookmarkDataFromFile(0, url, NULL); if (!bookmarkData) return QFileSystemEntry(); QCFType<CFURLRef> resolvedUrl = CFURLCreateByResolvingBookmarkData(0, bookmarkData, (CFURLBookmarkResolutionOptions)(kCFBookmarkResolutionWithoutUIMask | kCFBookmarkResolutionWithoutMountingMask), NULL, NULL, NULL, NULL); if (!resolvedUrl) return QFileSystemEntry(); QCFString cfstr(CFURLCopyFileSystemPath(resolvedUrl, kCFURLPOSIXPathStyle)); if (!cfstr) return QFileSystemEntry(); return QFileSystemEntry(QCFString::toQString(cfstr)); } #endif return QFileSystemEntry(); }