Home | History | Annotate | Download | only in cups
      1 /*
      2  * TLS check program for CUPS.
      3  *
      4  * Copyright 2007-2017 by Apple Inc.
      5  * Copyright 1997-2006 by Easy Software Products.
      6  *
      7  * These coded instructions, statements, and computer programs are the
      8  * property of Apple Inc. and are protected by Federal copyright
      9  * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
     10  * which should have been included with this file.  If this file is
     11  * missing or damaged, see the license at "http://www.cups.org/".
     12  *
     13  * This file is subject to the Apple OS-Developed Software exception.
     14  */
     15 
     16 /*
     17  * Include necessary headers...
     18  */
     19 
     20 #include "cups-private.h"
     21 
     22 
     23 #ifndef HAVE_SSL
     24 int main(void) { puts("Sorry, no TLS support compiled in."); return (1); }
     25 #else
     26 
     27 /*
     28  * Local functions...
     29  */
     30 
     31 static void	usage(void);
     32 
     33 
     34 /*
     35  * 'main()' - Main entry.
     36  */
     37 
     38 int					/* O - Exit status */
     39 main(int  argc,				/* I - Number of command-line arguments */
     40      char *argv[])			/* I - Command-line arguments */
     41 {
     42   int		i;			/* Looping var */
     43   http_t	*http;			/* HTTP connection */
     44   const char	*server = NULL;		/* Hostname from command-line */
     45   int		port = 0;		/* Port number */
     46   const char	*cipherName = "UNKNOWN";/* Cipher suite name */
     47   int		dhBits = 0;		/* Diffie-Hellman bits */
     48   int		tlsVersion = 0;		/* TLS version number */
     49   char		uri[1024],		/* Printer URI */
     50 		scheme[32],		/* URI scheme */
     51 		host[256],		/* Hostname */
     52 		userpass[256],		/* Username/password */
     53 		resource[256];		/* Resource path */
     54   int		af = AF_UNSPEC,		/* Address family */
     55 		tls_options = _HTTP_TLS_NONE,
     56 					/* TLS options */
     57 		verbose = 0;		/* Verbosity */
     58   ipp_t		*request,		/* IPP Get-Printer-Attributes request */
     59 		*response;		/* IPP Get-Printer-Attributes response */
     60   ipp_attribute_t *attr;		/* Current attribute */
     61   const char	*name;			/* Attribute name */
     62   char		value[1024];		/* Attribute (string) value */
     63   static const char * const pattrs[] =	/* Requested attributes */
     64   {
     65     "color-supported",
     66     "compression-supported",
     67     "document-format-supported",
     68     "pages-per-minute",
     69     "printer-location",
     70     "printer-make-and-model",
     71     "printer-state",
     72     "printer-state-reasons",
     73     "sides-supported",
     74     "uri-authentication-supported",
     75     "uri-security-supported"
     76   };
     77 
     78 
     79   for (i = 1; i < argc; i ++)
     80   {
     81     if (!strcmp(argv[i], "--dh"))
     82     {
     83       tls_options |= _HTTP_TLS_ALLOW_DH;
     84     }
     85     else if (!strcmp(argv[i], "--no-cbc"))
     86     {
     87       tls_options |= _HTTP_TLS_DENY_CBC;
     88     }
     89     else if (!strcmp(argv[i], "--no-tls10"))
     90     {
     91       tls_options |= _HTTP_TLS_DENY_TLS10;
     92     }
     93     else if (!strcmp(argv[i], "--tls10"))
     94     {
     95       tls_options |= _HTTP_TLS_ONLY_TLS10;
     96     }
     97     else if (!strcmp(argv[i], "--rc4"))
     98     {
     99       tls_options |= _HTTP_TLS_ALLOW_RC4;
    100     }
    101     else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v"))
    102     {
    103       verbose = 1;
    104     }
    105     else if (!strcmp(argv[i], "-4"))
    106     {
    107       af = AF_INET;
    108     }
    109     else if (!strcmp(argv[i], "-6"))
    110     {
    111       af = AF_INET6;
    112     }
    113     else if (argv[i][0] == '-')
    114     {
    115       printf("tlscheck: Unknown option '%s'.\n", argv[i]);
    116       usage();
    117     }
    118     else if (!server)
    119     {
    120       if (!strncmp(argv[i], "ipps://", 7))
    121       {
    122         httpSeparateURI(HTTP_URI_CODING_ALL, argv[i], scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource));
    123         server = host;
    124       }
    125       else
    126       {
    127         server = argv[i];
    128         strlcpy(resource, "/ipp/print", sizeof(resource));
    129       }
    130     }
    131     else if (!port && (argv[i][0] == '=' || isdigit(argv[i][0] & 255)))
    132     {
    133       if (argv[i][0] == '=')
    134 	port = atoi(argv[i] + 1);
    135       else
    136 	port = atoi(argv[i]);
    137     }
    138     else
    139     {
    140       printf("tlscheck: Unexpected argument '%s'.\n", argv[i]);
    141       usage();
    142     }
    143   }
    144 
    145   if (!server)
    146     usage();
    147 
    148   if (!port)
    149     port = 631;
    150 
    151   _httpTLSSetOptions(tls_options);
    152 
    153   http = httpConnect2(server, port, NULL, af, HTTP_ENCRYPTION_ALWAYS, 1, 30000, NULL);
    154   if (!http)
    155   {
    156     printf("%s: ERROR (%s)\n", server, cupsLastErrorString());
    157     return (1);
    158   }
    159 
    160 #ifdef __APPLE__
    161   SSLProtocol protocol;
    162   SSLCipherSuite cipher;
    163   char unknownCipherName[256];
    164   int paramsNeeded = 0;
    165   const void *params;
    166   size_t paramsLen;
    167   OSStatus err;
    168 
    169   if ((err = SSLGetNegotiatedProtocolVersion(http->tls, &protocol)) != noErr)
    170   {
    171     printf("%s: ERROR (No protocol version - %d)\n", server, (int)err);
    172     httpClose(http);
    173     return (1);
    174   }
    175 
    176   switch (protocol)
    177   {
    178     default :
    179         tlsVersion = 0;
    180         break;
    181     case kSSLProtocol3 :
    182         tlsVersion = 30;
    183         break;
    184     case kTLSProtocol1 :
    185         tlsVersion = 10;
    186         break;
    187     case kTLSProtocol11 :
    188         tlsVersion = 11;
    189         break;
    190     case kTLSProtocol12 :
    191         tlsVersion = 12;
    192         break;
    193   }
    194 
    195   if ((err = SSLGetNegotiatedCipher(http->tls, &cipher)) != noErr)
    196   {
    197     printf("%s: ERROR (No cipher suite - %d)\n", server, (int)err);
    198     httpClose(http);
    199     return (1);
    200   }
    201 
    202   switch (cipher)
    203   {
    204     case TLS_NULL_WITH_NULL_NULL:
    205 	cipherName = "TLS_NULL_WITH_NULL_NULL";
    206 	break;
    207     case TLS_RSA_WITH_NULL_MD5:
    208 	cipherName = "TLS_RSA_WITH_NULL_MD5";
    209 	break;
    210     case TLS_RSA_WITH_NULL_SHA:
    211 	cipherName = "TLS_RSA_WITH_NULL_SHA";
    212 	break;
    213     case TLS_RSA_WITH_RC4_128_MD5:
    214 	cipherName = "TLS_RSA_WITH_RC4_128_MD5";
    215 	break;
    216     case TLS_RSA_WITH_RC4_128_SHA:
    217 	cipherName = "TLS_RSA_WITH_RC4_128_SHA";
    218 	break;
    219     case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
    220 	cipherName = "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
    221 	break;
    222     case TLS_RSA_WITH_NULL_SHA256:
    223 	cipherName = "TLS_RSA_WITH_NULL_SHA256";
    224 	break;
    225     case TLS_RSA_WITH_AES_128_CBC_SHA256:
    226 	cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA256";
    227 	break;
    228     case TLS_RSA_WITH_AES_256_CBC_SHA256:
    229 	cipherName = "TLS_RSA_WITH_AES_256_CBC_SHA256";
    230 	break;
    231     case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
    232 	cipherName = "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
    233 	paramsNeeded = 1;
    234 	break;
    235     case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
    236 	cipherName = "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
    237 	paramsNeeded = 1;
    238 	break;
    239     case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
    240 	cipherName = "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
    241 	paramsNeeded = 1;
    242 	break;
    243     case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
    244 	cipherName = "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
    245 	paramsNeeded = 1;
    246 	break;
    247     case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
    248 	cipherName = "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
    249 	paramsNeeded = 1;
    250 	break;
    251     case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
    252 	cipherName = "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
    253 	paramsNeeded = 1;
    254 	break;
    255     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
    256 	cipherName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
    257 	paramsNeeded = 1;
    258 	break;
    259     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
    260 	cipherName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
    261 	paramsNeeded = 1;
    262 	break;
    263     case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
    264 	cipherName = "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
    265 	paramsNeeded = 1;
    266 	break;
    267     case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
    268 	cipherName = "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
    269 	paramsNeeded = 1;
    270 	break;
    271     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
    272 	cipherName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
    273 	paramsNeeded = 1;
    274 	break;
    275     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
    276 	cipherName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
    277 	paramsNeeded = 1;
    278 	break;
    279     case TLS_DH_anon_WITH_RC4_128_MD5:
    280 	cipherName = "TLS_DH_anon_WITH_RC4_128_MD5";
    281 	paramsNeeded = 1;
    282 	break;
    283     case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
    284 	cipherName = "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
    285 	paramsNeeded = 1;
    286 	break;
    287     case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
    288 	cipherName = "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
    289 	paramsNeeded = 1;
    290 	break;
    291     case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
    292 	cipherName = "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
    293 	paramsNeeded = 1;
    294 	break;
    295     case TLS_PSK_WITH_RC4_128_SHA:
    296 	cipherName = "TLS_PSK_WITH_RC4_128_SHA";
    297 	break;
    298     case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
    299 	cipherName = "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
    300 	break;
    301     case TLS_PSK_WITH_AES_128_CBC_SHA:
    302 	cipherName = "TLS_PSK_WITH_AES_128_CBC_SHA";
    303 	break;
    304     case TLS_PSK_WITH_AES_256_CBC_SHA:
    305 	cipherName = "TLS_PSK_WITH_AES_256_CBC_SHA";
    306 	break;
    307     case TLS_DHE_PSK_WITH_RC4_128_SHA:
    308 	cipherName = "TLS_DHE_PSK_WITH_RC4_128_SHA";
    309 	paramsNeeded = 1;
    310 	break;
    311     case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
    312 	cipherName = "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
    313 	paramsNeeded = 1;
    314 	break;
    315     case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
    316 	cipherName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
    317 	paramsNeeded = 1;
    318 	break;
    319     case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
    320 	cipherName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
    321 	paramsNeeded = 1;
    322 	break;
    323     case TLS_RSA_PSK_WITH_RC4_128_SHA:
    324 	cipherName = "TLS_RSA_PSK_WITH_RC4_128_SHA";
    325 	break;
    326     case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
    327 	cipherName = "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
    328 	break;
    329     case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
    330 	cipherName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
    331 	break;
    332     case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
    333 	cipherName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
    334 	break;
    335     case TLS_PSK_WITH_NULL_SHA:
    336 	cipherName = "TLS_PSK_WITH_NULL_SHA";
    337 	break;
    338     case TLS_DHE_PSK_WITH_NULL_SHA:
    339 	cipherName = "TLS_DHE_PSK_WITH_NULL_SHA";
    340 	paramsNeeded = 1;
    341 	break;
    342     case TLS_RSA_PSK_WITH_NULL_SHA:
    343 	cipherName = "TLS_RSA_PSK_WITH_NULL_SHA";
    344 	break;
    345     case TLS_RSA_WITH_AES_128_GCM_SHA256:
    346 	cipherName = "TLS_RSA_WITH_AES_128_GCM_SHA256";
    347 	break;
    348     case TLS_RSA_WITH_AES_256_GCM_SHA384:
    349 	cipherName = "TLS_RSA_WITH_AES_256_GCM_SHA384";
    350 	break;
    351     case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
    352 	cipherName = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
    353 	paramsNeeded = 1;
    354 	break;
    355     case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
    356 	cipherName = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
    357 	paramsNeeded = 1;
    358 	break;
    359     case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
    360 	cipherName = "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
    361 	paramsNeeded = 1;
    362 	break;
    363     case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
    364 	cipherName = "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
    365 	paramsNeeded = 1;
    366 	break;
    367     case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
    368 	cipherName = "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
    369 	paramsNeeded = 1;
    370 	break;
    371     case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
    372 	cipherName = "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
    373 	paramsNeeded = 1;
    374 	break;
    375     case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
    376 	cipherName = "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
    377 	paramsNeeded = 1;
    378 	break;
    379     case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
    380 	cipherName = "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
    381 	paramsNeeded = 1;
    382 	break;
    383     case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
    384 	cipherName = "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
    385 	paramsNeeded = 1;
    386 	break;
    387     case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
    388 	cipherName = "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
    389 	paramsNeeded = 1;
    390 	break;
    391     case TLS_PSK_WITH_AES_128_GCM_SHA256:
    392 	cipherName = "TLS_PSK_WITH_AES_128_GCM_SHA256";
    393 	break;
    394     case TLS_PSK_WITH_AES_256_GCM_SHA384:
    395 	cipherName = "TLS_PSK_WITH_AES_256_GCM_SHA384";
    396 	break;
    397     case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
    398 	cipherName = "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
    399 	paramsNeeded = 1;
    400 	break;
    401     case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
    402 	cipherName = "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
    403 	paramsNeeded = 1;
    404 	break;
    405     case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
    406 	cipherName = "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
    407 	break;
    408     case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
    409 	cipherName = "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384";
    410 	break;
    411     case TLS_PSK_WITH_AES_128_CBC_SHA256:
    412 	cipherName = "TLS_PSK_WITH_AES_128_CBC_SHA256";
    413 	break;
    414     case TLS_PSK_WITH_AES_256_CBC_SHA384:
    415 	cipherName = "TLS_PSK_WITH_AES_256_CBC_SHA384";
    416 	break;
    417     case TLS_PSK_WITH_NULL_SHA256:
    418 	cipherName = "TLS_PSK_WITH_NULL_SHA256";
    419 	break;
    420     case TLS_PSK_WITH_NULL_SHA384:
    421 	cipherName = "TLS_PSK_WITH_NULL_SHA384";
    422 	break;
    423     case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
    424 	cipherName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
    425 	paramsNeeded = 1;
    426 	break;
    427     case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
    428 	cipherName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
    429 	paramsNeeded = 1;
    430 	break;
    431     case TLS_DHE_PSK_WITH_NULL_SHA256:
    432 	cipherName = "TLS_DHE_PSK_WITH_NULL_SHA256";
    433 	paramsNeeded = 1;
    434 	break;
    435     case TLS_DHE_PSK_WITH_NULL_SHA384:
    436 	cipherName = "TLS_DHE_PSK_WITH_NULL_SHA384";
    437 	paramsNeeded = 1;
    438 	break;
    439     case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
    440 	cipherName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
    441 	break;
    442     case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
    443 	cipherName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
    444 	break;
    445     case TLS_RSA_PSK_WITH_NULL_SHA256:
    446 	cipherName = "TLS_RSA_PSK_WITH_NULL_SHA256";
    447 	break;
    448     case TLS_RSA_PSK_WITH_NULL_SHA384:
    449 	cipherName = "TLS_RSA_PSK_WITH_NULL_SHA384";
    450 	break;
    451     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
    452 	cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
    453 	paramsNeeded = 1;
    454 	break;
    455     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
    456 	cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
    457 	paramsNeeded = 1;
    458 	break;
    459     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
    460 	cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
    461 	paramsNeeded = 1;
    462 	break;
    463     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
    464 	cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
    465 	paramsNeeded = 1;
    466 	break;
    467     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
    468 	cipherName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
    469 	paramsNeeded = 1;
    470 	break;
    471     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
    472 	cipherName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
    473 	paramsNeeded = 1;
    474 	break;
    475     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
    476 	cipherName = "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
    477 	paramsNeeded = 1;
    478 	break;
    479     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
    480 	cipherName = "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
    481 	paramsNeeded = 1;
    482 	break;
    483     case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
    484 	cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
    485 	paramsNeeded = 1;
    486 	break;
    487     case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
    488 	cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
    489 	paramsNeeded = 1;
    490 	break;
    491     case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
    492 	cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
    493 	paramsNeeded = 1;
    494 	break;
    495     case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
    496 	cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
    497 	paramsNeeded = 1;
    498 	break;
    499     case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
    500 	cipherName = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
    501 	paramsNeeded = 1;
    502 	break;
    503     case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
    504 	cipherName = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
    505 	paramsNeeded = 1;
    506 	break;
    507     case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
    508 	cipherName = "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
    509 	paramsNeeded = 1;
    510 	break;
    511     case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
    512 	cipherName = "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
    513 	paramsNeeded = 1;
    514 	break;
    515     case TLS_RSA_WITH_AES_128_CBC_SHA:
    516 	cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA";
    517 	break;
    518     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
    519 	cipherName = "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
    520 	paramsNeeded = 1;
    521 	break;
    522     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
    523 	cipherName = "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
    524 	paramsNeeded = 1;
    525 	break;
    526     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
    527 	cipherName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
    528 	paramsNeeded = 1;
    529 	break;
    530     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
    531 	cipherName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
    532 	paramsNeeded = 1;
    533 	break;
    534     case TLS_DH_anon_WITH_AES_128_CBC_SHA:
    535 	cipherName = "TLS_DH_anon_WITH_AES_128_CBC_SHA";
    536 	paramsNeeded = 1;
    537 	break;
    538     case TLS_RSA_WITH_AES_256_CBC_SHA:
    539 	cipherName = "TLS_RSA_WITH_AES_256_CBC_SHA";
    540 	break;
    541     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
    542 	cipherName = "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
    543 	paramsNeeded = 1;
    544 	break;
    545     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
    546 	cipherName = "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
    547 	paramsNeeded = 1;
    548 	break;
    549     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
    550 	cipherName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
    551 	paramsNeeded = 1;
    552 	break;
    553     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
    554 	cipherName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
    555 	paramsNeeded = 1;
    556 	break;
    557     case TLS_DH_anon_WITH_AES_256_CBC_SHA:
    558 	cipherName = "TLS_DH_anon_WITH_AES_256_CBC_SHA";
    559 	paramsNeeded = 1;
    560 	break;
    561     case TLS_ECDH_ECDSA_WITH_NULL_SHA:
    562 	cipherName = "TLS_ECDH_ECDSA_WITH_NULL_SHA";
    563 	paramsNeeded = 1;
    564 	break;
    565     case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
    566 	cipherName = "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
    567 	paramsNeeded = 1;
    568 	break;
    569     case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
    570 	cipherName = "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
    571 	paramsNeeded = 1;
    572 	break;
    573     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
    574 	cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
    575 	paramsNeeded = 1;
    576 	break;
    577     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
    578 	cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
    579 	paramsNeeded = 1;
    580 	break;
    581     case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
    582 	cipherName = "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
    583 	paramsNeeded = 1;
    584 	break;
    585     case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
    586 	cipherName = "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
    587 	paramsNeeded = 1;
    588 	break;
    589     case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
    590 	cipherName = "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
    591 	paramsNeeded = 1;
    592 	break;
    593     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
    594 	cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
    595 	paramsNeeded = 1;
    596 	break;
    597     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
    598 	cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
    599 	paramsNeeded = 1;
    600 	break;
    601     case TLS_ECDH_RSA_WITH_NULL_SHA:
    602 	cipherName = "TLS_ECDH_RSA_WITH_NULL_SHA";
    603 	paramsNeeded = 1;
    604 	break;
    605     case TLS_ECDH_RSA_WITH_RC4_128_SHA:
    606 	cipherName = "TLS_ECDH_RSA_WITH_RC4_128_SHA";
    607 	paramsNeeded = 1;
    608 	break;
    609     case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
    610 	cipherName = "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
    611 	paramsNeeded = 1;
    612 	break;
    613     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
    614 	cipherName = "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
    615 	paramsNeeded = 1;
    616 	break;
    617     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
    618 	cipherName = "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
    619 	paramsNeeded = 1;
    620 	break;
    621     case TLS_ECDHE_RSA_WITH_NULL_SHA:
    622 	cipherName = "TLS_ECDHE_RSA_WITH_NULL_SHA";
    623 	paramsNeeded = 1;
    624 	break;
    625     case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
    626 	cipherName = "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
    627 	paramsNeeded = 1;
    628 	break;
    629     case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
    630 	cipherName = "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
    631 	paramsNeeded = 1;
    632 	break;
    633     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
    634 	cipherName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
    635 	paramsNeeded = 1;
    636 	break;
    637     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
    638 	cipherName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
    639 	paramsNeeded = 1;
    640 	break;
    641     case TLS_ECDH_anon_WITH_NULL_SHA:
    642 	cipherName = "TLS_ECDH_anon_WITH_NULL_SHA";
    643 	paramsNeeded = 1;
    644 	break;
    645     case TLS_ECDH_anon_WITH_RC4_128_SHA:
    646 	cipherName = "TLS_ECDH_anon_WITH_RC4_128_SHA";
    647 	paramsNeeded = 1;
    648 	break;
    649     case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
    650 	cipherName = "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
    651 	paramsNeeded = 1;
    652 	break;
    653     case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
    654 	cipherName = "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
    655 	paramsNeeded = 1;
    656 	break;
    657     case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
    658 	cipherName = "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
    659 	paramsNeeded = 1;
    660 	break;
    661     default :
    662         snprintf(unknownCipherName, sizeof(unknownCipherName), "UNKNOWN_%04X", cipher);
    663         cipherName = unknownCipherName;
    664         break;
    665   }
    666 
    667   if (cipher == TLS_RSA_WITH_RC4_128_MD5 ||
    668       cipher == TLS_RSA_WITH_RC4_128_SHA)
    669   {
    670     printf("%s: ERROR (Printers MUST NOT negotiate RC4 cipher suites.)\n", server);
    671     httpClose(http);
    672     return (1);
    673   }
    674 
    675   if ((err = SSLGetDiffieHellmanParams(http->tls, &params, &paramsLen)) != noErr && paramsNeeded)
    676   {
    677     printf("%s: ERROR (Unable to get Diffie-Hellman parameters - %d)\n", server, (int)err);
    678     httpClose(http);
    679     return (1);
    680   }
    681 
    682   if (paramsLen < 128 && paramsLen != 0)
    683   {
    684     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);
    685     httpClose(http);
    686     return (1);
    687   }
    688 
    689   dhBits = (int)paramsLen * 8;
    690 #endif /* __APPLE__ */
    691 
    692   if (dhBits > 0)
    693     printf("%s: OK (TLS: %d.%d, %s, %d DH bits)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName, dhBits);
    694   else
    695     printf("%s: OK (TLS: %d.%d, %s)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName);
    696 
    697   if (verbose)
    698   {
    699     httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipps", NULL, host, port, resource);
    700     request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
    701     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
    702     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
    703     ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);
    704 
    705     response = cupsDoRequest(http, request, resource);
    706 
    707     for (attr = ippFirstAttribute(response); attr; attr = ippNextAttribute(response))
    708     {
    709       if (ippGetGroupTag(attr) != IPP_TAG_PRINTER)
    710         continue;
    711 
    712       if ((name = ippGetName(attr)) == NULL)
    713         continue;
    714 
    715       ippAttributeString(attr, value, sizeof(value));
    716       printf("    %s=%s\n", name, value);
    717     }
    718 
    719     ippDelete(response);
    720   }
    721 
    722   httpClose(http);
    723 
    724   return (0);
    725 }
    726 
    727 
    728 /*
    729  * 'usage()' - Show program usage.
    730  */
    731 
    732 static void
    733 usage(void)
    734 {
    735   puts("Usage: ./tlscheck [options] server [port]");
    736   puts("       ./tlscheck [options] ipps://server[:port]/path");
    737   puts("");
    738   puts("Options:");
    739   puts("  --dh        Allow DH/DHE key exchange");
    740   puts("  --no-cbc    Disable CBC cipher suites");
    741   puts("  --no-tls10  Disable TLS/1.0");
    742   puts("  --rc4       Allow RC4 encryption");
    743   puts("  --tls10     Only use TLS/1.0");
    744   puts("  --verbose   Be verbose");
    745   puts("  -4          Connect using IPv4 addresses only");
    746   puts("  -6          Connect using IPv6 addresses only");
    747   puts("  -v          Be verbose");
    748   puts("");
    749   puts("The default port is 631.");
    750 
    751   exit(1);
    752 }
    753 #endif /* !HAVE_SSL */
    754