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;
(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;
* 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)
*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 */
(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...
*/
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))
{
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 */
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 */
{
DEBUG_printf(("1httpLoadCredentials: Using default path \"%s\".", path));
}
-
if ((err = SecKeychainOpen(path, &keychain)) != noErr)
goto cleanup;
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 */
{
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);
err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
+ _cupsMutexUnlock(&tls_mutex);
+
if (err)
goto cleanup;
*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 */
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)
fprintf(stderr, "Unknown option \"-%c\".\n", *opt);
usage(1);
}
+ }
}
else if (!name)
{
fprintf(stderr, "Using spool directory \"%s\".\n", directory);
}
+#ifdef HAVE_SSL
+ cupsSetServerCredentials(keypath, servername, 1);
+#endif /* HAVE_SSL */
+
/*
* Create the printer...
*/
* 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...
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...