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