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