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