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