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