]> git.saurik.com Git - apple/configd.git/blobdiff - Plugins/IPMonitor/dns-configuration.c
configd-1109.101.1.tar.gz
[apple/configd.git] / Plugins / IPMonitor / dns-configuration.c
index b958f11b3376b87b77306b7f3109c6f6e3a1a72b..910d8e49afd75bdf1a8206092b55ddda6784089d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 #include <resolv.h>
-#if    !TARGET_OS_IPHONE
-#include <notify.h>
-extern uint32_t notify_monitor_file(int token, const char *name, int flags);
-#endif // !TARGET_OS_IPHONE
 #include <CommonCrypto/CommonDigest.h>
 
 #include <CoreFoundation/CoreFoundation.h>
@@ -67,6 +63,12 @@ extern uint32_t notify_monitor_file(int token, const char *name, int flags);
 #include <dns_sd.h>
 #include <dns_sd_private.h>
 
+#if    !TARGET_OS_IPHONE
+#include <CoreServices/CoreServices.h>
+#else  // TARGET_OS_IPHONE
+#include <FSEvents/FSEvents.h>
+#endif // TARGET_OS_IPHONE
+
 #define DNS_CONFIGURATION_FLAGS_KEY    CFSTR("__FLAGS__")
 #define DNS_CONFIGURATION_IF_INDEX_KEY CFSTR("__IF_INDEX__")
 #define DNS_CONFIGURATION_ORDER_KEY    CFSTR("__ORDER__")
@@ -97,13 +99,13 @@ dns_resolver_flags_service(CFDictionaryRef service, uint32_t resolver_flags)
 
        // check if the service has v4 configured
        if (((resolver_flags & DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS) == 0) &&
-           service_contains_protocol(service, AF_INET)) {
+           service_is_routable(service, AF_INET)) {
                resolver_flags |= DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS;
        }
 
        // check if the service has v6 configured
        if (((resolver_flags & DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS) == 0) &&
-           service_contains_protocol(service, AF_INET6)) {
+           service_is_routable(service, AF_INET6)) {
                resolver_flags |= DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS;
        }
 
@@ -1321,7 +1323,7 @@ create_resolver(CFDictionaryRef dns)
                                *slash = '\0';
                        }
 
-                       bzero(&sortaddr, sizeof(sortaddr));
+                       memset(&sortaddr, 0, sizeof(sortaddr));
                        if (inet_aton(buf, &sortaddr.address) != 1) {
                                /* if address not valid */
                                continue;
@@ -1554,7 +1556,8 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
                      CFDictionaryRef   services,
                      CFArrayRef        serviceOrder,
                      CFArrayRef        multicastResolvers,
-                     CFArrayRef        privateResolvers)
+                     CFArrayRef        privateResolvers,
+                     CFDictionaryRef   *globalResolver)
 {
        dns_create_config_t     dns_create_config;
        Boolean                 changed                 = FALSE;
@@ -1564,8 +1567,8 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
        CFArrayRef              mySearchDomains         = NULL;
        CFIndex                 n_resolvers;
        CFMutableArrayRef       resolvers;
-       unsigned char           signature[CC_SHA1_DIGEST_LENGTH];
-       static unsigned char    signature_last[CC_SHA1_DIGEST_LENGTH];
+       unsigned char           signature[CC_SHA256_DIGEST_LENGTH];
+       static unsigned char    signature_last[CC_SHA256_DIGEST_LENGTH];
 
        // establish list of resolvers
 
@@ -1691,6 +1694,10 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
                                resolver = new_resolver;
                        }
 
+                       if (i == 0) {
+                               *globalResolver = CFRetain(resolver);
+                       }
+
                        _resolver = create_resolver(resolver);
                        _dns_configuration_add_resolver(&dns_create_config, _resolver);
                        _dns_resolver_free(&_resolver);
@@ -1700,19 +1707,17 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
                        }
                }
 
-#if    !TARGET_OS_IPHONE
                // add flatfile resolvers
 
                _dnsinfo_flatfile_set_flags(default_resolver_flags);
                _dnsinfo_flatfile_add_resolvers(&dns_create_config);
