]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Make sure to redirect stdout/stderr to /dev/null when running certtool.
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Wed, 2 Jul 2014 15:52:01 +0000 (15:52 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Wed, 2 Jul 2014 15:52:01 +0000 (15:52 +0000)
Add IPPS support to ippserver (still need to handle upgrade).

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@11986 a1ca3aef-8c08-0410-bb20-df032aa958be

cups/tls-darwin.c
test/ippserver.c

index 07ff0ee69d1ff99d354e2e5cc4679b45ac26778a..6ae154f71e09f7216fbc5dea999f3f90204330dc 100644 (file)
@@ -64,13 +64,14 @@ static OSStatus             http_cdsa_write(SSLConnectionRef connection, const void *data,
 
 int                                    /* O - 1 on success, 0 on failure */
 cupsMakeServerCredentials(
-    const char *path,                  /* I - Path to keychain/directory */
+    const char *path,                  /* I - Keychain path or @code NULL@ for default */
     const char *common_name,           /* I - Common name */
     int        num_alt_names,          /* I - Number of subject alternate names */
     const char **alt_names,            /* I - Subject Alternate Names */
     time_t     expiration_date)                /* I - Expiration date */
 {
 #if defined(HAVE_SECGENERATESELFSIGNEDCERTIFICATE) && defined(HAVE_SECKEYCHAINOPEN)
+  char                 filename[1024]; /* Default keychain path */
   int                  status = 0;     /* Return status */
   OSStatus             err;            /* Error code (if any) */
   CFStringRef          cfcommon_name = NULL;
@@ -90,8 +91,21 @@ cupsMakeServerCredentials(
   (void)alt_names;
   (void)expiration_date;
 
-  cfcommon_name = CFStringCreateWithCString(kCFAllocatorDefault, common_name,
-                                           kCFStringEncodingUTF8);
+  if (!path)
+  {
+    const char *home = getenv("HOME"); /* HOME environment variable */
+
+    if (getuid() && home)
+      snprintf(filename, sizeof(filename), "%s/Library/Keychains/login.keychain", home);
+    else
+      strlcpy(filename, "/Library/Keychains/System.keychain", sizeof(filename));
+
+    path = filename;
+
+    DEBUG_printf(("1cupsMakeServerCredentials: Using default path \"%s\".", path));
+  }
+
+  cfcommon_name = CFStringCreateWithCString(kCFAllocatorDefault, common_name, kCFStringEncodingUTF8);
   if (!cfcommon_name)
     goto cleanup;
 
@@ -99,16 +113,13 @@ cupsMakeServerCredentials(
   * Create a public/private key pair...
   */
 
-  keyParams = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
-                                       &kCFTypeDictionaryKeyCallBacks,
-                                       &kCFTypeDictionaryValueCallBacks);
+  keyParams = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
   if (!keyParams)
     goto cleanup;
 
   CFDictionaryAddValue(keyParams, kSecAttrKeyType, kSecAttrKeyTypeRSA);
   CFDictionaryAddValue(keyParams, kSecAttrKeySizeInBits, CFSTR("2048"));
-  CFDictionaryAddValue(keyParams, kSecAttrLabel,
-                       CFSTR("CUPS Self-Signed Certificate"));
+  CFDictionaryAddValue(keyParams, kSecAttrLabel, CFSTR("CUPS Self-Signed Certificate"));
 
   err = SecKeyGeneratePair(keyParams, &publicKey, &privateKey);
   if (err != noErr)
@@ -181,7 +192,8 @@ cleanup:
                *envp[1000],            /* Environment variables */
                days[32],               /* CERTTOOL_EXPIRATION_DAYS env var */
                keychain[1024],         /* Keychain argument */
-               infofile[1024];         /* Type-in information for cert */
+               infofile[1024],         /* Type-in information for cert */
+               filename[1024];         /* Default keychain path */
   cups_file_t  *fp;                    /* Seed/info file */
 
 
@@ -190,6 +202,20 @@ cleanup:
   (void)num_alt_names;
   (void)alt_names;
 
+  if (!path)
+  {
+    const char *home = getenv("HOME"); /* HOME environment variable */
+
+    if (getuid() && home)
+      snprintf(filename, sizeof(filename), "%s/Library/Keychains/login.keychain", home);
+    else
+      strlcpy(filename, "/Library/Keychains/System.keychain", sizeof(filename));
+
+    path = filename;
+
+    DEBUG_printf(("1cupsMakeServerCredentials: Using default path \"%s\".", path));
+  }
+
  /*
   * Run the "certtool" command to generate a self-signed certificate...
   */
@@ -244,6 +270,10 @@ cleanup:
   posix_spawn_file_actions_init(&actions);
   posix_spawn_file_actions_addclose(&actions, 0);
   posix_spawn_file_actions_addopen(&actions, 0, infofile, O_RDONLY, 0);
+  posix_spawn_file_actions_addclose(&actions, 1);
+  posix_spawn_file_actions_addopen(&actions, 1, "/dev/null", O_WRONLY, 0);
+  posix_spawn_file_actions_addclose(&actions, 2);
+  posix_spawn_file_actions_addopen(&actions, 2, "/dev/null", O_WRONLY, 0);
 
   if (posix_spawn(&pid, command, &actions, NULL, argv, envp))
   {
@@ -278,16 +308,31 @@ cleanup:
 
 int                                    /* O - 1 on success, 0 on failure */
 cupsSetServerCredentials(
-    const char *path,                  /* I - Path to keychain/directory */
+    const char *path,                  /* I - Keychain path or @code NULL@ for default */
     const char *common_name,           /* I - Default common name for server */
     int        auto_create)            /* I - 1 = automatically create self-signed certificates */
 {
   DEBUG_printf(("cupsSetServerCredentials(path=\"%s\", common_name=\"%s\", auto_create=%d)", path, common_name, auto_create));
 
 #ifdef HAVE_SECKEYCHAINOPEN
+  char                 filename[1024]; /* Filename for keychain */
   SecKeychainRef       keychain = NULL;/* Temporary keychain */
 
 
+  if (!path)
+  {
+    const char *home = getenv("HOME"); /* HOME environment variable */
+
+    if (getuid() && home)
+      snprintf(filename, sizeof(filename), "%s/Library/Keychains/login.keychain", home);
+    else
+      strlcpy(filename, "/Library/Keychains/System.keychain", sizeof(filename));
+
+    path = filename;
+
+    DEBUG_printf(("1cupsSetServerCredentials: Using default path \"%s\".", path));
+  }
+
   if (SecKeychainOpen(path, &keychain) != noErr)
   {
     /* TODO: Set cups last error string */
@@ -703,7 +748,7 @@ _httpFreeCredentials(
 
 int                                    /* O - 0 on success, -1 on error */
 httpLoadCredentials(
-    const char   *path,                        /* I  - Keychain/PKCS#12 path */
+    const char   *path,                        /* I  - Keychain path or @code NULL@ for default */
     cups_array_t **credentials,                /* IO - Credentials */
     const char   *common_name)         /* I  - Common name for credentials */
 {
@@ -742,7 +787,6 @@ httpLoadCredentials(
     DEBUG_printf(("1httpLoadCredentials: Using default path \"%s\".", path));
   }
 
-
   if ((err = SecKeychainOpen(path, &keychain)) != noErr)
     goto cleanup;
 
@@ -821,7 +865,7 @@ httpLoadCredentials(
 
 int                                    /* O - -1 on error, 0 on success */
 httpSaveCredentials(
-    const char   *path,                        /* I - Keychain/PKCS#12 path */
+    const char   *path,                        /* I - Keychain path or @code NULL@ for default */
     cups_array_t *credentials,         /* I - Credentials */
     const char   *common_name)         /* I - Common name for credentials */
 {
@@ -1459,6 +1503,8 @@ http_cdsa_copy_server(
   if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)))
     goto cleanup;
 
+  _cupsMutexLock(&tls_mutex);
+
   list = CFArrayCreate(kCFAllocatorDefault, (const void **)&tls_keychain, 1, &kCFTypeArrayCallBacks);
 
   CFDictionaryAddValue(query, kSecClass, kSecClassIdentity);
@@ -1471,6 +1517,8 @@ http_cdsa_copy_server(
 
   err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
 
+  _cupsMutexUnlock(&tls_mutex);
+
   if (err)
     goto cleanup;
 
index 5695b262238e220be03adcdcd912581cfcc88a53..214a5e507fd772270e7a39cf8280e9b782a3a56e 100644 (file)
@@ -321,6 +321,9 @@ main(int  argc,                             /* I - Number of command-line args */
                *icon = "printer.png",  /* Icon file */
                *formats = "application/pdf,image/jpeg,image/pwg-raster";
                                        /* Supported formats */
+#ifdef HAVE_SSL
+  const char   *keypath = NULL;        /* Keychain path */
+#endif /* HAVE_SSL */
 #ifdef HAVE_DNSSD
   const char   *subtype = "_print";    /* Bonjour service subtype */
 #endif /* HAVE_DNSSD */
@@ -341,12 +344,22 @@ main(int  argc,                           /* I - Number of command-line args */
     if (argv[i][0] == '-')
     {
       for (opt = argv[i] + 1; *opt; opt ++)
+      {
         switch (*opt)
        {
          case '2' : /* -2 (enable 2-sided printing) */
              duplex = 1;
              break;
 
+#ifdef HAVE_SSL
+         case 'K' : /* -K keypath */
+             i ++;
+             if (i >= argc)
+               usage(1);
+             keypath = argv[i];
+             break;
+#endif /* HAVE_SSL */
+
          case 'M' : /* -M manufacturer */
              i ++;
              if (i >= argc)
@@ -447,6 +460,7 @@ main(int  argc,                             /* I - Number of command-line args */
              fprintf(stderr, "Unknown option \"-%c\".\n", *opt);
              usage(1);
        }
+      }
     }
     else if (!name)
     {
@@ -480,6 +494,10 @@ main(int  argc,                            /* I - Number of command-line args */
       fprintf(stderr, "Using spool directory \"%s\".\n", directory);
   }
 
+#ifdef HAVE_SSL
+  cupsSetServerCredentials(keypath, servername, 1);
+#endif /* HAVE_SSL */
+
  /*
   * Create the printer...
   */
@@ -3694,9 +3712,39 @@ process_client(_ipp_client_t *client)    /* I - Client */
   * Loop until we are out of requests or timeout (30 seconds)...
   */
 
+#ifdef HAVE_SSL
+  int first_time = 1;                  /* First time request? */
+#endif /* HAVE_SSL */
+
   while (httpWait(client->http, 30000))
+  {
+#ifdef HAVE_SSL
+    if (first_time)
+    {
+     /*
+      * See if we need to negotiate a TLS connection...
+      */
+
+      char buf[1];                     /* First byte from client */
+
+      if (recv(httpGetFd(client->http), buf, 1, MSG_PEEK) == 1 && (!buf[0] || !strchr("DGHOPT", buf[0])))
+      {
+        fprintf(stderr, "%s Negotiating TLS session.\n", client->hostname);
+
+       if (httpEncryption(client->http, HTTP_ENCRYPTION_ALWAYS))
+       {
+         fprintf(stderr, "%s Unable to encrypt connection: %s\n", client->hostname, cupsLastErrorString());
+         break;
+        }
+      }
+
+      first_time = 0;
+    }
+#endif /* HAVE_SSL */
+
     if (!process_http(client))
       break;
+  }
 
  /*
   * Close the conection to the client and return...
@@ -4448,7 +4496,7 @@ register_printer(
     return (0);
   }
 
-#  if 0 /* ifdef HAVE_SSL */
+#  ifdef HAVE_SSL
  /*
   * Then register the _ipps._tcp (IPP) service type with the real port number to
   * advertise our IPP printer...