diff options
author | inoguchi <> | 2020-07-09 12:48:19 +0000 |
---|---|---|
committer | inoguchi <> | 2020-07-09 12:48:19 +0000 |
commit | 9edc96590efc611f43d91f100128253e9b3033b7 (patch) | |
tree | d5e4834cbf40384cbb8d61db3b872806bfa93a7b /src/usr.bin/openssl/s_client.c | |
parent | 52b64c85919c83f37c06ee740395852d6d5da007 (diff) | |
download | openbsd-9edc96590efc611f43d91f100128253e9b3033b7.tar.gz openbsd-9edc96590efc611f43d91f100128253e9b3033b7.tar.bz2 openbsd-9edc96590efc611f43d91f100128253e9b3033b7.zip |
Convert openssl(1) s_client option handling
suggestions and ok beck@ jsing@ tb@
Diffstat (limited to 'src/usr.bin/openssl/s_client.c')
-rw-r--r-- | src/usr.bin/openssl/s_client.c | 1220 |
1 files changed, 770 insertions, 450 deletions
diff --git a/src/usr.bin/openssl/s_client.c b/src/usr.bin/openssl/s_client.c index cc886b11e6..2b47bf7ff9 100644 --- a/src/usr.bin/openssl/s_client.c +++ b/src/usr.bin/openssl/s_client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s_client.c,v 1.46 2020/05/23 12:52:54 tb Exp $ */ | 1 | /* $OpenBSD: s_client.c,v 1.47 2020/07/09 12:48:19 inoguchi Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -170,87 +170,674 @@ | |||
170 | 170 | ||
171 | #define BUFSIZZ 1024*8 | 171 | #define BUFSIZZ 1024*8 |
172 | 172 | ||
173 | static int c_nbio = 0; | ||
174 | static int c_Pause = 0; | ||
175 | static int c_debug = 0; | ||
176 | static int c_tlsextdebug = 0; | ||
177 | static int c_status_req = 0; | ||
178 | static int c_msg = 0; | ||
179 | static int c_showcerts = 0; | ||
180 | |||
181 | static char *keymatexportlabel = NULL; | ||
182 | static int keymatexportlen = 20; | ||
183 | |||
184 | static void sc_usage(void); | 173 | static void sc_usage(void); |
185 | static void print_stuff(BIO * berr, SSL * con, int full); | 174 | static void print_stuff(BIO * berr, SSL * con, int full); |
186 | static int ocsp_resp_cb(SSL * s, void *arg); | 175 | static int ocsp_resp_cb(SSL * s, void *arg); |
187 | static BIO *bio_c_out = NULL; | 176 | static BIO *bio_c_out = NULL; |
188 | static int c_quiet = 0; | ||
189 | static int c_ign_eof = 0; | ||
190 | 177 | ||
178 | enum { | ||
179 | PROTO_OFF = 0, | ||
180 | PROTO_SMTP, | ||
181 | PROTO_LMTP, | ||
182 | PROTO_POP3, | ||
183 | PROTO_IMAP, | ||
184 | PROTO_FTP, | ||
185 | PROTO_XMPP, | ||
186 | }; | ||
191 | 187 | ||
192 | static void | 188 | static struct { |
193 | sc_usage(void) | 189 | int af; |
190 | char *alpn_in; | ||
191 | int bugs; | ||
192 | char *CAfile; | ||
193 | char *CApath; | ||
194 | int c_debug; | ||
195 | int c_ign_eof; | ||
196 | int c_msg; | ||
197 | int c_nbio; | ||
198 | int c_Pause; | ||
199 | int c_quiet; | ||
200 | int c_showcerts; | ||
201 | int c_status_req; | ||
202 | int c_tlsextdebug; | ||
203 | char *cert_file; | ||
204 | int cert_format; | ||
205 | char *cipher; | ||
206 | unsigned int clr; | ||
207 | char *connect; | ||
208 | int crlf; | ||
209 | int enable_timeouts; | ||
210 | const char *errstr; | ||
211 | char *groups_in; | ||
212 | char *host; | ||
213 | char *key_file; | ||
214 | int key_format; | ||
215 | char *keymatexportlabel; | ||
216 | int keymatexportlen; | ||
217 | uint16_t max_version; | ||
218 | uint16_t min_version; | ||
219 | const SSL_METHOD *meth; | ||
220 | int nbio_test; | ||
221 | char *npn_in; | ||
222 | unsigned int off; | ||
223 | char *passarg; | ||
224 | int peekaboo; | ||
225 | char *port; | ||
226 | int prexit; | ||
227 | char *proxy; | ||
228 | int reconnect; | ||
229 | char *servername; | ||
230 | char *sess_in; | ||
231 | char *sess_out; | ||
232 | int socket_type; | ||
233 | long socket_mtu; | ||
234 | #ifndef OPENSSL_NO_SRTP | ||
235 | char *srtp_profiles; | ||
236 | #endif | ||
237 | int starttls_proto; | ||
238 | int state; | ||
239 | int verify; | ||
240 | X509_VERIFY_PARAM *vpm; | ||
241 | char *xmpphost; | ||
242 | } s_client_config; | ||
243 | |||
244 | static int | ||
245 | s_client_opt_keymatexportlen(char *arg) | ||
194 | { | 246 | { |
195 | BIO_printf(bio_err, "usage: s_client args\n"); | 247 | s_client_config.keymatexportlen = strtonum(arg, 1, INT_MAX, |
196 | BIO_printf(bio_err, "\n"); | 248 | &s_client_config.errstr); |
197 | BIO_printf(bio_err, " -4 - Force IPv4\n"); | 249 | if (s_client_config.errstr != NULL) { |
198 | BIO_printf(bio_err, " -6 - Force IPv6\n"); | 250 | BIO_printf(bio_err, "invalid argument %s: %s\n", |
199 | BIO_printf(bio_err, " -host host - use -connect instead\n"); | 251 | arg, s_client_config.errstr); |
200 | BIO_printf(bio_err, " -port port - use -connect instead\n"); | 252 | return (1); |
201 | BIO_printf(bio_err, " -connect host:port - who to connect to (default is %s:%s)\n", SSL_HOST_NAME, PORT_STR); | 253 | } |
202 | BIO_printf(bio_err, " -proxy host:port - connect to http proxy\n"); | 254 | return (0); |
203 | 255 | } | |
204 | BIO_printf(bio_err, " -verify arg - turn on peer certificate verification\n"); | 256 | |
205 | BIO_printf(bio_err, " -cert arg - certificate file to use, PEM format assumed\n"); | 257 | #ifndef OPENSSL_NO_DTLS1 |
206 | BIO_printf(bio_err, " -certform arg - certificate format (PEM or DER) PEM default\n"); | 258 | static int |
207 | BIO_printf(bio_err, " -key arg - Private key file to use, in cert file if\n"); | 259 | s_client_opt_mtu(char *arg) |
208 | BIO_printf(bio_err, " not specified but cert file is.\n"); | 260 | { |
209 | BIO_printf(bio_err, " -keyform arg - key format (PEM or DER) PEM default\n"); | 261 | s_client_config.socket_mtu = strtonum(arg, 0, LONG_MAX, |
210 | BIO_printf(bio_err, " -pass arg - private key file pass phrase source\n"); | 262 | &s_client_config.errstr); |
211 | BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); | 263 | if (s_client_config.errstr != NULL) { |
212 | BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); | 264 | BIO_printf(bio_err, "invalid argument %s: %s\n", |
213 | BIO_printf(bio_err, " -reconnect - Drop and re-make the connection with the same Session-ID\n"); | 265 | arg, s_client_config.errstr); |
214 | BIO_printf(bio_err, " -pause - sleep(1) after each read(2) and write(2) system call\n"); | 266 | return (1); |
215 | BIO_printf(bio_err, " -showcerts - show all certificates in the chain\n"); | 267 | } |
216 | BIO_printf(bio_err, " -debug - extra output\n"); | 268 | return (0); |
217 | BIO_printf(bio_err, " -msg - Show protocol messages\n"); | 269 | } |
218 | BIO_printf(bio_err, " -nbio_test - more ssl protocol testing\n"); | 270 | #endif |
219 | BIO_printf(bio_err, " -state - print the 'ssl' states\n"); | 271 | |
220 | BIO_printf(bio_err, " -nbio - Run with non-blocking IO\n"); | 272 | static int |
221 | BIO_printf(bio_err, " -crlf - convert LF from terminal into CRLF\n"); | 273 | s_client_opt_port(char *arg) |
222 | BIO_printf(bio_err, " -quiet - no s_client output\n"); | 274 | { |
223 | BIO_printf(bio_err, " -ign_eof - ignore input eof (default when -quiet)\n"); | 275 | if (*arg == '\0') |
224 | BIO_printf(bio_err, " -no_ign_eof - don't ignore input eof\n"); | 276 | return (1); |
225 | BIO_printf(bio_err, " -tls1_3 - just use TLSv1.3\n"); | 277 | |
226 | BIO_printf(bio_err, " -tls1_2 - just use TLSv1.2\n"); | 278 | s_client_config.port = arg; |
227 | BIO_printf(bio_err, " -tls1_1 - just use TLSv1.1\n"); | 279 | return (0); |
228 | BIO_printf(bio_err, " -tls1 - just use TLSv1\n"); | 280 | } |
229 | BIO_printf(bio_err, " -dtls1 - just use DTLSv1\n"); | 281 | |
230 | BIO_printf(bio_err, " -mtu - set the link layer MTU\n"); | 282 | #ifndef OPENSSL_NO_DTLS1 |
231 | BIO_printf(bio_err, " -no_tls1_3/-no_tls1_2/-no_tls1_1/-no_tls1 - turn off that protocol\n"); | 283 | static int |
232 | BIO_printf(bio_err, " -bugs - Switch on all SSL implementation bug workarounds\n"); | 284 | s_client_opt_protocol_version_dtls1(void) |
233 | BIO_printf(bio_err, " -cipher - preferred cipher to use, use the 'openssl ciphers'\n"); | 285 | { |
234 | BIO_printf(bio_err, " command to see what is available\n"); | 286 | s_client_config.meth = DTLS_client_method(); |
235 | BIO_printf(bio_err, " -starttls prot - use the STARTTLS command before starting TLS\n"); | 287 | s_client_config.socket_type = SOCK_DGRAM; |
236 | BIO_printf(bio_err, " for those protocols that support it, where\n"); | 288 | return (0); |
237 | BIO_printf(bio_err, " 'prot' defines which one to assume. Currently,\n"); | 289 | } |
238 | BIO_printf(bio_err, " only \"smtp\", \"lmtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n"); | 290 | #endif |
239 | BIO_printf(bio_err, " are supported.\n"); | 291 | |
240 | BIO_printf(bio_err, " -xmpphost host - connect to this virtual host on the xmpp server\n"); | 292 | static int |
241 | BIO_printf(bio_err, " -sess_out arg - file to write SSL session to\n"); | 293 | s_client_opt_protocol_version_tls1(void) |
242 | BIO_printf(bio_err, " -sess_in arg - file to read SSL session from\n"); | 294 | { |
243 | BIO_printf(bio_err, " -servername host - Set TLS extension servername in ClientHello\n"); | 295 | s_client_config.min_version = TLS1_VERSION; |
244 | BIO_printf(bio_err, " -tlsextdebug - hex dump of all TLS extensions received\n"); | 296 | s_client_config.max_version = TLS1_VERSION; |
245 | BIO_printf(bio_err, " -status - request certificate status from server\n"); | 297 | return (0); |
246 | BIO_printf(bio_err, " -no_ticket - disable use of RFC4507bis session tickets\n"); | 298 | } |
247 | BIO_printf(bio_err, " -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n"); | 299 | |
248 | BIO_printf(bio_err, " -groups arg - specify EC groups (colon-separated list)\n"); | 300 | static int |
301 | s_client_opt_protocol_version_tls1_1(void) | ||
302 | { | ||
303 | s_client_config.min_version = TLS1_1_VERSION; | ||
304 | s_client_config.max_version = TLS1_1_VERSION; | ||
305 | return (0); | ||
306 | } | ||
307 | |||
308 | static int | ||
309 | s_client_opt_protocol_version_tls1_2(void) | ||
310 | { | ||
311 | s_client_config.min_version = TLS1_2_VERSION; | ||
312 | s_client_config.max_version = TLS1_2_VERSION; | ||
313 | return (0); | ||
314 | } | ||
315 | |||
316 | static int | ||
317 | s_client_opt_protocol_version_tls1_3(void) | ||
318 | { | ||
319 | s_client_config.min_version = TLS1_3_VERSION; | ||
320 | s_client_config.max_version = TLS1_3_VERSION; | ||
321 | return (0); | ||
322 | } | ||
323 | |||
324 | static int | ||
325 | s_client_opt_quiet(void) | ||
326 | { | ||
327 | s_client_config.c_quiet = 1; | ||
328 | s_client_config.c_ign_eof = 1; | ||
329 | return (0); | ||
330 | } | ||
331 | |||
332 | static int | ||
333 | s_client_opt_starttls(char *arg) | ||
334 | { | ||
335 | if (strcmp(arg, "smtp") == 0) | ||
336 | s_client_config.starttls_proto = PROTO_SMTP; | ||
337 | else if (strcmp(arg, "lmtp") == 0) | ||
338 | s_client_config.starttls_proto = PROTO_LMTP; | ||
339 | else if (strcmp(arg, "pop3") == 0) | ||
340 | s_client_config.starttls_proto = PROTO_POP3; | ||
341 | else if (strcmp(arg, "imap") == 0) | ||
342 | s_client_config.starttls_proto = PROTO_IMAP; | ||
343 | else if (strcmp(arg, "ftp") == 0) | ||
344 | s_client_config.starttls_proto = PROTO_FTP; | ||
345 | else if (strcmp(arg, "xmpp") == 0) | ||
346 | s_client_config.starttls_proto = PROTO_XMPP; | ||
347 | else | ||
348 | return (1); | ||
349 | return (0); | ||
350 | } | ||
351 | |||
352 | static int | ||
353 | s_client_opt_verify(char *arg) | ||
354 | { | ||
355 | s_client_config.verify = SSL_VERIFY_PEER; | ||
356 | |||
357 | verify_depth = strtonum(arg, 0, INT_MAX, &s_client_config.errstr); | ||
358 | if (s_client_config.errstr != NULL) { | ||
359 | BIO_printf(bio_err, "invalid argument %s: %s\n", | ||
360 | arg, s_client_config.errstr); | ||
361 | return (1); | ||
362 | } | ||
363 | BIO_printf(bio_err, "verify depth is %d\n", verify_depth); | ||
364 | return (0); | ||
365 | } | ||
366 | |||
367 | static int | ||
368 | s_client_opt_verify_param(int argc, char **argv, int *argsused) | ||
369 | { | ||
370 | char **pargs = argv; | ||
371 | int pargc = argc; | ||
372 | int badarg = 0; | ||
373 | |||
374 | if (!args_verify(&pargs, &pargc, &badarg, bio_err, | ||
375 | &s_client_config.vpm)) { | ||
376 | BIO_printf(bio_err, "unknown option %s\n", *argv); | ||
377 | return (1); | ||
378 | } | ||
379 | if (badarg) | ||
380 | return (1); | ||
381 | |||
382 | *argsused = argc - pargc; | ||
383 | return (0); | ||
384 | } | ||
385 | |||
386 | static const struct option s_client_options[] = { | ||
387 | { | ||
388 | .name = "4", | ||
389 | .desc = "Use IPv4 only", | ||
390 | .type = OPTION_VALUE, | ||
391 | .opt.value = &s_client_config.af, | ||
392 | .value = AF_INET, | ||
393 | }, | ||
394 | { | ||
395 | .name = "6", | ||
396 | .desc = "Use IPv6 only", | ||
397 | .type = OPTION_VALUE, | ||
398 | .opt.value = &s_client_config.af, | ||
399 | .value = AF_INET6, | ||
400 | }, | ||
401 | { | ||
402 | .name = "alpn", | ||
403 | .argname = "protocols", | ||
404 | .desc = "Set the advertised protocols for ALPN" | ||
405 | " (comma-separated list)", | ||
406 | .type = OPTION_ARG, | ||
407 | .opt.arg = &s_client_config.alpn_in, | ||
408 | }, | ||
409 | { | ||
410 | .name = "bugs", | ||
411 | .desc = "Enable various workarounds for buggy implementations", | ||
412 | .type = OPTION_FLAG, | ||
413 | .opt.flag = &s_client_config.bugs, | ||
414 | }, | ||
415 | { | ||
416 | .name = "CAfile", | ||
417 | .argname = "file", | ||
418 | .desc = "PEM format file of CA certificates", | ||
419 | .type = OPTION_ARG, | ||
420 | .opt.arg = &s_client_config.CAfile, | ||
421 | }, | ||
422 | { | ||
423 | .name = "CApath", | ||
424 | .argname = "directory", | ||
425 | .desc = "PEM format directory of CA certificates", | ||
426 | .type = OPTION_ARG, | ||
427 | .opt.arg = &s_client_config.CApath, | ||
428 | }, | ||
429 | { | ||
430 | .name = "cert", | ||
431 | .argname = "file", | ||
432 | .desc = "Certificate file to use, PEM format assumed", | ||
433 | .type = OPTION_ARG, | ||
434 | .opt.arg = &s_client_config.cert_file, | ||
435 | }, | ||
436 | { | ||
437 | .name = "certform", | ||
438 | .argname = "fmt", | ||
439 | .desc = "Certificate format (PEM or DER) PEM default", | ||
440 | .type = OPTION_ARG_FORMAT, | ||
441 | .opt.value = &s_client_config.cert_format, | ||
442 | }, | ||
443 | { | ||
444 | .name = "cipher", | ||
445 | .argname = "cipherlist", | ||
446 | .desc = "Preferred cipher to use (see 'openssl ciphers')", | ||
447 | .type = OPTION_ARG, | ||
448 | .opt.arg = &s_client_config.cipher, | ||
449 | }, | ||
450 | { | ||
451 | .name = "connect", | ||
452 | .argname = "host:port", | ||
453 | .desc = "Who to connect to (default is localhost:4433)", | ||
454 | .type = OPTION_ARG, | ||
455 | .opt.arg = &s_client_config.connect, | ||
456 | }, | ||
457 | { | ||
458 | .name = "crlf", | ||
459 | .desc = "Convert LF from terminal into CRLF", | ||
460 | .type = OPTION_FLAG, | ||
461 | .opt.flag = &s_client_config.crlf, | ||
462 | }, | ||
463 | { | ||
464 | .name = "debug", | ||
465 | .desc = "Print extensive debugging information", | ||
466 | .type = OPTION_FLAG, | ||
467 | .opt.flag = &s_client_config.c_debug, | ||
468 | }, | ||
469 | #ifndef OPENSSL_NO_DTLS1 | ||
470 | { | ||
471 | .name = "dtls1", | ||
472 | .desc = "Just use DTLSv1", | ||
473 | .type = OPTION_FUNC, | ||
474 | .opt.func = s_client_opt_protocol_version_dtls1, | ||
475 | }, | ||
476 | #endif | ||
477 | { | ||
478 | .name = "groups", | ||
479 | .argname = "list", | ||
480 | .desc = "Specify EC groups (colon-separated list)", | ||
481 | .type = OPTION_ARG, | ||
482 | .opt.arg = &s_client_config.groups_in, | ||
483 | }, | ||
484 | { | ||
485 | .name = "host", | ||
486 | .argname = "host", | ||
487 | .desc = "Use -connect instead", | ||
488 | .type = OPTION_ARG, | ||
489 | .opt.arg = &s_client_config.host, | ||
490 | }, | ||
491 | { | ||
492 | .name = "ign_eof", | ||
493 | .desc = "Ignore input EOF (default when -quiet)", | ||
494 | .type = OPTION_VALUE, | ||
495 | .opt.value = &s_client_config.c_ign_eof, | ||
496 | .value = 1, | ||
497 | }, | ||
498 | { | ||
499 | .name = "key", | ||
500 | .argname = "file", | ||
501 | .desc = "Private key file to use, if not, -cert file is used", | ||
502 | .type = OPTION_ARG, | ||
503 | .opt.arg = &s_client_config.key_file, | ||
504 | }, | ||
505 | { | ||
506 | .name = "keyform", | ||
507 | .argname = "fmt", | ||
508 | .desc = "Key format (PEM or DER) PEM default", | ||
509 | .type = OPTION_ARG_FORMAT, | ||
510 | .opt.value = &s_client_config.key_format, | ||
511 | }, | ||
512 | { | ||
513 | .name = "keymatexport", | ||
514 | .argname = "label", | ||
515 | .desc = "Export keying material using label", | ||
516 | .type = OPTION_ARG, | ||
517 | .opt.arg = &s_client_config.keymatexportlabel, | ||
518 | }, | ||
519 | { | ||
520 | .name = "keymatexportlen", | ||
521 | .argname = "len", | ||
522 | .desc = "Export len bytes of keying material (default 20)", | ||
523 | .type = OPTION_ARG_FUNC, | ||
524 | .opt.argfunc = s_client_opt_keymatexportlen, | ||
525 | }, | ||
526 | { | ||
527 | .name = "legacy_renegotiation", | ||
528 | .type = OPTION_DISCARD, | ||
529 | }, | ||
530 | { | ||
531 | .name = "legacy_server_connect", | ||
532 | .desc = "Allow initial connection to servers that don't support RI", | ||
533 | .type = OPTION_VALUE_OR, | ||
534 | .opt.value = &s_client_config.off, | ||
535 | .value = SSL_OP_LEGACY_SERVER_CONNECT, | ||
536 | }, | ||
537 | { | ||
538 | .name = "msg", | ||
539 | .desc = "Show all protocol messages with hex dump", | ||
540 | .type = OPTION_FLAG, | ||
541 | .opt.flag = &s_client_config.c_msg, | ||
542 | }, | ||
543 | #ifndef OPENSSL_NO_DTLS1 | ||
544 | { | ||
545 | .name = "mtu", | ||
546 | .argname = "mtu", | ||
547 | .desc = "Set the link layer MTU on DTLS connections", | ||
548 | .type = OPTION_ARG_FUNC, | ||
549 | .opt.argfunc = s_client_opt_mtu, | ||
550 | }, | ||
551 | #endif | ||
552 | { | ||
553 | .name = "nbio", | ||
554 | .desc = "Turn on non-blocking I/O", | ||
555 | .type = OPTION_FLAG, | ||
556 | .opt.flag = &s_client_config.c_nbio, | ||
557 | }, | ||
558 | { | ||
559 | .name = "nbio_test", | ||
560 | .desc = "Test non-blocking I/O", | ||
561 | .type = OPTION_FLAG, | ||
562 | .opt.flag = &s_client_config.nbio_test, | ||
563 | }, | ||
564 | { | ||
565 | .name = "nextprotoneg", | ||
566 | .argname = "protocols", | ||
567 | .type = OPTION_ARG, | ||
568 | .opt.arg = &s_client_config.npn_in, /* Ignored. */ | ||
569 | }, | ||
570 | { | ||
571 | .name = "no_comp", | ||
572 | .type = OPTION_VALUE_OR, | ||
573 | .opt.value = &s_client_config.off, | ||
574 | .value = SSL_OP_NO_COMPRESSION, | ||
575 | }, | ||
576 | { | ||
577 | .name = "no_ign_eof", | ||
578 | .desc = "Don't ignore input EOF", | ||
579 | .type = OPTION_VALUE, | ||
580 | .opt.value = &s_client_config.c_ign_eof, | ||
581 | .value = 0, | ||
582 | }, | ||
583 | { | ||
584 | .name = "no_legacy_server_connect", | ||
585 | .desc = "Disallow initial connection to servers that don't support RI", | ||
586 | .type = OPTION_VALUE_OR, | ||
587 | .opt.value = &s_client_config.clr, | ||
588 | .value = SSL_OP_LEGACY_SERVER_CONNECT, | ||
589 | }, | ||
590 | { | ||
591 | .name = "no_ssl2", | ||
592 | .type = OPTION_VALUE_OR, | ||
593 | .opt.value = &s_client_config.off, | ||
594 | .value = SSL_OP_NO_SSLv2, | ||
595 | }, | ||
596 | { | ||
597 | .name = "no_ssl3", | ||
598 | .type = OPTION_VALUE_OR, | ||
599 | .opt.value = &s_client_config.off, | ||
600 | .value = SSL_OP_NO_SSLv3, | ||
601 | }, | ||
602 | { | ||
603 | .name = "no_ticket", | ||
604 | .desc = "Disable use of RFC4507 session ticket support", | ||
605 | .type = OPTION_VALUE_OR, | ||
606 | .opt.value = &s_client_config.off, | ||
607 | .value = SSL_OP_NO_TICKET, | ||
608 | }, | ||
609 | { | ||
610 | .name = "no_tls1", | ||
611 | .desc = "Disable the use of TLSv1", | ||
612 | .type = OPTION_VALUE_OR, | ||
613 | .opt.value = &s_client_config.off, | ||
614 | .value = SSL_OP_NO_TLSv1, | ||
615 | }, | ||
616 | { | ||
617 | .name = "no_tls1_1", | ||
618 | .desc = "Disable the use of TLSv1.1", | ||
619 | .type = OPTION_VALUE_OR, | ||
620 | .opt.value = &s_client_config.off, | ||
621 | .value = SSL_OP_NO_TLSv1_1, | ||
622 | }, | ||
623 | { | ||
624 | .name = "no_tls1_2", | ||
625 | .desc = "Disable the use of TLSv1.2", | ||
626 | .type = OPTION_VALUE_OR, | ||
627 | .opt.value = &s_client_config.off, | ||
628 | .value = SSL_OP_NO_TLSv1_2, | ||
629 | }, | ||
630 | { | ||
631 | .name = "no_tls1_3", | ||
632 | .desc = "Disable the use of TLSv1.3", | ||
633 | .type = OPTION_VALUE_OR, | ||
634 | .opt.value = &s_client_config.off, | ||
635 | .value = SSL_OP_NO_TLSv1_3, | ||
636 | }, | ||
637 | { | ||
638 | .name = "pass", | ||
639 | .argname = "arg", | ||
640 | .desc = "Private key file pass phrase source", | ||
641 | .type = OPTION_ARG, | ||
642 | .opt.arg = &s_client_config.passarg, | ||
643 | }, | ||
644 | { | ||
645 | .name = "pause", | ||
646 | .desc = "Pause 1 second between each read and write call", | ||
647 | .type = OPTION_FLAG, | ||
648 | .opt.flag = &s_client_config.c_Pause, | ||
649 | }, | ||
650 | { | ||
651 | .name = "peekaboo", | ||
652 | .type = OPTION_FLAG, | ||
653 | .opt.flag = &s_client_config.peekaboo, | ||
654 | }, | ||
655 | { | ||
656 | .name = "port", | ||
657 | .argname = "port", | ||
658 | .desc = "Use -connect instead", | ||
659 | .type = OPTION_ARG_FUNC, | ||
660 | .opt.argfunc = s_client_opt_port, | ||
661 | }, | ||
662 | { | ||
663 | .name = "prexit", | ||
664 | .desc = "Print session information when the program exits", | ||
665 | .type = OPTION_FLAG, | ||
666 | .opt.flag = &s_client_config.prexit, | ||
667 | }, | ||
668 | { | ||
669 | .name = "proxy", | ||
670 | .argname = "host:port", | ||
671 | .desc = "Connect to http proxy", | ||
672 | .type = OPTION_ARG, | ||
673 | .opt.arg = &s_client_config.proxy, | ||
674 | }, | ||
675 | { | ||
676 | .name = "quiet", | ||
677 | .desc = "Inhibit printing of session and certificate info", | ||
678 | .type = OPTION_FUNC, | ||
679 | .opt.func = s_client_opt_quiet, | ||
680 | }, | ||
681 | { | ||
682 | .name = "reconnect", | ||
683 | .desc = "Drop and re-make the connection with the same Session-ID", | ||
684 | .type = OPTION_VALUE, | ||
685 | .opt.value = &s_client_config.reconnect, | ||
686 | .value = 5, | ||
687 | }, | ||
688 | { | ||
689 | .name = "servername", | ||
690 | .argname = "name", | ||
691 | .desc = "Set TLS extension servername in ClientHello (SNI)", | ||
692 | .type = OPTION_ARG, | ||
693 | .opt.arg = &s_client_config.servername, | ||
694 | }, | ||
695 | { | ||
696 | .name = "serverpref", | ||
697 | .desc = "Use server's cipher preferences", | ||
698 | .type = OPTION_VALUE_OR, | ||
699 | .opt.value = &s_client_config.off, | ||
700 | .value = SSL_OP_CIPHER_SERVER_PREFERENCE, | ||
701 | }, | ||
702 | { | ||
703 | .name = "sess_in", | ||
704 | .argname = "file", | ||
705 | .desc = "File to read TLS session from", | ||
706 | .type = OPTION_ARG, | ||
707 | .opt.arg = &s_client_config.sess_in, | ||
708 | }, | ||
709 | { | ||
710 | .name = "sess_out", | ||
711 | .argname = "file", | ||
712 | .desc = "File to write TLS session to", | ||
713 | .type = OPTION_ARG, | ||
714 | .opt.arg = &s_client_config.sess_out, | ||
715 | }, | ||
716 | { | ||
717 | .name = "showcerts", | ||
718 | .desc = "Show all server certificates in the chain", | ||
719 | .type = OPTION_FLAG, | ||
720 | .opt.flag = &s_client_config.c_showcerts, | ||
721 | }, | ||
722 | { | ||
723 | .name = "starttls", | ||
724 | .argname = "protocol", | ||
725 | .desc = "Use the STARTTLS command before starting TLS,\n" | ||
726 | "smtp, lmtp, pop3, imap, ftp and xmpp are supported.", | ||
727 | .type = OPTION_ARG_FUNC, | ||
728 | .opt.argfunc = s_client_opt_starttls, | ||
729 | }, | ||
730 | { | ||
731 | .name = "state", | ||
732 | .desc = "Print the TLS session states", | ||
733 | .type = OPTION_FLAG, | ||
734 | .opt.flag = &s_client_config.state, | ||
735 | }, | ||
736 | { | ||
737 | .name = "status", | ||
738 | .desc = "Send a certificate status request to the server (OCSP)", | ||
739 | .type = OPTION_FLAG, | ||
740 | .opt.flag = &s_client_config.c_status_req, | ||
741 | }, | ||
742 | #ifndef OPENSSL_NO_DTLS1 | ||
743 | { | ||
744 | .name = "timeout", | ||
745 | .desc = "Enable send/receive timeout on DTLS connections", | ||
746 | .type = OPTION_FLAG, | ||
747 | .opt.flag = &s_client_config.enable_timeouts, | ||
748 | }, | ||
749 | #endif | ||
750 | { | ||
751 | .name = "tls1", | ||
752 | .desc = "Just use TLSv1", | ||
753 | .type = OPTION_FUNC, | ||
754 | .opt.func = s_client_opt_protocol_version_tls1, | ||
755 | }, | ||
756 | { | ||
757 | .name = "tls1_1", | ||
758 | .desc = "Just use TLSv1.1", | ||
759 | .type = OPTION_FUNC, | ||
760 | .opt.func = s_client_opt_protocol_version_tls1_1, | ||
761 | }, | ||
762 | { | ||
763 | .name = "tls1_2", | ||
764 | .desc = "Just use TLSv1.2", | ||
765 | .type = OPTION_FUNC, | ||
766 | .opt.func = s_client_opt_protocol_version_tls1_2, | ||
767 | }, | ||
768 | { | ||
769 | .name = "tls1_3", | ||
770 | .desc = "Just use TLSv1.3", | ||
771 | .type = OPTION_FUNC, | ||
772 | .opt.func = s_client_opt_protocol_version_tls1_3, | ||
773 | }, | ||
774 | { | ||
775 | .name = "tlsextdebug", | ||
776 | .desc = "Hex dump of all TLS extensions received", | ||
777 | .type = OPTION_FLAG, | ||
778 | .opt.flag = &s_client_config.c_tlsextdebug, | ||
779 | }, | ||
249 | #ifndef OPENSSL_NO_SRTP | 780 | #ifndef OPENSSL_NO_SRTP |
250 | BIO_printf(bio_err, " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); | 781 | { |
782 | .name = "use_srtp", | ||
783 | .argname = "profiles", | ||
784 | .desc = "Offer SRTP key management with a colon-separated profiles", | ||
785 | .type = OPTION_ARG, | ||
786 | .opt.arg = &s_client_config.srtp_profiles, | ||
787 | }, | ||
251 | #endif | 788 | #endif |
252 | BIO_printf(bio_err, " -keymatexport label - Export keying material using label\n"); | 789 | { |
253 | BIO_printf(bio_err, " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); | 790 | .name = "verify", |
791 | .argname = "depth", | ||
792 | .desc = "Turn on peer certificate verification, with a max of depth", | ||
793 | .type = OPTION_ARG_FUNC, | ||
794 | .opt.argfunc = s_client_opt_verify, | ||
795 | }, | ||
796 | { | ||
797 | .name = "verify_return_error", | ||
798 | .desc = "Return verification error", | ||
799 | .type = OPTION_FLAG, | ||
800 | .opt.flag = &verify_return_error, | ||
801 | }, | ||
802 | { | ||
803 | .name = "xmpphost", | ||
804 | .argname = "host", | ||
805 | .desc = "Connect to this virtual host on the xmpp server", | ||
806 | .type = OPTION_ARG, | ||
807 | .opt.arg = &s_client_config.xmpphost, | ||
808 | }, | ||
809 | { | ||
810 | .name = NULL, | ||
811 | .desc = "", | ||
812 | .type = OPTION_ARGV_FUNC, | ||
813 | .opt.argvfunc = s_client_opt_verify_param, | ||
814 | }, | ||
815 | { NULL }, | ||
816 | }; | ||
817 | |||
818 | static void | ||
819 | sc_usage(void) | ||
820 | { | ||
821 | fprintf(stderr, "usage: s_client " | ||
822 | "[-4 | -6] [-alpn protocols] [-bugs] [-CAfile file]\n" | ||
823 | " [-CApath directory] [-cert file] [-certform der | pem] [-check_ss_sig]\n" | ||
824 | " [-cipher cipherlist] [-connect host[:port]] [-crl_check]\n" | ||
825 | " [-crl_check_all] [-crlf] [-debug] [-dtls1] [-extended_crl]\n" | ||
826 | " [-groups list] [-host host] [-ign_eof] [-ignore_critical]\n" | ||
827 | " [-issuer_checks] [-key keyfile] [-keyform der | pem]\n" | ||
828 | " [-keymatexport label] [-keymatexportlen len] [-legacy_server_connect]\n" | ||
829 | " [-msg] [-mtu mtu] [-nbio] [-nbio_test] [-no_comp] [-no_ign_eof]\n" | ||
830 | " [-no_legacy_server_connect] [-no_ticket] [-no_tls1] [-no_tls1_1]\n" | ||
831 | " [-no_tls1_2] [-no_tls1_3] [-pass arg] [-pause] [-policy_check]\n" | ||
832 | " [-port port] [-prexit] [-proxy host:port] [-quiet] [-reconnect]\n" | ||
833 | " [-servername name] [-serverpref] [-sess_in file] [-sess_out file]\n" | ||
834 | " [-showcerts] [-starttls protocol] [-state] [-status] [-timeout]\n" | ||
835 | " [-tls1] [-tls1_1] [-tls1_2] [-tls1_3] [-tlsextdebug]\n" | ||
836 | " [-use_srtp profiles] [-verify depth] [-verify_return_error]\n" | ||
837 | " [-x509_strict] [-xmpphost host]\n"); | ||
838 | fprintf(stderr, "\n"); | ||
839 | options_usage(s_client_options); | ||
840 | fprintf(stderr, "\n"); | ||
254 | } | 841 | } |
255 | 842 | ||
256 | 843 | ||
@@ -274,68 +861,29 @@ ssl_servername_cb(SSL * s, int *ad, void *arg) | |||
274 | return SSL_TLSEXT_ERR_OK; | 861 | return SSL_TLSEXT_ERR_OK; |
275 | } | 862 | } |
276 | 863 | ||
277 | #ifndef OPENSSL_NO_SRTP | ||
278 | char *srtp_profiles = NULL; | ||
279 | #endif | ||
280 | |||
281 | enum { | ||
282 | PROTO_OFF = 0, | ||
283 | PROTO_SMTP, | ||
284 | PROTO_LMTP, | ||
285 | PROTO_POP3, | ||
286 | PROTO_IMAP, | ||
287 | PROTO_FTP, | ||
288 | PROTO_XMPP | ||
289 | }; | ||
290 | |||
291 | int | 864 | int |
292 | s_client_main(int argc, char **argv) | 865 | s_client_main(int argc, char **argv) |
293 | { | 866 | { |
294 | unsigned int off = 0, clr = 0; | ||
295 | SSL *con = NULL; | 867 | SSL *con = NULL; |
296 | int s, k, p = 0, pending = 0, state = 0, af = AF_UNSPEC; | 868 | int s, k, p = 0, pending = 0; |
297 | char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL, *pbuf = NULL; | 869 | char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL, *pbuf = NULL; |
298 | int cbuf_len, cbuf_off; | 870 | int cbuf_len, cbuf_off; |
299 | int sbuf_len, sbuf_off; | 871 | int sbuf_len, sbuf_off; |
300 | int pbuf_len, pbuf_off; | 872 | int pbuf_len, pbuf_off; |
301 | char *port = PORT_STR; | ||
302 | int full_log = 1; | 873 | int full_log = 1; |
303 | char *host = SSL_HOST_NAME; | 874 | char *pass = NULL; |
304 | char *xmpphost = NULL; | ||
305 | char *proxy = NULL, *connect = NULL; | ||
306 | char *cert_file = NULL, *key_file = NULL; | ||
307 | int cert_format = FORMAT_PEM, key_format = FORMAT_PEM; | ||
308 | char *passarg = NULL, *pass = NULL; | ||
309 | X509 *cert = NULL; | 875 | X509 *cert = NULL; |
310 | EVP_PKEY *key = NULL; | 876 | EVP_PKEY *key = NULL; |
311 | char *CApath = NULL, *CAfile = NULL, *cipher = NULL; | 877 | int badop = 0; |
312 | int reconnect = 0, badop = 0, verify = SSL_VERIFY_NONE, bugs = 0; | ||
313 | int crlf = 0; | ||
314 | int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; | 878 | int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; |
315 | SSL_CTX *ctx = NULL; | 879 | SSL_CTX *ctx = NULL; |
316 | int ret = 1, in_init = 1, i, nbio_test = 0; | 880 | int ret = 1, in_init = 1, i; |
317 | int starttls_proto = PROTO_OFF; | ||
318 | int prexit = 0; | ||
319 | int peekaboo = 0; | ||
320 | X509_VERIFY_PARAM *vpm = NULL; | ||
321 | int badarg = 0; | ||
322 | const SSL_METHOD *meth = NULL; | ||
323 | int socket_type = SOCK_STREAM; | ||
324 | BIO *sbio; | 881 | BIO *sbio; |
325 | int mbuf_len = 0; | 882 | int mbuf_len = 0; |
326 | struct timeval timeout; | 883 | struct timeval timeout; |
327 | const char *errstr = NULL; | ||
328 | char *servername = NULL; | ||
329 | tlsextctx tlsextcbp = {NULL, 0}; | 884 | tlsextctx tlsextcbp = {NULL, 0}; |
330 | const char *alpn_in = NULL; | ||
331 | const char *groups_in = NULL; | ||
332 | char *sess_in = NULL; | ||
333 | char *sess_out = NULL; | ||
334 | struct sockaddr_storage peer; | 885 | struct sockaddr_storage peer; |
335 | int peerlen = sizeof(peer); | 886 | int peerlen = sizeof(peer); |
336 | int enable_timeouts = 0; | ||
337 | long socket_mtu = 0; | ||
338 | uint16_t min_version = 0, max_version = 0; | ||
339 | 887 | ||
340 | if (single_execution) { | 888 | if (single_execution) { |
341 | if (pledge("stdio cpath wpath rpath inet dns tty", NULL) == -1) { | 889 | if (pledge("stdio cpath wpath rpath inet dns tty", NULL) == -1) { |
@@ -344,14 +892,17 @@ s_client_main(int argc, char **argv) | |||
344 | } | 892 | } |
345 | } | 893 | } |
346 | 894 | ||
347 | meth = TLS_client_method(); | 895 | memset(&s_client_config, 0, sizeof(s_client_config)); |
348 | 896 | s_client_config.af = AF_UNSPEC; | |
349 | c_Pause = 0; | 897 | s_client_config.cert_format = FORMAT_PEM; |
350 | c_quiet = 0; | 898 | s_client_config.host = SSL_HOST_NAME; |
351 | c_ign_eof = 0; | 899 | s_client_config.key_format = FORMAT_PEM; |
352 | c_debug = 0; | 900 | s_client_config.keymatexportlen = 20; |
353 | c_msg = 0; | 901 | s_client_config.meth = TLS_client_method(); |
354 | c_showcerts = 0; | 902 | s_client_config.port = PORT_STR; |
903 | s_client_config.socket_type = SOCK_STREAM; | ||
904 | s_client_config.starttls_proto = PROTO_OFF; | ||
905 | s_client_config.verify = SSL_VERIFY_NONE; | ||
355 | 906 | ||
356 | if (((cbuf = malloc(BUFSIZZ)) == NULL) || | 907 | if (((cbuf = malloc(BUFSIZZ)) == NULL) || |
357 | ((sbuf = malloc(BUFSIZZ)) == NULL) || | 908 | ((sbuf = malloc(BUFSIZZ)) == NULL) || |
@@ -361,277 +912,46 @@ s_client_main(int argc, char **argv) | |||
361 | goto end; | 912 | goto end; |
362 | } | 913 | } |
363 | verify_depth = 0; | 914 | verify_depth = 0; |
364 | c_nbio = 0; | 915 | |
365 | 916 | if (options_parse(argc, argv, s_client_options, NULL, NULL) != 0) { | |
366 | argc--; | 917 | badop = 1; |
367 | argv++; | 918 | goto bad; |
368 | while (argc >= 1) { | ||
369 | if (strcmp(*argv, "-host") == 0) { | ||
370 | if (--argc < 1) | ||
371 | goto bad; | ||
372 | host = *(++argv); | ||
373 | } else if (strcmp(*argv, "-port") == 0) { | ||
374 | if (--argc < 1) | ||
375 | goto bad; | ||
376 | port = *(++argv); | ||
377 | if (port == NULL || *port == '\0') | ||
378 | goto bad; | ||
379 | } else if (strcmp(*argv, "-connect") == 0) { | ||
380 | if (--argc < 1) | ||
381 | goto bad; | ||
382 | connect = *(++argv); | ||
383 | } else if (strcmp(*argv, "-proxy") == 0) { | ||
384 | if (--argc < 1) | ||
385 | goto bad; | ||
386 | proxy = *(++argv); | ||
387 | } else if (strcmp(*argv,"-xmpphost") == 0) { | ||
388 | if (--argc < 1) | ||
389 | goto bad; | ||
390 | xmpphost= *(++argv); | ||
391 | } else if (strcmp(*argv, "-verify") == 0) { | ||
392 | verify = SSL_VERIFY_PEER; | ||
393 | if (--argc < 1) | ||
394 | goto bad; | ||
395 | verify_depth = strtonum(*(++argv), 0, INT_MAX, &errstr); | ||
396 | if (errstr) | ||
397 | goto bad; | ||
398 | BIO_printf(bio_err, "verify depth is %d\n", verify_depth); | ||
399 | } else if (strcmp(*argv, "-cert") == 0) { | ||
400 | if (--argc < 1) | ||
401 | goto bad; | ||
402 | cert_file = *(++argv); | ||
403 | } else if (strcmp(*argv, "-sess_out") == 0) { | ||
404 | if (--argc < 1) | ||
405 | goto bad; | ||
406 | sess_out = *(++argv); | ||
407 | } else if (strcmp(*argv, "-sess_in") == 0) { | ||
408 | if (--argc < 1) | ||
409 | goto bad; | ||
410 | sess_in = *(++argv); | ||
411 | } else if (strcmp(*argv, "-certform") == 0) { | ||
412 | if (--argc < 1) | ||
413 | goto bad; | ||
414 | cert_format = str2fmt(*(++argv)); | ||
415 | } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { | ||
416 | if (badarg) | ||
417 | goto bad; | ||
418 | continue; | ||
419 | } else if (strcmp(*argv, "-verify_return_error") == 0) | ||
420 | verify_return_error = 1; | ||
421 | else if (strcmp(*argv, "-prexit") == 0) | ||
422 | prexit = 1; | ||
423 | else if (strcmp(*argv, "-peekaboo") == 0) | ||
424 | peekaboo = 1; | ||
425 | else if (strcmp(*argv, "-crlf") == 0) | ||
426 | crlf = 1; | ||
427 | else if (strcmp(*argv, "-quiet") == 0) { | ||
428 | c_quiet = 1; | ||
429 | c_ign_eof = 1; | ||
430 | } else if (strcmp(*argv, "-ign_eof") == 0) | ||
431 | c_ign_eof = 1; | ||
432 | else if (strcmp(*argv, "-no_ign_eof") == 0) | ||
433 | c_ign_eof = 0; | ||
434 | else if (strcmp(*argv, "-pause") == 0) | ||
435 | c_Pause = 1; | ||
436 | else if (strcmp(*argv, "-debug") == 0) | ||
437 | c_debug = 1; | ||
438 | else if (strcmp(*argv, "-tlsextdebug") == 0) | ||
439 | c_tlsextdebug = 1; | ||
440 | else if (strcmp(*argv, "-status") == 0) | ||
441 | c_status_req = 1; | ||
442 | else if (strcmp(*argv, "-msg") == 0) | ||
443 | c_msg = 1; | ||
444 | else if (strcmp(*argv, "-showcerts") == 0) | ||
445 | c_showcerts = 1; | ||
446 | else if (strcmp(*argv, "-nbio_test") == 0) | ||
447 | nbio_test = 1; | ||
448 | else if (strcmp(*argv, "-state") == 0) | ||
449 | state = 1; | ||
450 | else if (strcmp(*argv, "-tls1_3") == 0) { | ||
451 | min_version = TLS1_3_VERSION; | ||
452 | max_version = TLS1_3_VERSION; | ||
453 | } else if (strcmp(*argv, "-tls1_2") == 0) { | ||
454 | min_version = TLS1_2_VERSION; | ||
455 | max_version = TLS1_2_VERSION; | ||
456 | } else if (strcmp(*argv, "-tls1_1") == 0) { | ||
457 | min_version = TLS1_1_VERSION; | ||
458 | max_version = TLS1_1_VERSION; | ||
459 | } else if (strcmp(*argv, "-tls1") == 0) { | ||
460 | min_version = TLS1_VERSION; | ||
461 | max_version = TLS1_VERSION; | ||
462 | #ifndef OPENSSL_NO_DTLS1 | ||
463 | } else if (strcmp(*argv, "-dtls1") == 0) { | ||
464 | meth = DTLS_client_method(); | ||
465 | socket_type = SOCK_DGRAM; | ||
466 | } else if (strcmp(*argv, "-timeout") == 0) | ||
467 | enable_timeouts = 1; | ||
468 | else if (strcmp(*argv, "-mtu") == 0) { | ||
469 | if (--argc < 1) | ||
470 | goto bad; | ||
471 | socket_mtu = strtonum(*(++argv), 0, LONG_MAX, &errstr); | ||
472 | if (errstr) | ||
473 | goto bad; | ||
474 | } | ||
475 | #endif | ||
476 | else if (strcmp(*argv, "-bugs") == 0) | ||
477 | bugs = 1; | ||
478 | else if (strcmp(*argv, "-keyform") == 0) { | ||
479 | if (--argc < 1) | ||
480 | goto bad; | ||
481 | key_format = str2fmt(*(++argv)); | ||
482 | } else if (strcmp(*argv, "-pass") == 0) { | ||
483 | if (--argc < 1) | ||
484 | goto bad; | ||
485 | passarg = *(++argv); | ||
486 | } else if (strcmp(*argv, "-key") == 0) { | ||
487 | if (--argc < 1) | ||
488 | goto bad; | ||
489 | key_file = *(++argv); | ||
490 | } else if (strcmp(*argv, "-reconnect") == 0) { | ||
491 | reconnect = 5; | ||
492 | } else if (strcmp(*argv, "-CApath") == 0) { | ||
493 | if (--argc < 1) | ||
494 | goto bad; | ||
495 | CApath = *(++argv); | ||
496 | } else if (strcmp(*argv, "-CAfile") == 0) { | ||
497 | if (--argc < 1) | ||
498 | goto bad; | ||
499 | CAfile = *(++argv); | ||
500 | } else if (strcmp(*argv, "-no_tls1_3") == 0) | ||
501 | off |= SSL_OP_NO_TLSv1_3; | ||
502 | else if (strcmp(*argv, "-no_tls1_2") == 0) | ||
503 | off |= SSL_OP_NO_TLSv1_2; | ||
504 | else if (strcmp(*argv, "-no_tls1_1") == 0) | ||
505 | off |= SSL_OP_NO_TLSv1_1; | ||
506 | else if (strcmp(*argv, "-no_tls1") == 0) | ||
507 | off |= SSL_OP_NO_TLSv1; | ||
508 | else if (strcmp(*argv, "-no_ssl3") == 0) | ||
509 | off |= SSL_OP_NO_SSLv3; | ||
510 | else if (strcmp(*argv, "-no_ssl2") == 0) | ||
511 | off |= SSL_OP_NO_SSLv2; | ||
512 | else if (strcmp(*argv, "-no_comp") == 0) { | ||
513 | off |= SSL_OP_NO_COMPRESSION; | ||
514 | } else if (strcmp(*argv, "-no_ticket") == 0) { | ||
515 | off |= SSL_OP_NO_TICKET; | ||
516 | } else if (strcmp(*argv, "-nextprotoneg") == 0) { | ||
517 | /* Ignored. */ | ||
518 | if (--argc < 1) | ||
519 | goto bad; | ||
520 | ++argv; | ||
521 | } else if (strcmp(*argv, "-alpn") == 0) { | ||
522 | if (--argc < 1) | ||
523 | goto bad; | ||
524 | alpn_in = *(++argv); | ||
525 | } else if (strcmp(*argv, "-groups") == 0) { | ||
526 | if (--argc < 1) | ||
527 | goto bad; | ||
528 | groups_in = *(++argv); | ||
529 | } else if (strcmp(*argv, "-serverpref") == 0) | ||
530 | off |= SSL_OP_CIPHER_SERVER_PREFERENCE; | ||
531 | else if (strcmp(*argv, "-legacy_renegotiation") == 0) | ||
532 | ; /* no-op */ | ||
533 | else if (strcmp(*argv, "-legacy_server_connect") == 0) { | ||
534 | off |= SSL_OP_LEGACY_SERVER_CONNECT; | ||
535 | } else if (strcmp(*argv, "-no_legacy_server_connect") == 0) { | ||
536 | clr |= SSL_OP_LEGACY_SERVER_CONNECT; | ||
537 | } else if (strcmp(*argv, "-cipher") == 0) { | ||
538 | if (--argc < 1) | ||
539 | goto bad; | ||
540 | cipher = *(++argv); | ||
541 | } | ||
542 | else if (strcmp(*argv, "-nbio") == 0) { | ||
543 | c_nbio = 1; | ||
544 | } | ||
545 | else if (strcmp(*argv, "-starttls") == 0) { | ||
546 | if (--argc < 1) | ||
547 | goto bad; | ||
548 | ++argv; | ||
549 | if (strcmp(*argv, "smtp") == 0) | ||
550 | starttls_proto = PROTO_SMTP; | ||
551 | else if (strcmp(*argv, "lmtp") == 0) | ||
552 | starttls_proto = PROTO_LMTP; | ||
553 | else if (strcmp(*argv, "pop3") == 0) | ||
554 | starttls_proto = PROTO_POP3; | ||
555 | else if (strcmp(*argv, "imap") == 0) | ||
556 | starttls_proto = PROTO_IMAP; | ||
557 | else if (strcmp(*argv, "ftp") == 0) | ||
558 | starttls_proto = PROTO_FTP; | ||
559 | else if (strcmp(*argv, "xmpp") == 0) | ||
560 | starttls_proto = PROTO_XMPP; | ||
561 | else | ||
562 | goto bad; | ||
563 | } else if (strcmp(*argv, "-4") == 0) { | ||
564 | af = AF_INET; | ||
565 | } else if (strcmp(*argv, "-6") == 0) { | ||
566 | af = AF_INET6; | ||
567 | } else if (strcmp(*argv, "-servername") == 0) { | ||
568 | if (--argc < 1) | ||
569 | goto bad; | ||
570 | servername = *(++argv); | ||
571 | } | ||
572 | #ifndef OPENSSL_NO_SRTP | ||
573 | else if (strcmp(*argv, "-use_srtp") == 0) { | ||
574 | if (--argc < 1) | ||
575 | goto bad; | ||
576 | srtp_profiles = *(++argv); | ||
577 | } | ||
578 | #endif | ||
579 | else if (strcmp(*argv, "-keymatexport") == 0) { | ||
580 | if (--argc < 1) | ||
581 | goto bad; | ||
582 | keymatexportlabel = *(++argv); | ||
583 | } else if (strcmp(*argv, "-keymatexportlen") == 0) { | ||
584 | if (--argc < 1) | ||
585 | goto bad; | ||
586 | keymatexportlen = strtonum(*(++argv), 1, INT_MAX, &errstr); | ||
587 | if (errstr) | ||
588 | goto bad; | ||
589 | } else { | ||
590 | BIO_printf(bio_err, "unknown option %s\n", *argv); | ||
591 | badop = 1; | ||
592 | break; | ||
593 | } | ||
594 | argc--; | ||
595 | argv++; | ||
596 | } | 919 | } |
597 | if (proxy != NULL) { | 920 | if (s_client_config.proxy != NULL) { |
598 | if (!extract_host_port(proxy, &host, NULL, &port)) | 921 | if (!extract_host_port(s_client_config.proxy, &s_client_config.host, NULL, &s_client_config.port)) |
599 | goto bad; | 922 | goto bad; |
600 | if (connect == NULL) | 923 | if (s_client_config.connect == NULL) |
601 | connect = SSL_HOST_NAME; | 924 | s_client_config.connect = SSL_HOST_NAME; |
602 | } else if (connect != NULL) { | 925 | } else if (s_client_config.connect != NULL) { |
603 | if (!extract_host_port(connect, &host, NULL, &port)) | 926 | if (!extract_host_port(s_client_config.connect, &s_client_config.host, NULL, &s_client_config.port)) |
604 | goto bad; | 927 | goto bad; |
605 | } | 928 | } |
606 | if (badop) { | 929 | if (badop) { |
607 | bad: | 930 | bad: |
608 | if (errstr) | 931 | if (s_client_config.errstr == NULL) |
609 | BIO_printf(bio_err, "invalid argument %s: %s\n", | ||
610 | *argv, errstr); | ||
611 | else | ||
612 | sc_usage(); | 932 | sc_usage(); |
613 | goto end; | 933 | goto end; |
614 | } | 934 | } |
615 | 935 | ||
616 | if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { | 936 | if (!app_passwd(bio_err, s_client_config.passarg, NULL, &pass, NULL)) { |
617 | BIO_printf(bio_err, "Error getting password\n"); | 937 | BIO_printf(bio_err, "Error getting password\n"); |
618 | goto end; | 938 | goto end; |
619 | } | 939 | } |
620 | if (key_file == NULL) | 940 | if (s_client_config.key_file == NULL) |
621 | key_file = cert_file; | 941 | s_client_config.key_file = s_client_config.cert_file; |
622 | 942 | ||
623 | 943 | ||
624 | if (key_file) { | 944 | if (s_client_config.key_file) { |
625 | 945 | ||
626 | key = load_key(bio_err, key_file, key_format, 0, pass, | 946 | key = load_key(bio_err, s_client_config.key_file, s_client_config.key_format, 0, pass, |
627 | "client certificate private key file"); | 947 | "client certificate private key file"); |
628 | if (!key) { | 948 | if (!key) { |
629 | ERR_print_errors(bio_err); | 949 | ERR_print_errors(bio_err); |
630 | goto end; | 950 | goto end; |
631 | } | 951 | } |
632 | } | 952 | } |
633 | if (cert_file) { | 953 | if (s_client_config.cert_file) { |
634 | cert = load_cert(bio_err, cert_file, cert_format, | 954 | cert = load_cert(bio_err, s_client_config.cert_file, s_client_config.cert_format, |
635 | NULL, "client certificate file"); | 955 | NULL, "client certificate file"); |
636 | 956 | ||
637 | if (!cert) { | 957 | if (!cert) { |
@@ -640,7 +960,7 @@ s_client_main(int argc, char **argv) | |||
640 | } | 960 | } |
641 | } | 961 | } |
642 | if (bio_c_out == NULL) { | 962 | if (bio_c_out == NULL) { |
643 | if (c_quiet && !c_debug && !c_msg) { | 963 | if (s_client_config.c_quiet && !s_client_config.c_debug && !s_client_config.c_msg) { |
644 | bio_c_out = BIO_new(BIO_s_null()); | 964 | bio_c_out = BIO_new(BIO_s_null()); |
645 | } else { | 965 | } else { |
646 | if (bio_c_out == NULL) | 966 | if (bio_c_out == NULL) |
@@ -648,7 +968,7 @@ s_client_main(int argc, char **argv) | |||
648 | } | 968 | } |
649 | } | 969 | } |
650 | 970 | ||
651 | ctx = SSL_CTX_new(meth); | 971 | ctx = SSL_CTX_new(s_client_config.meth); |
652 | if (ctx == NULL) { | 972 | if (ctx == NULL) { |
653 | ERR_print_errors(bio_err); | 973 | ERR_print_errors(bio_err); |
654 | goto end; | 974 | goto end; |
@@ -656,35 +976,35 @@ s_client_main(int argc, char **argv) | |||
656 | 976 | ||
657 | SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY); | 977 | SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY); |
658 | 978 | ||
659 | if (vpm) | 979 | if (s_client_config.vpm) |
660 | SSL_CTX_set1_param(ctx, vpm); | 980 | SSL_CTX_set1_param(ctx, s_client_config.vpm); |
661 | 981 | ||
662 | if (!SSL_CTX_set_min_proto_version(ctx, min_version)) | 982 | if (!SSL_CTX_set_min_proto_version(ctx, s_client_config.min_version)) |
663 | goto end; | 983 | goto end; |
664 | if (!SSL_CTX_set_max_proto_version(ctx, max_version)) | 984 | if (!SSL_CTX_set_max_proto_version(ctx, s_client_config.max_version)) |
665 | goto end; | 985 | goto end; |
666 | 986 | ||
667 | #ifndef OPENSSL_NO_SRTP | 987 | #ifndef OPENSSL_NO_SRTP |
668 | if (srtp_profiles != NULL) | 988 | if (s_client_config.srtp_profiles != NULL) |
669 | SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles); | 989 | SSL_CTX_set_tlsext_use_srtp(ctx, s_client_config.srtp_profiles); |
670 | #endif | 990 | #endif |
671 | if (bugs) | 991 | if (s_client_config.bugs) |
672 | SSL_CTX_set_options(ctx, SSL_OP_ALL | off); | 992 | SSL_CTX_set_options(ctx, SSL_OP_ALL | s_client_config.off); |
673 | else | 993 | else |
674 | SSL_CTX_set_options(ctx, off); | 994 | SSL_CTX_set_options(ctx, s_client_config.off); |
675 | 995 | ||
676 | if (clr) | 996 | if (s_client_config.clr) |
677 | SSL_CTX_clear_options(ctx, clr); | 997 | SSL_CTX_clear_options(ctx, s_client_config.clr); |
678 | /* | 998 | /* |
679 | * DTLS: partial reads end up discarding unread UDP bytes :-( Setting | 999 | * DTLS: partial reads end up discarding unread UDP bytes :-( Setting |
680 | * read ahead solves this problem. | 1000 | * read ahead solves this problem. |
681 | */ | 1001 | */ |
682 | if (socket_type == SOCK_DGRAM) | 1002 | if (s_client_config.socket_type == SOCK_DGRAM) |
683 | SSL_CTX_set_read_ahead(ctx, 1); | 1003 | SSL_CTX_set_read_ahead(ctx, 1); |
684 | 1004 | ||
685 | if (alpn_in) { | 1005 | if (s_client_config.alpn_in) { |
686 | unsigned short alpn_len; | 1006 | unsigned short alpn_len; |
687 | unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in); | 1007 | unsigned char *alpn = next_protos_parse(&alpn_len, s_client_config.alpn_in); |
688 | 1008 | ||
689 | if (alpn == NULL) { | 1009 | if (alpn == NULL) { |
690 | BIO_printf(bio_err, "Error parsing -alpn argument\n"); | 1010 | BIO_printf(bio_err, "Error parsing -alpn argument\n"); |
@@ -693,47 +1013,47 @@ s_client_main(int argc, char **argv) | |||
693 | SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len); | 1013 | SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len); |
694 | free(alpn); | 1014 | free(alpn); |
695 | } | 1015 | } |
696 | if (groups_in != NULL) { | 1016 | if (s_client_config.groups_in != NULL) { |
697 | if (SSL_CTX_set1_groups_list(ctx, groups_in) != 1) { | 1017 | if (SSL_CTX_set1_groups_list(ctx, s_client_config.groups_in) != 1) { |
698 | BIO_printf(bio_err, "Failed to set groups '%s'\n", | 1018 | BIO_printf(bio_err, "Failed to set groups '%s'\n", |
699 | groups_in); | 1019 | s_client_config.groups_in); |
700 | goto end; | 1020 | goto end; |
701 | } | 1021 | } |
702 | } | 1022 | } |
703 | 1023 | ||
704 | if (state) | 1024 | if (s_client_config.state) |
705 | SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); | 1025 | SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); |
706 | if (cipher != NULL) | 1026 | if (s_client_config.cipher != NULL) |
707 | if (!SSL_CTX_set_cipher_list(ctx, cipher)) { | 1027 | if (!SSL_CTX_set_cipher_list(ctx, s_client_config.cipher)) { |
708 | BIO_printf(bio_err, "error setting cipher list\n"); | 1028 | BIO_printf(bio_err, "error setting cipher list\n"); |
709 | ERR_print_errors(bio_err); | 1029 | ERR_print_errors(bio_err); |
710 | goto end; | 1030 | goto end; |
711 | } | 1031 | } |
712 | 1032 | ||
713 | SSL_CTX_set_verify(ctx, verify, verify_callback); | 1033 | SSL_CTX_set_verify(ctx, s_client_config.verify, verify_callback); |
714 | if (!set_cert_key_stuff(ctx, cert, key)) | 1034 | if (!set_cert_key_stuff(ctx, cert, key)) |
715 | goto end; | 1035 | goto end; |
716 | 1036 | ||
717 | if ((CAfile || CApath) | 1037 | if ((s_client_config.CAfile || s_client_config.CApath) |
718 | && !SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) | 1038 | && !SSL_CTX_load_verify_locations(ctx, s_client_config.CAfile, s_client_config.CApath)) |
719 | ERR_print_errors(bio_err); | 1039 | ERR_print_errors(bio_err); |
720 | 1040 | ||
721 | if (!SSL_CTX_set_default_verify_paths(ctx)) | 1041 | if (!SSL_CTX_set_default_verify_paths(ctx)) |
722 | ERR_print_errors(bio_err); | 1042 | ERR_print_errors(bio_err); |
723 | 1043 | ||
724 | if (servername != NULL) { | 1044 | if (s_client_config.servername != NULL) { |
725 | tlsextcbp.biodebug = bio_err; | 1045 | tlsextcbp.biodebug = bio_err; |
726 | SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); | 1046 | SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); |
727 | SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); | 1047 | SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); |
728 | } | 1048 | } |
729 | 1049 | ||
730 | con = SSL_new(ctx); | 1050 | con = SSL_new(ctx); |
731 | if (sess_in) { | 1051 | if (s_client_config.sess_in) { |
732 | SSL_SESSION *sess; | 1052 | SSL_SESSION *sess; |
733 | BIO *stmp = BIO_new_file(sess_in, "r"); | 1053 | BIO *stmp = BIO_new_file(s_client_config.sess_in, "r"); |
734 | if (!stmp) { | 1054 | if (!stmp) { |
735 | BIO_printf(bio_err, "Can't open session file %s\n", | 1055 | BIO_printf(bio_err, "Can't open session file %s\n", |
736 | sess_in); | 1056 | s_client_config.sess_in); |
737 | ERR_print_errors(bio_err); | 1057 | ERR_print_errors(bio_err); |
738 | goto end; | 1058 | goto end; |
739 | } | 1059 | } |
@@ -741,15 +1061,15 @@ s_client_main(int argc, char **argv) | |||
741 | BIO_free(stmp); | 1061 | BIO_free(stmp); |
742 | if (!sess) { | 1062 | if (!sess) { |
743 | BIO_printf(bio_err, "Can't open session file %s\n", | 1063 | BIO_printf(bio_err, "Can't open session file %s\n", |
744 | sess_in); | 1064 | s_client_config.sess_in); |
745 | ERR_print_errors(bio_err); | 1065 | ERR_print_errors(bio_err); |
746 | goto end; | 1066 | goto end; |
747 | } | 1067 | } |
748 | SSL_set_session(con, sess); | 1068 | SSL_set_session(con, sess); |
749 | SSL_SESSION_free(sess); | 1069 | SSL_SESSION_free(sess); |
750 | } | 1070 | } |
751 | if (servername != NULL) { | 1071 | if (s_client_config.servername != NULL) { |
752 | if (!SSL_set_tlsext_host_name(con, servername)) { | 1072 | if (!SSL_set_tlsext_host_name(con, s_client_config.servername)) { |
753 | BIO_printf(bio_err, "Unable to set TLS servername extension.\n"); | 1073 | BIO_printf(bio_err, "Unable to set TLS servername extension.\n"); |
754 | ERR_print_errors(bio_err); | 1074 | ERR_print_errors(bio_err); |
755 | goto end; | 1075 | goto end; |
@@ -759,21 +1079,21 @@ s_client_main(int argc, char **argv) | |||
759 | 1079 | ||
760 | re_start: | 1080 | re_start: |
761 | 1081 | ||
762 | if (init_client(&s, host, port, socket_type, af) == 0) { | 1082 | if (init_client(&s, s_client_config.host, s_client_config.port, s_client_config.socket_type, s_client_config.af) == 0) { |
763 | BIO_printf(bio_err, "connect:errno=%d\n", errno); | 1083 | BIO_printf(bio_err, "connect:errno=%d\n", errno); |
764 | goto end; | 1084 | goto end; |
765 | } | 1085 | } |
766 | BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); | 1086 | BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); |
767 | 1087 | ||
768 | if (c_nbio) { | 1088 | if (s_client_config.c_nbio) { |
769 | if (!c_quiet) | 1089 | if (!s_client_config.c_quiet) |
770 | BIO_printf(bio_c_out, "turning on non blocking io\n"); | 1090 | BIO_printf(bio_c_out, "turning on non blocking io\n"); |
771 | if (!BIO_socket_nbio(s, 1)) { | 1091 | if (!BIO_socket_nbio(s, 1)) { |
772 | ERR_print_errors(bio_err); | 1092 | ERR_print_errors(bio_err); |
773 | goto end; | 1093 | goto end; |
774 | } | 1094 | } |
775 | } | 1095 | } |
776 | if (c_Pause & 0x01) | 1096 | if (s_client_config.c_Pause & 0x01) |
777 | SSL_set_debug(con, 1); | 1097 | SSL_set_debug(con, 1); |
778 | 1098 | ||
779 | if (SSL_version(con) == DTLS1_VERSION) { | 1099 | if (SSL_version(con) == DTLS1_VERSION) { |
@@ -789,7 +1109,7 @@ re_start: | |||
789 | } | 1109 | } |
790 | (void) BIO_ctrl_set_connected(sbio, 1, &peer); | 1110 | (void) BIO_ctrl_set_connected(sbio, 1, &peer); |
791 | 1111 | ||
792 | if (enable_timeouts) { | 1112 | if (s_client_config.enable_timeouts) { |
793 | timeout.tv_sec = 0; | 1113 | timeout.tv_sec = 0; |
794 | timeout.tv_usec = DGRAM_RCV_TIMEOUT; | 1114 | timeout.tv_usec = DGRAM_RCV_TIMEOUT; |
795 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); | 1115 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); |
@@ -798,35 +1118,35 @@ re_start: | |||
798 | timeout.tv_usec = DGRAM_SND_TIMEOUT; | 1118 | timeout.tv_usec = DGRAM_SND_TIMEOUT; |
799 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); | 1119 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); |
800 | } | 1120 | } |
801 | if (socket_mtu > 28) { | 1121 | if (s_client_config.socket_mtu > 28) { |
802 | SSL_set_options(con, SSL_OP_NO_QUERY_MTU); | 1122 | SSL_set_options(con, SSL_OP_NO_QUERY_MTU); |
803 | SSL_set_mtu(con, socket_mtu - 28); | 1123 | SSL_set_mtu(con, s_client_config.socket_mtu - 28); |
804 | } else | 1124 | } else |
805 | /* want to do MTU discovery */ | 1125 | /* want to do MTU discovery */ |
806 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); | 1126 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); |
807 | } else | 1127 | } else |
808 | sbio = BIO_new_socket(s, BIO_NOCLOSE); | 1128 | sbio = BIO_new_socket(s, BIO_NOCLOSE); |
809 | 1129 | ||
810 | if (nbio_test) { | 1130 | if (s_client_config.nbio_test) { |
811 | BIO *test; | 1131 | BIO *test; |
812 | 1132 | ||
813 | test = BIO_new(BIO_f_nbio_test()); | 1133 | test = BIO_new(BIO_f_nbio_test()); |
814 | sbio = BIO_push(test, sbio); | 1134 | sbio = BIO_push(test, sbio); |
815 | } | 1135 | } |
816 | if (c_debug) { | 1136 | if (s_client_config.c_debug) { |
817 | SSL_set_debug(con, 1); | 1137 | SSL_set_debug(con, 1); |
818 | BIO_set_callback(sbio, bio_dump_callback); | 1138 | BIO_set_callback(sbio, bio_dump_callback); |
819 | BIO_set_callback_arg(sbio, (char *) bio_c_out); | 1139 | BIO_set_callback_arg(sbio, (char *) bio_c_out); |
820 | } | 1140 | } |
821 | if (c_msg) { | 1141 | if (s_client_config.c_msg) { |
822 | SSL_set_msg_callback(con, msg_cb); | 1142 | SSL_set_msg_callback(con, msg_cb); |
823 | SSL_set_msg_callback_arg(con, bio_c_out); | 1143 | SSL_set_msg_callback_arg(con, bio_c_out); |
824 | } | 1144 | } |
825 | if (c_tlsextdebug) { | 1145 | if (s_client_config.c_tlsextdebug) { |
826 | SSL_set_tlsext_debug_callback(con, tlsext_cb); | 1146 | SSL_set_tlsext_debug_callback(con, tlsext_cb); |
827 | SSL_set_tlsext_debug_arg(con, bio_c_out); | 1147 | SSL_set_tlsext_debug_arg(con, bio_c_out); |
828 | } | 1148 | } |
829 | if (c_status_req) { | 1149 | if (s_client_config.c_status_req) { |
830 | SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp); | 1150 | SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp); |
831 | SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb); | 1151 | SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb); |
832 | SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out); | 1152 | SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out); |
@@ -857,7 +1177,7 @@ re_start: | |||
857 | * push a buffering BIO into the chain that is removed again later on | 1177 | * push a buffering BIO into the chain that is removed again later on |
858 | * to not disturb the rest of the s_client operation. | 1178 | * to not disturb the rest of the s_client operation. |
859 | */ | 1179 | */ |
860 | if (starttls_proto == PROTO_SMTP || starttls_proto == PROTO_LMTP) { | 1180 | if (s_client_config.starttls_proto == PROTO_SMTP || s_client_config.starttls_proto == PROTO_LMTP) { |
861 | int foundit = 0; | 1181 | int foundit = 0; |
862 | BIO *fbio = BIO_new(BIO_f_buffer()); | 1182 | BIO *fbio = BIO_new(BIO_f_buffer()); |
863 | BIO_push(fbio, sbio); | 1183 | BIO_push(fbio, sbio); |
@@ -868,7 +1188,7 @@ re_start: | |||
868 | while (mbuf_len > 3 && mbuf[3] == '-'); | 1188 | while (mbuf_len > 3 && mbuf[3] == '-'); |
869 | /* STARTTLS command requires EHLO... */ | 1189 | /* STARTTLS command requires EHLO... */ |
870 | BIO_printf(fbio, "%cHLO openssl.client.net\r\n", | 1190 | BIO_printf(fbio, "%cHLO openssl.client.net\r\n", |
871 | starttls_proto == PROTO_SMTP ? 'E' : 'L'); | 1191 | s_client_config.starttls_proto == PROTO_SMTP ? 'E' : 'L'); |
872 | (void) BIO_flush(fbio); | 1192 | (void) BIO_flush(fbio); |
873 | /* wait for multi-line response to end EHLO SMTP response */ | 1193 | /* wait for multi-line response to end EHLO SMTP response */ |
874 | do { | 1194 | do { |
@@ -886,7 +1206,7 @@ re_start: | |||
886 | " try anyway...\n"); | 1206 | " try anyway...\n"); |
887 | BIO_printf(sbio, "STARTTLS\r\n"); | 1207 | BIO_printf(sbio, "STARTTLS\r\n"); |
888 | BIO_read(sbio, sbuf, BUFSIZZ); | 1208 | BIO_read(sbio, sbuf, BUFSIZZ); |
889 | } else if (starttls_proto == PROTO_POP3) { | 1209 | } else if (s_client_config.starttls_proto == PROTO_POP3) { |
890 | mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); | 1210 | mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); |
891 | if (mbuf_len == -1) { | 1211 | if (mbuf_len == -1) { |
892 | BIO_printf(bio_err, "BIO_read failed\n"); | 1212 | BIO_printf(bio_err, "BIO_read failed\n"); |
@@ -894,7 +1214,7 @@ re_start: | |||
894 | } | 1214 | } |
895 | BIO_printf(sbio, "STLS\r\n"); | 1215 | BIO_printf(sbio, "STLS\r\n"); |
896 | BIO_read(sbio, sbuf, BUFSIZZ); | 1216 | BIO_read(sbio, sbuf, BUFSIZZ); |
897 | } else if (starttls_proto == PROTO_IMAP) { | 1217 | } else if (s_client_config.starttls_proto == PROTO_IMAP) { |
898 | int foundit = 0; | 1218 | int foundit = 0; |
899 | BIO *fbio = BIO_new(BIO_f_buffer()); | 1219 | BIO *fbio = BIO_new(BIO_f_buffer()); |
900 | BIO_push(fbio, sbio); | 1220 | BIO_push(fbio, sbio); |
@@ -918,7 +1238,7 @@ re_start: | |||
918 | " try anyway...\n"); | 1238 | " try anyway...\n"); |
919 | BIO_printf(sbio, ". STARTTLS\r\n"); | 1239 | BIO_printf(sbio, ". STARTTLS\r\n"); |
920 | BIO_read(sbio, sbuf, BUFSIZZ); | 1240 | BIO_read(sbio, sbuf, BUFSIZZ); |
921 | } else if (starttls_proto == PROTO_FTP) { | 1241 | } else if (s_client_config.starttls_proto == PROTO_FTP) { |
922 | BIO *fbio = BIO_new(BIO_f_buffer()); | 1242 | BIO *fbio = BIO_new(BIO_f_buffer()); |
923 | BIO_push(fbio, sbio); | 1243 | BIO_push(fbio, sbio); |
924 | /* wait for multi-line response to end from FTP */ | 1244 | /* wait for multi-line response to end from FTP */ |
@@ -931,11 +1251,11 @@ re_start: | |||
931 | BIO_free(fbio); | 1251 | BIO_free(fbio); |
932 | BIO_printf(sbio, "AUTH TLS\r\n"); | 1252 | BIO_printf(sbio, "AUTH TLS\r\n"); |
933 | BIO_read(sbio, sbuf, BUFSIZZ); | 1253 | BIO_read(sbio, sbuf, BUFSIZZ); |
934 | } else if (starttls_proto == PROTO_XMPP) { | 1254 | } else if (s_client_config.starttls_proto == PROTO_XMPP) { |
935 | int seen = 0; | 1255 | int seen = 0; |
936 | BIO_printf(sbio, "<stream:stream " | 1256 | BIO_printf(sbio, "<stream:stream " |
937 | "xmlns:stream='http://etherx.jabber.org/streams' " | 1257 | "xmlns:stream='http://etherx.jabber.org/streams' " |
938 | "xmlns='jabber:client' to='%s' version='1.0'>", xmpphost ? xmpphost : host); | 1258 | "xmlns='jabber:client' to='%s' version='1.0'>", s_client_config.xmpphost ? s_client_config.xmpphost : s_client_config.host); |
939 | seen = BIO_read(sbio, mbuf, BUFSIZZ); | 1259 | seen = BIO_read(sbio, mbuf, BUFSIZZ); |
940 | 1260 | ||
941 | if (seen <= 0) | 1261 | if (seen <= 0) |
@@ -957,8 +1277,8 @@ re_start: | |||
957 | if (!strstr(sbuf, "<proceed")) | 1277 | if (!strstr(sbuf, "<proceed")) |
958 | goto shut; | 1278 | goto shut; |
959 | mbuf[0] = 0; | 1279 | mbuf[0] = 0; |
960 | } else if (proxy != NULL) { | 1280 | } else if (s_client_config.proxy != NULL) { |
961 | BIO_printf(sbio, "CONNECT %s HTTP/1.0\r\n\r\n", connect); | 1281 | BIO_printf(sbio, "CONNECT %s HTTP/1.0\r\n\r\n", s_client_config.connect); |
962 | mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); | 1282 | mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); |
963 | if (mbuf_len == -1) { | 1283 | if (mbuf_len == -1) { |
964 | BIO_printf(bio_err, "BIO_read failed\n"); | 1284 | BIO_printf(bio_err, "BIO_read failed\n"); |
@@ -980,25 +1300,25 @@ re_start: | |||
980 | tty_on = 1; | 1300 | tty_on = 1; |
981 | if (in_init) { | 1301 | if (in_init) { |
982 | in_init = 0; | 1302 | in_init = 0; |
983 | if (sess_out) { | 1303 | if (s_client_config.sess_out) { |
984 | BIO *stmp = BIO_new_file(sess_out, "w"); | 1304 | BIO *stmp = BIO_new_file(s_client_config.sess_out, "w"); |
985 | if (stmp) { | 1305 | if (stmp) { |
986 | PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con)); | 1306 | PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con)); |
987 | BIO_free(stmp); | 1307 | BIO_free(stmp); |
988 | } else | 1308 | } else |
989 | BIO_printf(bio_err, "Error writing session file %s\n", sess_out); | 1309 | BIO_printf(bio_err, "Error writing session file %s\n", s_client_config.sess_out); |
990 | } | 1310 | } |
991 | print_stuff(bio_c_out, con, full_log); | 1311 | print_stuff(bio_c_out, con, full_log); |
992 | if (full_log > 0) | 1312 | if (full_log > 0) |
993 | full_log--; | 1313 | full_log--; |
994 | 1314 | ||
995 | if (starttls_proto) { | 1315 | if (s_client_config.starttls_proto) { |
996 | BIO_write(bio_err, mbuf, mbuf_len); | 1316 | BIO_write(bio_err, mbuf, mbuf_len); |
997 | /* We don't need to know any more */ | 1317 | /* We don't need to know any more */ |
998 | starttls_proto = PROTO_OFF; | 1318 | s_client_config.starttls_proto = PROTO_OFF; |
999 | } | 1319 | } |
1000 | if (reconnect) { | 1320 | if (s_client_config.reconnect) { |
1001 | reconnect--; | 1321 | s_client_config.reconnect--; |
1002 | BIO_printf(bio_c_out, "drop connection and then reconnect\n"); | 1322 | BIO_printf(bio_c_out, "drop connection and then reconnect\n"); |
1003 | SSL_shutdown(con); | 1323 | SSL_shutdown(con); |
1004 | SSL_set_connect_state(con); | 1324 | SSL_set_connect_state(con); |
@@ -1137,7 +1457,7 @@ re_start: | |||
1137 | } | 1457 | } |
1138 | } | 1458 | } |
1139 | #endif | 1459 | #endif |
1140 | if (peekaboo) { | 1460 | if (s_client_config.peekaboo) { |
1141 | k = p = SSL_peek(con, pbuf, 1024 /* BUFSIZZ */ ); | 1461 | k = p = SSL_peek(con, pbuf, 1024 /* BUFSIZZ */ ); |
1142 | pending = SSL_pending(con); | 1462 | pending = SSL_pending(con); |
1143 | if (SSL_get_error(con, p) == SSL_ERROR_NONE) { | 1463 | if (SSL_get_error(con, p) == SSL_ERROR_NONE) { |
@@ -1158,7 +1478,7 @@ re_start: | |||
1158 | goto end; | 1478 | goto end; |
1159 | sbuf_off = 0; | 1479 | sbuf_off = 0; |
1160 | sbuf_len = k; | 1480 | sbuf_len = k; |
1161 | if (peekaboo) { | 1481 | if (s_client_config.peekaboo) { |
1162 | if (p != pending) { | 1482 | if (p != pending) { |
1163 | ret = -1; | 1483 | ret = -1; |
1164 | BIO_printf(bio_err, | 1484 | BIO_printf(bio_err, |
@@ -1215,7 +1535,7 @@ re_start: | |||
1215 | BIO_printf(bio_err, "poll error"); | 1535 | BIO_printf(bio_err, "poll error"); |
1216 | goto shut; | 1536 | goto shut; |
1217 | } | 1537 | } |
1218 | if (crlf) { | 1538 | if (s_client_config.crlf) { |
1219 | int j, lf_num; | 1539 | int j, lf_num; |
1220 | 1540 | ||
1221 | i = read(fileno(stdin), cbuf, BUFSIZZ / 2); | 1541 | i = read(fileno(stdin), cbuf, BUFSIZZ / 2); |
@@ -1236,12 +1556,12 @@ re_start: | |||
1236 | } else | 1556 | } else |
1237 | i = read(fileno(stdin), cbuf, BUFSIZZ); | 1557 | i = read(fileno(stdin), cbuf, BUFSIZZ); |
1238 | 1558 | ||
1239 | if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) { | 1559 | if ((!s_client_config.c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) { |
1240 | BIO_printf(bio_err, "DONE\n"); | 1560 | BIO_printf(bio_err, "DONE\n"); |
1241 | ret = 0; | 1561 | ret = 0; |
1242 | goto shut; | 1562 | goto shut; |
1243 | } | 1563 | } |
1244 | if ((!c_ign_eof) && (cbuf[0] == 'R')) { | 1564 | if ((!s_client_config.c_ign_eof) && (cbuf[0] == 'R')) { |
1245 | BIO_printf(bio_err, "RENEGOTIATING\n"); | 1565 | BIO_printf(bio_err, "RENEGOTIATING\n"); |
1246 | SSL_renegotiate(con); | 1566 | SSL_renegotiate(con); |
1247 | cbuf_len = 0; | 1567 | cbuf_len = 0; |
@@ -1264,7 +1584,7 @@ re_start: | |||
1264 | close(SSL_get_fd(con)); | 1584 | close(SSL_get_fd(con)); |
1265 | end: | 1585 | end: |
1266 | if (con != NULL) { | 1586 | if (con != NULL) { |
1267 | if (prexit != 0) | 1587 | if (s_client_config.prexit != 0) |
1268 | print_stuff(bio_c_out, con, 1); | 1588 | print_stuff(bio_c_out, con, 1); |
1269 | SSL_free(con); | 1589 | SSL_free(con); |
1270 | } | 1590 | } |
@@ -1272,7 +1592,7 @@ re_start: | |||
1272 | X509_free(cert); | 1592 | X509_free(cert); |
1273 | EVP_PKEY_free(key); | 1593 | EVP_PKEY_free(key); |
1274 | free(pass); | 1594 | free(pass); |
1275 | X509_VERIFY_PARAM_free(vpm); | 1595 | X509_VERIFY_PARAM_free(s_client_config.vpm); |
1276 | freezero(cbuf, BUFSIZZ); | 1596 | freezero(cbuf, BUFSIZZ); |
1277 | freezero(sbuf, BUFSIZZ); | 1597 | freezero(sbuf, BUFSIZZ); |
1278 | freezero(mbuf, BUFSIZZ); | 1598 | freezero(mbuf, BUFSIZZ); |
@@ -1315,7 +1635,7 @@ print_stuff(BIO * bio, SSL * s, int full) | |||
1315 | X509_NAME_oneline(X509_get_issuer_name( | 1635 | X509_NAME_oneline(X509_get_issuer_name( |
1316 | sk_X509_value(sk, i)), buf, sizeof buf); | 1636 | sk_X509_value(sk, i)), buf, sizeof buf); |
1317 | BIO_printf(bio, " i:%s\n", buf); | 1637 | BIO_printf(bio, " i:%s\n", buf); |
1318 | if (c_showcerts) | 1638 | if (s_client_config.c_showcerts) |
1319 | PEM_write_bio_X509(bio, sk_X509_value(sk, i)); | 1639 | PEM_write_bio_X509(bio, sk_X509_value(sk, i)); |
1320 | } | 1640 | } |
1321 | } | 1641 | } |
@@ -1323,7 +1643,7 @@ print_stuff(BIO * bio, SSL * s, int full) | |||
1323 | peer = SSL_get_peer_certificate(s); | 1643 | peer = SSL_get_peer_certificate(s); |
1324 | if (peer != NULL) { | 1644 | if (peer != NULL) { |
1325 | BIO_printf(bio, "Server certificate\n"); | 1645 | BIO_printf(bio, "Server certificate\n"); |
1326 | if (!(c_showcerts && got_a_chain)) /* Redundant if we | 1646 | if (!(s_client_config.c_showcerts && got_a_chain)) /* Redundant if we |
1327 | * showed the whole | 1647 | * showed the whole |
1328 | * chain */ | 1648 | * chain */ |
1329 | PEM_write_bio_X509(bio, peer); | 1649 | PEM_write_bio_X509(bio, peer); |
@@ -1434,21 +1754,21 @@ print_stuff(BIO * bio, SSL * s, int full) | |||
1434 | #endif | 1754 | #endif |
1435 | 1755 | ||
1436 | SSL_SESSION_print(bio, SSL_get_session(s)); | 1756 | SSL_SESSION_print(bio, SSL_get_session(s)); |
1437 | if (keymatexportlabel != NULL) { | 1757 | if (s_client_config.keymatexportlabel != NULL) { |
1438 | BIO_printf(bio, "Keying material exporter:\n"); | 1758 | BIO_printf(bio, "Keying material exporter:\n"); |
1439 | BIO_printf(bio, " Label: '%s'\n", keymatexportlabel); | 1759 | BIO_printf(bio, " Label: '%s'\n", s_client_config.keymatexportlabel); |
1440 | BIO_printf(bio, " Length: %i bytes\n", keymatexportlen); | 1760 | BIO_printf(bio, " Length: %i bytes\n", s_client_config.keymatexportlen); |
1441 | exportedkeymat = malloc(keymatexportlen); | 1761 | exportedkeymat = malloc(s_client_config.keymatexportlen); |
1442 | if (exportedkeymat != NULL) { | 1762 | if (exportedkeymat != NULL) { |
1443 | if (!SSL_export_keying_material(s, exportedkeymat, | 1763 | if (!SSL_export_keying_material(s, exportedkeymat, |
1444 | keymatexportlen, | 1764 | s_client_config.keymatexportlen, |
1445 | keymatexportlabel, | 1765 | s_client_config.keymatexportlabel, |
1446 | strlen(keymatexportlabel), | 1766 | strlen(s_client_config.keymatexportlabel), |
1447 | NULL, 0, 0)) { | 1767 | NULL, 0, 0)) { |
1448 | BIO_printf(bio, " Error\n"); | 1768 | BIO_printf(bio, " Error\n"); |
1449 | } else { | 1769 | } else { |
1450 | BIO_printf(bio, " Keying material: "); | 1770 | BIO_printf(bio, " Keying material: "); |
1451 | for (i = 0; i < keymatexportlen; i++) | 1771 | for (i = 0; i < s_client_config.keymatexportlen; i++) |
1452 | BIO_printf(bio, "%02X", | 1772 | BIO_printf(bio, "%02X", |
1453 | exportedkeymat[i]); | 1773 | exportedkeymat[i]); |
1454 | BIO_printf(bio, "\n"); | 1774 | BIO_printf(bio, "\n"); |