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