SCDynamicStoreCopySpecific.cpp
1 #include <unistd.h> 2 #include <sys/types.h> 3 #include <stdlib.h> 4 #include <pwd.h> 5 #include <sys/utsname.h> 6 //#include "log.h" 7 8 #include <CoreFoundation/CFString.h> 9 #include <SystemConfiguration/SCDynamicStoreCopySpecific.h> 10 #include <SystemConfiguration/SCSchemaDefinitions.h> 11 #include <vector> 12 13 #define MAX_PASSENTRY_LENGTH 4096 14 15 16 17 CFStringRef SCDynamicStoreCopyComputerName (SCDynamicStoreRef store, CFStringEncoding *nameEncoding) 18 { 19 char hostname[100]; 20 if (gethostname(hostname, sizeof(hostname)) != 0) 21 return nullptr; 22 hostname[sizeof(hostname)-1] = '\0'; 23 24 if (nameEncoding) 25 *nameEncoding = kCFStringEncodingUTF8; 26 27 return CFStringCreateWithCString(nullptr, hostname, kCFStringEncodingUTF8); 28 } 29 30 CFStringRef SCDynamicStoreCopyConsoleUser (SCDynamicStoreRef store, uid_t *uid, gid_t *gid){ 31 struct passwd pwent, *pwentp; 32 char buffer[MAX_PASSENTRY_LENGTH]; 33 char *user; 34 35 if (uid) *uid = getuid(); 36 if (gid) *gid = getgid(); 37 38 user = getenv("USER"); 39 if (user) 40 return CFStringCreateWithCString(NULL, user, kCFStringEncodingUTF8); 41 42 if (getpwuid_r(getuid(), &pwent, buffer, MAX_PASSENTRY_LENGTH, &pwentp)) 43 return CFStringCreateWithCString(NULL, pwentp->pw_name, kCFStringEncodingUTF8); 44 45 return NULL; 46 } 47 48 CFStringRef SCDynamicStoreCopyLocalHostName (SCDynamicStoreRef store){ 49 struct utsname info; 50 51 if (uname(&info) != 0) 52 return NULL; 53 54 return CFStringCreateWithCString(NULL, info.nodename, kCFStringEncodingUTF8); 55 } 56 57 CFStringRef SCDynamicStoreCopyLocation (SCDynamicStoreRef store){ 58 //LOG << "fixme: SCDynamicStoreCopyLocation() - stub" << std::endl; 59 return NULL; 60 } 61 62 static CFNumberRef cfNumber(int n) 63 { 64 return CFNumberCreate(nullptr, kCFNumberSInt32Type, &n); 65 } 66 67 static void fillProxy(std::vector<CFStringRef>& keys, std::vector<CFTypeRef>& values, 68 const char* envVarName, 69 CFStringRef enabledKey, CFStringRef hostKey, CFStringRef portKey) 70 { 71 const char* var = getenv(envVarName); 72 if (!var) 73 { 74 keys.push_back(enabledKey); 75 values.push_back(cfNumber(0)); 76 } 77 else 78 { 79 keys.push_back(enabledKey); 80 values.push_back(cfNumber(1)); 81 82 CFURLRef url = CFURLCreateWithBytes(nullptr, (const UInt8*) var, strlen(var), kCFStringEncodingUTF8, nullptr); 83 84 if (url != nullptr) 85 { 86 keys.push_back(hostKey); 87 values.push_back(CFURLCopyHostName(url)); 88 89 int port = CFURLGetPortNumber(url); 90 if (port == -1) 91 port = 80; 92 93 keys.push_back(portKey); 94 values.push_back(cfNumber(port)); 95 96 CFRelease(url); 97 } 98 } 99 } 100 101 CFDictionaryRef SCDynamicStoreCopyProxies (SCDynamicStoreRef store) 102 { 103 // NOTE: Proxy username and password are supposed to be accessed via Security.framework 104 // https://stackoverflow.com/a/15085066/479753 105 106 std::vector<CFStringRef> keys; 107 std::vector<CFTypeRef> values; 108 109 keys.push_back(kSCPropNetProxiesGopherEnable); 110 values.push_back(cfNumber(0)); 111 112 fillProxy(keys, values, "http_proxy", kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); 113 fillProxy(keys, values, "https_proxy", kSCPropNetProxiesHTTPSEnable, kSCPropNetProxiesHTTPSProxy, kSCPropNetProxiesHTTPSPort); 114 fillProxy(keys, values, "ftp_proxy", kSCPropNetProxiesFTPEnable, kSCPropNetProxiesFTPProxy, kSCPropNetProxiesFTPPort); 115 116 CFDictionaryRef rv = CFDictionaryCreate(nullptr, (const void**) keys.data(), (const void**) values.data(), keys.size(), 117 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 118 119 for (CFTypeRef cf : values) 120 CFRelease(cf); 121 return rv; 122 } 123 124 CFDictionaryRef SCDynamicStoreCopyProxiesWithOptions(SCDynamicStoreRef store, CFDictionaryRef options) 125 { 126 return SCDynamicStoreCopyProxies(store); 127 }