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