void *server_cert_data;
/* Server certificate user data */
int server_version, /* Server IPP version */
- any_root, /* Allow any root */
- expired_certs, /* Allow expired certs */
- expired_root; /* Allow expired root */
+ any_root, /* Allow any (e.g., self-signed) root */
+ expired_certs; /* Allow expired certs */
/* util.c */
char def_printer[256];
cg->password_cb = (cups_password_cb2_t)_cupsGetPassword;
cg->any_root = 1;
cg->expired_certs = 1;
- cg->expired_root = 1;
#ifdef DEBUG
/*
# include <Security/SecCertificate.h>
# include <Security/SecIdentity.h>
# endif /* HAVE_SECCERTIFICATE_H */
+# ifdef HAVE_SECCERTIFICATEPRIV_H
+# include <Security/SecCertificatePriv.h>
+# else
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+extern SecCertificateRef SecCertificateCreateWithBytes(CFAllocatorRef allocator, const UInt8 *bytes, CFIndex length);
+extern bool SecCertificateIsValid(SecCertificateRef certificate, CFAbsoluteTime verifyTime);
+extern CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRef certificate);
+extern OSStatus SecCertificateIsSelfSigned(SecCertificateRef certRef, Boolean *isSelfSigned);
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+# endif /* HAVE_SECCERTIFICATEPRIV_H */
# ifdef HAVE_SECITEMPRIV_H
# include <Security/SecItemPriv.h>
# endif /* HAVE_SECITEMPRIV_H */
perror(hostname);
continue;
}
+
+ if (httpIsEncrypted(http))
+ {
+ cups_array_t *creds;
+ char info[1024];
+
+ if (!httpCopyCredentials(http, &creds))
+ {
+ httpCredentialsString(creds, info, sizeof(info));
+ httpFreeCredentials(creds);
+ printf("Credentials: \"%s\"\n", info);
+ }
+ else
+ puts("Credentials: Unknown");
+ }
+
printf("Checking file \"%s\"...\n", resource);
do
}
+/*
+ * 'http_cdsa_create_credential()' - Create a single credential in the internal format.
+ */
+
+static SecCertificateRef /* O - Certificate */
+http_cdsa_create_credential(
+ http_credential_t *credential) /* I - Credential */
+{
+ if (!credential)
+ return (NULL);
+
+ return (SecCertificateCreateWithBytes(kCFAllocatorDefault, credential->data, (CFIndex)credential->datalen));
+}
+
+
/*
* '_httpCreateCredentials()' - Create credentials in the internal format.
*/
{
CFMutableArrayRef peerCerts; /* Peer credentials reference */
SecCertificateRef secCert; /* Certificate reference */
- CFDataRef data; /* Credential data reference */
http_credential_t *credential; /* Credential data */
credential;
credential = (http_credential_t *)cupsArrayNext(credentials))
{
- if ((data = CFDataCreate(kCFAllocatorDefault, credential->data, (CFIndex)credential->datalen)))
+ if ((secCert = http_cdsa_create_credential(credential)) != NULL)
{
- if ((secCert = SecCertificateCreateWithData(kCFAllocatorDefault, data))
- != NULL)
- {
- CFArrayAppendValue(peerCerts, secCert);
- CFRelease(secCert);
- }
-
- CFRelease(data);
+ CFArrayAppendValue(peerCerts, secCert);
+ CFRelease(secCert);
}
}
httpCredentialsAreTrusted(
cups_array_t *credentials) /* I - Credentials */
{
- (void)credentials;
+ SecCertificateRef secCert; /* Certificate reference */
+ int trusted = 1; /* Trusted? */
+ Boolean isSelfSigned; /* Is this certificate self-signed? */
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Per-thread globals */
- return (0);
+
+ if ((secCert = http_cdsa_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL)
+ return (0);
+
+ if (!cg->expired_certs && !SecCertificateIsValid(secCert, CFAbsoluteTimeGetCurrent()))
+ trusted = 0;
+ else if (!cg->any_root && (SecCertificateIsSelfSigned(secCert, &isSelfSigned) != noErr || isSelfSigned))
+ trusted = 0;
+
+ CFRelease(secCert);
+
+ return (trusted);
}
httpCredentialsGetExpiration(
cups_array_t *credentials) /* I - Credentials */
{
- (void)credentials;
+ SecCertificateRef secCert; /* Certificate reference */
+ time_t expiration; /* Expiration date */
- return (0);
+
+ if ((secCert = http_cdsa_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL)
+ return (0);
+
+ expiration = (time_t)(SecCertificateNotValidAfter(secCert) - kCFAbsoluteTimeIntervalSince1970);
+
+ CFRelease(secCert);
+
+ return (expiration);
}
cups_array_t *credentials, /* I - Credentials */
const char *common_name) /* I - Name to check */
{
- (void)credentials;
- (void)common_name;
+ SecCertificateRef secCert; /* Certificate reference */
+ CFStringRef cfcommon_name; /* CF string for common name */
+ CFStringRef cert_name = NULL;
+ /* Certificate's common name */
+ int valid = 1; /* Valid name? */
- return (0);
+
+ if ((secCert = http_cdsa_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL)
+ return (0);
+
+ /*
+ * Compare the common names...
+ */
+
+ cfcommon_name = CFStringCreateWithCString(kCFAllocatorDefault, common_name, kCFStringEncodingUTF8);
+
+ if (SecCertificateCopyCommonName(secCert, &cert_name) != noErr)
+ {
+ /*
+ * Can't get common name, cannot be valid...
+ */
+
+ valid = 0;
+ }
+ else if (CFStringCompare(cfcommon_name, cert_name, kCFCompareCaseInsensitive))
+ {
+ /*
+ * Not the common name, check whether the certificate is saved in the keychain...
+ */
+
+ /* TODO: Pull certificate from the keychain using label */
+ }
+
+ CFRelease(cfcommon_name);
+
+ if (cert_name)
+ CFRelease(cert_name);
+
+ CFRelease(secCert);
+
+ return (valid);
}
char *buffer, /* I - Buffer or @code NULL@ */
size_t bufsize) /* I - Size of buffer */
{
- (void)credentials;
+ SecCertificateRef secCert; /* Certificate reference */
+ CFStringRef summary; /* CF string for summary */
+
+
+ if (!buffer)
+ return (0);
if (buffer && bufsize > 0)
*buffer = '\0';
- return (1);
+ /* TODO: This needs to include a hash of the credentials */
+ if ((secCert = http_cdsa_create_credential((http_credential_t *)cupsArrayFirst(credentials))) != NULL)
+ {
+ if ((summary = SecCertificateCopySubjectSummary(secCert)) != NULL)
+ {
+ CFStringGetCString(summary, buffer, (CFIndex)bufsize, kCFStringEncodingUTF8);
+ CFRelease(summary);
+ }
+
+ CFRelease(secCert);
+ }
+
+ return (strlen(buffer));
}
const char *cups_gssservicename,
#endif /* HAVE_GSSAPI */
const char *cups_anyroot,
- const char *cups_expiredroot,
const char *cups_expiredcerts);
*cups_gssservicename, /* CUPS_GSSSERVICENAME env var */
#endif /* HAVE_GSSAPI */
*cups_anyroot, /* CUPS_ANYROOT env var */
- *cups_expiredroot, /* CUPS_EXPIREDROOT env var */
*cups_expiredcerts; /* CUPS_EXPIREDCERTS env var */
char filename[1024]; /* Filename */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
cups_gssservicename = getenv("CUPS_GSSSERVICENAME");
#endif /* HAVE_GSSAPI */
cups_anyroot = getenv("CUPS_ANYROOT");
- cups_expiredroot = getenv("CUPS_EXPIREDROOT");
cups_expiredcerts = getenv("CUPS_EXPIREDCERTS");
if ((cups_user = getenv("CUPS_USER")) == NULL)
#ifdef HAVE_GSSAPI
cups_gssservicename,
#endif /* HAVE_GSSAPI */
- cups_anyroot, cups_expiredroot,
- cups_expiredcerts);
+ cups_anyroot, cups_expiredcerts);
cupsFileClose(fp);
}
}
/* I - CUPS_GSSSERVICENAME env var */
#endif /* HAVE_GSSAPI */
const char *cups_anyroot, /* I - CUPS_ANYROOT env var */
- const char *cups_expiredroot, /* I - CUPS_EXPIREDROOT env var */
const char *cups_expiredcerts) /* I - CUPS_EXPIREDCERTS env var */
{
int linenum; /* Current line number */
#endif /* !__APPLE__ */
user[256], /* User value */
any_root[1024], /* AllowAnyRoot value */
- expired_root[1024], /* AllowExpiredRoot value */
expired_certs[1024]; /* AllowExpiredCerts value */
#ifdef HAVE_GSSAPI
char gss_service_name[32]; /* GSSServiceName value */
strlcpy(any_root, value, sizeof(any_root));
cups_anyroot = any_root;
}
- else if (!cups_expiredroot && !_cups_strcasecmp(line, "AllowExpiredRoot") &&
- value)
- {
- strlcpy(expired_root, value, sizeof(expired_root));
- cups_expiredroot = expired_root;
- }
else if (!cups_expiredcerts && !_cups_strcasecmp(line, "AllowExpiredCerts") &&
value)
{
!_cups_strcasecmp(cups_anyroot, "on") ||
!_cups_strcasecmp(cups_anyroot, "true");
- if (cups_expiredroot)
- cg->expired_root = !_cups_strcasecmp(cups_expiredroot, "yes") ||
- !_cups_strcasecmp(cups_expiredroot, "on") ||
- !_cups_strcasecmp(cups_expiredroot, "true");
-
if (cups_expiredcerts)
cg->expired_certs = !_cups_strcasecmp(cups_expiredcerts, "yes") ||
!_cups_strcasecmp(cups_expiredcerts, "on") ||