-#endif // !TARGET_OS_IPHONE
        }
 
        // check if the configuration changed
        _dns_configuration_signature(&dns_create_config, signature, sizeof(signature));
        if (bcmp(signature, signature_last, sizeof(signature)) != 0) {
                // save [new] signature
-               bcopy(signature, signature_last, sizeof(signature));
+               memcpy(signature_last, signature, sizeof(signature));
 
                my_log(LOG_INFO, "Updating DNS configuration");
                if (dns_create_config != NULL) {
@@ -1757,35 +1762,35 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
 }
 
 
-#if    !TARGET_OS_IPHONE
 static SCDynamicStoreRef       dns_configuration_store;
 static SCDynamicStoreCallBack  dns_configuration_callout;
 
 static void
-dns_configuration_changed(CFMachPortRef port, void *msg, CFIndex size, void *info)
+dns_configuration_changed(ConstFSEventStreamRef                streamRef,
+                         void                          *clientCallBackInfo,
+                         size_t                        numEvents,
+                         void                          *eventPaths,
+                         const FSEventStreamEventFlags *eventFlags,
+                         const FSEventStreamEventId    *eventIds)
 {
-#pragma unused(port)
-#pragma unused(msg)
-#pragma unused(size)
-#pragma unused(info)
-       os_activity_t                   activity;
+#pragma unused(streamRef)
+#pragma unused(clientCallBackInfo)
+#pragma unused(numEvents)
+#pragma unused(eventPaths)
+#pragma unused(eventFlags)
+#pragma unused(eventIds)
        static const CFStringRef        key     = CFSTR(_PATH_RESOLVER_DIR);
        CFArrayRef                      keys;
        Boolean                         resolvers_now;
        static Boolean                  resolvers_save  = FALSE;
        struct stat                     statbuf;
 
-       activity = os_activity_create("processing DNS configuration change",
-                                     OS_ACTIVITY_CURRENT,
-                                     OS_ACTIVITY_FLAG_DEFAULT);
-       os_activity_scope(activity);
-
        resolvers_now = (stat(_PATH_RESOLVER_DIR, &statbuf) == 0);
        if (!resolvers_save && (resolvers_save == resolvers_now)) {
                // if we did not (and still do not) have an "/etc/resolvers"
                // directory than this notification is the result of a change
                // to the "/etc" directory.
-               goto done;
+               return;
        }
        resolvers_save = resolvers_now;
 
@@ -1796,11 +1801,34 @@ dns_configuration_changed(CFMachPortRef port, void *msg, CFIndex size, void *inf
        (*dns_configuration_callout)(dns_configuration_store, keys, NULL);
        CFRelease(keys);
 
-    done :
+       return;
+}
 
-       os_release(activity);
 
-       return;
+static Boolean
+normalize_path(const char *file_name, char resolved_name[PATH_MAX])
+{
+       char    *ch;
+       char    path[PATH_MAX];
+
+       strlcpy(path, file_name, sizeof(path));
+       if (realpath(path, resolved_name) != NULL) {
+               // if the path exists
+               return TRUE;
+       }
+
+       ch = strrchr(path, '/');
+       if (ch != NULL) {
+               *ch = '\0';
+               if (realpath(path, resolved_name) != NULL) {
+                       // if a parent path exists
+                       strlcat(resolved_name, "/", PATH_MAX);
+                       strlcat(resolved_name, ch+1, PATH_MAX);
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
 }
 
 
@@ -1808,47 +1836,47 @@ __private_extern__
 void
 dns_configuration_monitor(SCDynamicStoreRef store, SCDynamicStoreCallBack callout)
 {
-       CFMachPortRef           mp;
-       mach_port_t             notify_port;
-       int                     notify_token;
-       CFRunLoopSourceRef      rls;
-       uint32_t                status;
+       FSEventStreamContext            context = { 0,          // version
+                                                   NULL,       // info
+                                                   NULL,       // retain
+                                                   NULL,       // release
+                                                   NULL };     // copyDescription
+       FSEventStreamCreateFlags        flags   = kFSEventStreamCreateFlagUseCFTypes
+                                                 | kFSEventStreamCreateFlagFileEvents
+                                                 | kFSEventStreamCreateFlagWatchRoot;
+       FSEventStreamRef                monitor;
+       CFStringRef                     path;
+       CFMutableArrayRef               paths;
+       char                            resolver_directory_path[PATH_MAX];
+
+       if (!normalize_path(_PATH_RESOLVER_DIR, resolver_directory_path)) {
+               my_log(LOG_ERR, "Not monitoring \"%s\", could not resolve directory path", _PATH_RESOLVER_DIR);
+               return;
+       }
 
        dns_configuration_store   = store;
        dns_configuration_callout = callout;
 
-       status = notify_register_mach_port(_PATH_RESOLVER_DIR, &notify_port, 0, &notify_token);
-       if (status != NOTIFY_STATUS_OK) {
-               my_log(LOG_ERR, "notify_register_mach_port() failed");
-               return;
-       }
+       paths = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       path = CFStringCreateWithCString(NULL, resolver_directory_path, kCFStringEncodingUTF8);
+       CFArrayAppendValue(paths, path);
+       CFRelease(path);
 
-       status = notify_monitor_file(notify_token, "/private" _PATH_RESOLVER_DIR, 0);
-       if (status != NOTIFY_STATUS_OK) {
-               my_log(LOG_ERR, "notify_monitor_file() failed");
-               (void)notify_cancel(notify_token);
-               return;
-       }
+       monitor = FSEventStreamCreate(NULL,                             // allocator
+                                     dns_configuration_changed,        // callback
+                                     &context,                         // context
+                                     paths,                            // pathsToWatch (CFArray)
+                                     kFSEventStreamEventIdSinceNow,    // sinceWhen
+                                     0.0,                              // latency
+                                     flags);                           // flags
 
-       mp = _SC_CFMachPortCreateWithPort("IPMonitor/dns_configuration",
-                                         notify_port,
-                                         dns_configuration_changed,
-                                         NULL);
+       CFRelease(paths);
 
-       rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
-       if (rls == NULL) {
-               my_log(LOG_ERR, "SCDynamicStoreCreateRunLoopSource() failed");
-               CFRelease(mp);
-               (void)notify_cancel(notify_token);
-               return;
-       }
-       CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
-       CFRelease(rls);
+       FSEventStreamScheduleWithRunLoop(monitor, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+       FSEventStreamStart(monitor);
 
-       CFRelease(mp);
        return;
 }
-#endif // !TARGET_OS_IPHONE
 
 
 __private_extern__
@@ -1966,6 +1994,7 @@ int
 main(int argc, char **argv)
 {
        CFDictionaryRef         entities;
+       CFDictionaryRef         globalResolver  = NULL;
        CFStringRef             key;
        CFArrayRef              multicast_resolvers;
        CFStringRef             pattern;
@@ -1980,7 +2009,7 @@ main(int argc, char **argv)
        SCDynamicStoreRef       store;
 
        _sc_debug   = TRUE;
-       _sc_log     = FALSE;
+       _sc_log     = kSCLogDestinationFile;
        _sc_verbose = (argc > 1) ? TRUE : FALSE;
 
        store = SCDynamicStoreCreate(NULL, CFSTR("TEST"), NULL, NULL);
@@ -2066,13 +2095,15 @@ main(int argc, char **argv)
                                    service_state_dict,
                                    service_order,
                                    multicast_resolvers,
-                                   private_resolvers);
+                                   private_resolvers,
+                                   &globalResolver);
 
        // cleanup
        if (setup_global_ipv4 != NULL)  CFRelease(setup_global_ipv4);
        if (state_global_ipv4 != NULL)  CFRelease(state_global_ipv4);
        if (multicast_resolvers != NULL) CFRelease(multicast_resolvers);
        if (private_resolvers != NULL)  CFRelease(private_resolvers);
+       if (globalResolver != NULL)     CFRelease(globalResolver);
        CFRelease(service_state_dict);
        CFRelease(store);