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
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 		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
usage(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