You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
784 lines
22 KiB
784 lines
22 KiB
/*
|
|
* TLS check program for CUPS.
|
|
*
|
|
* Copyright 2007-2017 by Apple Inc.
|
|
* Copyright 1997-2006 by Easy Software Products.
|
|
*
|
|
* Licensed under Apache License v2.0. See the file "LICENSE" for more information.
|
|
*/
|
|
|
|
/*
|
|
* Include necessary headers...
|
|
*/
|
|
|
|
#include "cups-private.h"
|
|
|
|
|
|
#ifndef HAVE_SSL
|
|
int main(void) { puts("Sorry, no TLS support compiled in."); return (1); }
|
|
#else
|
|
|
|
/*
|
|
* Local functions...
|
|
*/
|
|
|
|
static void usage(void);
|
|
|
|
|
|
/*
|
|
* 'main()' - Main entry.
|
|
*/
|
|
|
|
int /* O - Exit status */
|
|
main(int argc, /* I - Number of command-line arguments */
|
|
char *argv[]) /* I - Command-line arguments */
|
|
{
|
|
int i; /* Looping var */
|
|
http_t *http; /* HTTP connection */
|
|
const char *server = NULL; /* Hostname from command-line */
|
|
int port = 0; /* Port number */
|
|
cups_array_t *creds; /* Server credentials */
|
|
char creds_str[2048]; /* Credentials string */
|
|
const char *cipherName = "UNKNOWN";/* Cipher suite name */
|
|
int dhBits = 0; /* Diffie-Hellman bits */
|
|
int tlsVersion = 0; /* TLS version number */
|
|
char uri[1024], /* Printer URI */
|
|
scheme[32], /* URI scheme */
|
|
host[256], /* Hostname */
|
|
userpass[256], /* Username/password */
|
|
resource[256]; /* Resource path */
|
|
int af = AF_UNSPEC, /* Address family */
|
|
tls_options = _HTTP_TLS_NONE,
|
|
/* TLS options */
|
|
tls_min_version = _HTTP_TLS_1_0,
|
|
tls_max_version = _HTTP_TLS_MAX,
|
|
verbose = 0; /* Verbosity */
|
|
ipp_t *request, /* IPP Get-Printer-Attributes request */
|
|
*response; /* IPP Get-Printer-Attributes response */
|
|
ipp_attribute_t *attr; /* Current attribute */
|
|
const char *name; /* Attribute name */
|
|
char value[1024]; /* Attribute (string) value */
|
|
static const char * const pattrs[] = /* Requested attributes */
|
|
{
|
|
"color-supported",
|
|
"compression-supported",
|
|
"document-format-supported",
|
|
"pages-per-minute",
|
|
"printer-location",
|
|
"printer-make-and-model",
|
|
"printer-state",
|
|
"printer-state-reasons",
|
|
"sides-supported",
|
|
"uri-authentication-supported",
|
|
"uri-security-supported"
|
|
};
|
|
|
|
|
|
for (i = 1; i < argc; i ++)
|
|
{
|
|
if (!strcmp(argv[i], "--dh"))
|
|
{
|
|
tls_options |= _HTTP_TLS_ALLOW_DH;
|
|
}
|
|
else if (!strcmp(argv[i], "--no-cbc"))
|
|
{
|
|
tls_options |= _HTTP_TLS_DENY_CBC;
|
|
}
|
|
else if (!strcmp(argv[i], "--no-tls10"))
|
|
{
|
|
tls_min_version = _HTTP_TLS_1_1;
|
|
}
|
|
else if (!strcmp(argv[i], "--tls10"))
|
|
{
|
|
tls_min_version = _HTTP_TLS_1_0;
|
|
tls_max_version = _HTTP_TLS_1_0;
|
|
}
|
|
else if (!strcmp(argv[i], "--tls11"))
|
|
{
|
|
tls_min_version = _HTTP_TLS_1_1;
|
|
tls_max_version = _HTTP_TLS_1_1;
|
|
}
|
|
else if (!strcmp(argv[i], "--tls12"))
|
|
{
|
|
tls_min_version = _HTTP_TLS_1_2;
|
|
tls_max_version = _HTTP_TLS_1_2;
|
|
}
|
|
else if (!strcmp(argv[i], "--tls13"))
|
|
{
|
|
tls_min_version = _HTTP_TLS_1_3;
|
|
tls_max_version = _HTTP_TLS_1_3;
|
|
}
|
|
else if (!strcmp(argv[i], "--rc4"))
|
|
{
|
|
tls_options |= _HTTP_TLS_ALLOW_RC4;
|
|
}
|
|
else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v"))
|
|
{
|
|
verbose = 1;
|
|
}
|
|
else if (!strcmp(argv[i], "-4"))
|
|
{
|
|
af = AF_INET;
|
|
}
|
|
else if (!strcmp(argv[i], "-6"))
|
|
{
|
|
af = AF_INET6;
|
|
}
|
|
else if (argv[i][0] == '-')
|
|
{
|
|
printf("tlscheck: Unknown option '%s'.\n", argv[i]);
|
|
usage();
|
|
}
|
|
else if (!server)
|
|
{
|
|
if (!strncmp(argv[i], "ipps://", 7))
|
|
{
|
|
httpSeparateURI(HTTP_URI_CODING_ALL, argv[i], scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource));
|
|
server = host;
|
|
}
|
|
else
|
|
{
|
|
server = argv[i];
|
|
strlcpy(resource, "/ipp/print", sizeof(resource));
|
|
}
|
|
}
|
|
else if (!port && (argv[i][0] == '=' || isdigit(argv[i][0] & 255)))
|
|
{
|
|
if (argv[i][0] == '=')
|
|
port = atoi(argv[i] + 1);
|
|
else
|
|
port = atoi(argv[i]);
|
|
}
|
|
else
|
|
{
|
|
printf("tlscheck: Unexpected argument '%s'.\n", argv[i]);
|
|
usage();
|
|
}
|
|
}
|
|
|
|
if (!server)
|
|
usage();
|
|
|
|
if (!port)
|
|
port = 631;
|
|
|
|
_httpTLSSetOptions(tls_options, tls_min_version, tls_max_version);
|
|
|
|
http = httpConnect2(server, port, NULL, af, HTTP_ENCRYPTION_ALWAYS, 1, 30000, NULL);
|
|
if (!http)
|
|
{
|
|
printf("%s: ERROR (%s)\n", server, cupsLastErrorString());
|
|
return (1);
|
|
}
|
|
|
|
if (httpCopyCredentials(http, &creds))
|
|
{
|
|
strlcpy(creds_str, "Unable to get server X.509 credentials.", sizeof(creds_str));
|
|
}
|
|
else
|
|
{
|
|
httpCredentialsString(creds, creds_str, sizeof(creds_str));
|
|
httpFreeCredentials(creds);
|
|
}
|
|
|
|
#ifdef __APPLE__
|
|
SSLProtocol protocol;
|
|
SSLCipherSuite cipher;
|
|
char unknownCipherName[256];
|
|
int paramsNeeded = 0;
|
|
const void *params;
|
|
size_t paramsLen;
|
|
OSStatus err;
|
|
|
|
if ((err = SSLGetNegotiatedProtocolVersion(http->tls, &protocol)) != noErr)
|
|
{
|
|
printf("%s: ERROR (No protocol version - %d)\n", server, (int)err);
|
|
httpClose(http);
|
|
return (1);
|
|
}
|
|
|
|
switch (protocol)
|
|
{
|
|
default :
|
|
tlsVersion = 0;
|
|
break;
|
|
case kSSLProtocol3 :
|
|
tlsVersion = 30;
|
|
break;
|
|
case kTLSProtocol1 :
|
|
tlsVersion = 10;
|
|
break;
|
|
case kTLSProtocol11 :
|
|
tlsVersion = 11;
|
|
break;
|
|
case kTLSProtocol12 :
|
|
tlsVersion = 12;
|
|
break;
|
|
}
|
|
|
|
if ((err = SSLGetNegotiatedCipher(http->tls, &cipher)) != noErr)
|
|
{
|
|
printf("%s: ERROR (No cipher suite - %d)\n", server, (int)err);
|
|
httpClose(http);
|
|
return (1);
|
|
}
|
|
|
|
switch (cipher)
|
|
{
|
|
case TLS_NULL_WITH_NULL_NULL:
|
|
cipherName = "TLS_NULL_WITH_NULL_NULL";
|
|
break;
|
|
case TLS_RSA_WITH_NULL_MD5:
|
|
cipherName = "TLS_RSA_WITH_NULL_MD5";
|
|
break;
|
|
case TLS_RSA_WITH_NULL_SHA:
|
|
cipherName = "TLS_RSA_WITH_NULL_SHA";
|
|
break;
|
|
case TLS_RSA_WITH_RC4_128_MD5:
|
|
cipherName = "TLS_RSA_WITH_RC4_128_MD5";
|
|
break;
|
|
case TLS_RSA_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_RSA_WITH_RC4_128_SHA";
|
|
break;
|
|
case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
|
|
break;
|
|
case TLS_RSA_WITH_NULL_SHA256:
|
|
cipherName = "TLS_RSA_WITH_NULL_SHA256";
|
|
break;
|
|
case TLS_RSA_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA256";
|
|
break;
|
|
case TLS_RSA_WITH_AES_256_CBC_SHA256:
|
|
cipherName = "TLS_RSA_WITH_AES_256_CBC_SHA256";
|
|
break;
|
|
case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
|
|
cipherName = "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
|
|
cipherName = "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
|
|
cipherName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
|
|
cipherName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_anon_WITH_RC4_128_MD5:
|
|
cipherName = "TLS_DH_anon_WITH_RC4_128_MD5";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
|
|
cipherName = "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_PSK_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_PSK_WITH_RC4_128_SHA";
|
|
break;
|
|
case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
|
|
break;
|
|
case TLS_PSK_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_PSK_WITH_AES_128_CBC_SHA";
|
|
break;
|
|
case TLS_PSK_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_PSK_WITH_AES_256_CBC_SHA";
|
|
break;
|
|
case TLS_DHE_PSK_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_DHE_PSK_WITH_RC4_128_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_RSA_PSK_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_RSA_PSK_WITH_RC4_128_SHA";
|
|
break;
|
|
case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
|
|
break;
|
|
case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
|
|
break;
|
|
case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
|
|
break;
|
|
case TLS_PSK_WITH_NULL_SHA:
|
|
cipherName = "TLS_PSK_WITH_NULL_SHA";
|
|
break;
|
|
case TLS_DHE_PSK_WITH_NULL_SHA:
|
|
cipherName = "TLS_DHE_PSK_WITH_NULL_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_RSA_PSK_WITH_NULL_SHA:
|
|
cipherName = "TLS_RSA_PSK_WITH_NULL_SHA";
|
|
break;
|
|
case TLS_RSA_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_RSA_WITH_AES_128_GCM_SHA256";
|
|
break;
|
|
case TLS_RSA_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_RSA_WITH_AES_256_GCM_SHA384";
|
|
break;
|
|
case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_PSK_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_PSK_WITH_AES_128_GCM_SHA256";
|
|
break;
|
|
case TLS_PSK_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_PSK_WITH_AES_256_GCM_SHA384";
|
|
break;
|
|
case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
|
|
break;
|
|
case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384";
|
|
break;
|
|
case TLS_PSK_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_PSK_WITH_AES_128_CBC_SHA256";
|
|
break;
|
|
case TLS_PSK_WITH_AES_256_CBC_SHA384:
|
|
cipherName = "TLS_PSK_WITH_AES_256_CBC_SHA384";
|
|
break;
|
|
case TLS_PSK_WITH_NULL_SHA256:
|
|
cipherName = "TLS_PSK_WITH_NULL_SHA256";
|
|
break;
|
|
case TLS_PSK_WITH_NULL_SHA384:
|
|
cipherName = "TLS_PSK_WITH_NULL_SHA384";
|
|
break;
|
|
case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
|
|
cipherName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_PSK_WITH_NULL_SHA256:
|
|
cipherName = "TLS_DHE_PSK_WITH_NULL_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_PSK_WITH_NULL_SHA384:
|
|
cipherName = "TLS_DHE_PSK_WITH_NULL_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
|
|
break;
|
|
case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
|
|
cipherName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
|
|
break;
|
|
case TLS_RSA_PSK_WITH_NULL_SHA256:
|
|
cipherName = "TLS_RSA_PSK_WITH_NULL_SHA256";
|
|
break;
|
|
case TLS_RSA_PSK_WITH_NULL_SHA384:
|
|
cipherName = "TLS_RSA_PSK_WITH_NULL_SHA384";
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
|
|
cipherName = "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
|
|
cipherName = "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
|
|
cipherName = "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
|
|
cipherName = "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_RSA_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA";
|
|
break;
|
|
case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_anon_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_DH_anon_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_RSA_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_RSA_WITH_AES_256_CBC_SHA";
|
|
break;
|
|
case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_DH_anon_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_DH_anon_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_NULL_SHA:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_NULL_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_NULL_SHA:
|
|
cipherName = "TLS_ECDH_RSA_WITH_NULL_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_ECDH_RSA_WITH_RC4_128_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_NULL_SHA:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_NULL_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_anon_WITH_NULL_SHA:
|
|
cipherName = "TLS_ECDH_anon_WITH_NULL_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_anon_WITH_RC4_128_SHA:
|
|
cipherName = "TLS_ECDH_anon_WITH_RC4_128_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
|
|
cipherName = "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
|
|
cipherName = "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
|
|
cipherName = "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
|
|
paramsNeeded = 1;
|
|
break;
|
|
default :
|
|
snprintf(unknownCipherName, sizeof(unknownCipherName), "UNKNOWN_%04X", cipher);
|
|
cipherName = unknownCipherName;
|
|
break;
|
|
}
|
|
|
|
if (cipher == TLS_RSA_WITH_RC4_128_MD5 ||
|
|
cipher == TLS_RSA_WITH_RC4_128_SHA)
|
|
{
|
|
printf("%s: ERROR (Printers MUST NOT negotiate RC4 cipher suites.)\n", server);
|
|
httpClose(http);
|
|
return (1);
|
|
}
|
|
|
|
if ((err = SSLGetDiffieHellmanParams(http->tls, ¶ms, ¶msLen)) != noErr && paramsNeeded)
|
|
{
|
|
printf("%s: ERROR (Unable to get Diffie-Hellman parameters - %d)\n", server, (int)err);
|
|
httpClose(http);
|
|
return (1);
|
|
}
|
|
|
|
if (paramsLen < 128 && paramsLen != 0)
|
|
{
|
|
printf("%s: ERROR (Diffie-Hellman parameters MUST be at least 2048 bits, but Printer uses only %d bits/%d bytes)\n", server, (int)paramsLen * 8, (int)paramsLen);
|
|
httpClose(http);
|
|
return (1);
|
|
}
|
|
|
|
dhBits = (int)paramsLen * 8;
|
|
#endif /* __APPLE__ */
|
|
|
|
if (dhBits > 0)
|
|
printf("%s: OK (TLS: %d.%d, %s, %d DH bits)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName, dhBits);
|
|
else
|
|
printf("%s: OK (TLS: %d.%d, %s)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName);
|
|
|
|
printf(" %s\n", creds_str);
|
|
|
|
if (verbose)
|
|
{
|
|
httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipps", NULL, host, port, resource);
|
|
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
|
|
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);
|
|
|
|
response = cupsDoRequest(http, request, resource);
|
|
|
|
for (attr = ippFirstAttribute(response); attr; attr = ippNextAttribute(response))
|
|
{
|
|
if (ippGetGroupTag(attr) != IPP_TAG_PRINTER)
|
|
continue;
|
|
|
|
if ((name = ippGetName(attr)) == NULL)
|
|
continue;
|
|
|
|
ippAttributeString(attr, value, sizeof(value));
|
|
printf(" %s=%s\n", name, value);
|
|
}
|
|
|
|
ippDelete(response);
|
|
puts("");
|
|
}
|
|
|
|
httpClose(http);
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
/*
|
|
* 'usage()' - Show program usage.
|
|
*/
|
|
|
|
static void
|
|
usage(void)
|
|
{
|
|
puts("Usage: ./tlscheck [options] server [port]");
|
|
puts(" ./tlscheck [options] ipps://server[:port]/path");
|
|
puts("");
|
|
puts("Options:");
|
|
puts(" --dh Allow DH/DHE key exchange");
|
|
puts(" --no-cbc Disable CBC cipher suites");
|
|
puts(" --no-tls10 Disable TLS/1.0");
|
|
puts(" --rc4 Allow RC4 encryption");
|
|
puts(" --tls10 Only use TLS/1.0");
|
|
puts(" --tls11 Only use TLS/1.1");
|
|
puts(" --tls12 Only use TLS/1.2");
|
|
puts(" --tls13 Only use TLS/1.3");
|
|
puts(" --verbose Be verbose");
|
|
puts(" -4 Connect using IPv4 addresses only");
|
|
puts(" -6 Connect using IPv6 addresses only");
|
|
puts(" -v Be verbose");
|
|
puts("");
|
|
puts("The default port is 631.");
|
|
|
|
exit(1);
|
|
}
|
|
#endif /* !HAVE_SSL */
|