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