Deleted Added
full compact
common.c (236490) common.c (256257)
1/*-
2 * Copyright (c) 1998-2011 Dag-Erling Sm��rgrav
1/*-
2 * Copyright (c) 1998-2011 Dag-Erling Sm��rgrav
3 * Copyright (c) 2013 Michael Gmelin <freebsd@grem.de>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.

--- 11 unchanged lines hidden (view full) ---

22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer
11 * in this position and unchanged.

--- 11 unchanged lines hidden (view full) ---

23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: stable/9/lib/libfetch/common.c 236490 2012-06-02 20:18:34Z jilles $");
31__FBSDID("$FreeBSD: stable/9/lib/libfetch/common.c 256257 2013-10-10 09:42:41Z glebius $");
31
32#include <sys/param.h>
33#include <sys/socket.h>
34#include <sys/time.h>
35#include <sys/uio.h>
36
37#include <netinet/in.h>
38
39#include <ctype.h>
40#include <errno.h>
41#include <fcntl.h>
42#include <netdb.h>
43#include <pwd.h>
44#include <stdarg.h>
45#include <stdlib.h>
46#include <stdio.h>
47#include <string.h>
48#include <unistd.h>
49
32
33#include <sys/param.h>
34#include <sys/socket.h>
35#include <sys/time.h>
36#include <sys/uio.h>
37
38#include <netinet/in.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <fcntl.h>
43#include <netdb.h>
44#include <pwd.h>
45#include <stdarg.h>
46#include <stdlib.h>
47#include <stdio.h>
48#include <string.h>
49#include <unistd.h>
50
51#ifdef WITH_SSL
52#include <openssl/x509v3.h>
53#endif
54
50#include "fetch.h"
51#include "common.h"
52
53
54/*** Local data **************************************************************/
55
56/*
57 * Error messages for resolver errors

--- 254 unchanged lines hidden (view full) ---

312
313 if ((conn = fetch_reopen(sd)) == NULL) {
314 fetch_syserr();
315 close(sd);
316 }
317 return (conn);
318}
319
55#include "fetch.h"
56#include "common.h"
57
58
59/*** Local data **************************************************************/
60
61/*
62 * Error messages for resolver errors

--- 254 unchanged lines hidden (view full) ---

317
318 if ((conn = fetch_reopen(sd)) == NULL) {
319 fetch_syserr();
320 close(sd);
321 }
322 return (conn);
323}
324
325#ifdef WITH_SSL
326/*
327 * Convert characters A-Z to lowercase (intentionally avoid any locale
328 * specific conversions).
329 */
330static char
331fetch_ssl_tolower(char in)
332{
333 if (in >= 'A' && in <= 'Z')
334 return (in + 32);
335 else
336 return (in);
337}
320
321/*
338
339/*
340 * isalpha implementation that intentionally avoids any locale specific
341 * conversions.
342 */
343static int
344fetch_ssl_isalpha(char in)
345{
346 return ((in >= 'A' && in <= 'Z') || (in >= 'a' && in <= 'z'));
347}
348
349/*
350 * Check if passed hostnames a and b are equal.
351 */
352static int
353fetch_ssl_hname_equal(const char *a, size_t alen, const char *b,
354 size_t blen)
355{
356 size_t i;
357
358 if (alen != blen)
359 return (0);
360 for (i = 0; i < alen; ++i) {
361 if (fetch_ssl_tolower(a[i]) != fetch_ssl_tolower(b[i]))
362 return (0);
363 }
364 return (1);
365}
366
367/*
368 * Check if domain label is traditional, meaning that only A-Z, a-z, 0-9
369 * and '-' (hyphen) are allowed. Hyphens have to be surrounded by alpha-
370 * numeric characters. Double hyphens (like they're found in IDN a-labels
371 * 'xn--') are not allowed. Empty labels are invalid.
372 */
373static int
374fetch_ssl_is_trad_domain_label(const char *l, size_t len, int wcok)
375{
376 size_t i;
377
378 if (!len || l[0] == '-' || l[len-1] == '-')
379 return (0);
380 for (i = 0; i < len; ++i) {
381 if (!isdigit(l[i]) &&
382 !fetch_ssl_isalpha(l[i]) &&
383 !(l[i] == '*' && wcok) &&
384 !(l[i] == '-' && l[i - 1] != '-'))
385 return (0);
386 }
387 return (1);
388}
389
390/*
391 * Check if host name consists only of numbers. This might indicate an IP
392 * address, which is not a good idea for CN wildcard comparison.
393 */
394static int
395fetch_ssl_hname_is_only_numbers(const char *hostname, size_t len)
396{
397 size_t i;
398
399 for (i = 0; i < len; ++i) {
400 if (!((hostname[i] >= '0' && hostname[i] <= '9') ||
401 hostname[i] == '.'))
402 return (0);
403 }
404 return (1);
405}
406
407/*
408 * Check if the host name h passed matches the pattern passed in m which
409 * is usually part of subjectAltName or CN of a certificate presented to
410 * the client. This includes wildcard matching. The algorithm is based on
411 * RFC6125, sections 6.4.3 and 7.2, which clarifies RFC2818 and RFC3280.
412 */
413static int
414fetch_ssl_hname_match(const char *h, size_t hlen, const char *m,
415 size_t mlen)
416{
417 int delta, hdotidx, mdot1idx, wcidx;
418 const char *hdot, *mdot1, *mdot2;
419 const char *wc; /* wildcard */
420
421 if (!(h && *h && m && *m))
422 return (0);
423 if ((wc = strnstr(m, "*", mlen)) == NULL)
424 return (fetch_ssl_hname_equal(h, hlen, m, mlen));
425 wcidx = wc - m;
426 /* hostname should not be just dots and numbers */
427 if (fetch_ssl_hname_is_only_numbers(h, hlen))
428 return (0);
429 /* only one wildcard allowed in pattern */
430 if (strnstr(wc + 1, "*", mlen - wcidx - 1) != NULL)
431 return (0);
432 /*
433 * there must be at least two more domain labels and
434 * wildcard has to be in the leftmost label (RFC6125)
435 */
436 mdot1 = strnstr(m, ".", mlen);
437 if (mdot1 == NULL || mdot1 < wc || (mlen - (mdot1 - m)) < 4)
438 return (0);
439 mdot1idx = mdot1 - m;
440 mdot2 = strnstr(mdot1 + 1, ".", mlen - mdot1idx - 1);
441 if (mdot2 == NULL || (mlen - (mdot2 - m)) < 2)
442 return (0);
443 /* hostname must contain a dot and not be the 1st char */
444 hdot = strnstr(h, ".", hlen);
445 if (hdot == NULL || hdot == h)
446 return (0);
447 hdotidx = hdot - h;
448 /*
449 * host part of hostname must be at least as long as
450 * pattern it's supposed to match
451 */
452 if (hdotidx < mdot1idx)
453 return (0);
454 /*
455 * don't allow wildcards in non-traditional domain names
456 * (IDN, A-label, U-label...)
457 */
458 if (!fetch_ssl_is_trad_domain_label(h, hdotidx, 0) ||
459 !fetch_ssl_is_trad_domain_label(m, mdot1idx, 1))
460 return (0);
461 /* match domain part (part after first dot) */
462 if (!fetch_ssl_hname_equal(hdot, hlen - hdotidx, mdot1,
463 mlen - mdot1idx))
464 return (0);
465 /* match part left of wildcard */
466 if (!fetch_ssl_hname_equal(h, wcidx, m, wcidx))
467 return (0);
468 /* match part right of wildcard */
469 delta = mdot1idx - wcidx - 1;
470 if (!fetch_ssl_hname_equal(hdot - delta, delta,
471 mdot1 - delta, delta))
472 return (0);
473 /* all tests succeded, it's a match */
474 return (1);
475}
476
477/*
478 * Get numeric host address info - returns NULL if host was not an IP
479 * address. The caller is responsible for deallocation using
480 * freeaddrinfo(3).
481 */
482static struct addrinfo *
483fetch_ssl_get_numeric_addrinfo(const char *hostname, size_t len)
484{
485 struct addrinfo hints, *res;
486 char *host;
487
488 host = (char *)malloc(len + 1);
489 memcpy(host, hostname, len);
490 host[len] = '\0';
491 memset(&hints, 0, sizeof(hints));
492 hints.ai_family = PF_UNSPEC;
493 hints.ai_socktype = SOCK_STREAM;
494 hints.ai_protocol = 0;
495 hints.ai_flags = AI_NUMERICHOST;
496 /* port is not relevant for this purpose */
497 getaddrinfo(host, "443", &hints, &res);
498 free(host);
499 return res;
500}
501
502/*
503 * Compare ip address in addrinfo with address passes.
504 */
505static int
506fetch_ssl_ipaddr_match_bin(const struct addrinfo *lhost, const char *rhost,
507 size_t rhostlen)
508{
509 const void *left;
510
511 if (lhost->ai_family == AF_INET && rhostlen == 4) {
512 left = (void *)&((struct sockaddr_in*)(void *)
513 lhost->ai_addr)->sin_addr.s_addr;
514#ifdef INET6
515 } else if (lhost->ai_family == AF_INET6 && rhostlen == 16) {
516 left = (void *)&((struct sockaddr_in6 *)(void *)
517 lhost->ai_addr)->sin6_addr;
518#endif
519 } else
520 return (0);
521 return (!memcmp(left, (const void *)rhost, rhostlen) ? 1 : 0);
522}
523
524/*
525 * Compare ip address in addrinfo with host passed. If host is not an IP
526 * address, comparison will fail.
527 */
528static int
529fetch_ssl_ipaddr_match(const struct addrinfo *laddr, const char *r,
530 size_t rlen)
531{
532 struct addrinfo *raddr;
533 int ret;
534 char *rip;
535
536 ret = 0;
537 if ((raddr = fetch_ssl_get_numeric_addrinfo(r, rlen)) == NULL)
538 return 0; /* not a numeric host */
539
540 if (laddr->ai_family == raddr->ai_family) {
541 if (laddr->ai_family == AF_INET) {
542 rip = (char *)&((struct sockaddr_in *)(void *)
543 raddr->ai_addr)->sin_addr.s_addr;
544 ret = fetch_ssl_ipaddr_match_bin(laddr, rip, 4);
545#ifdef INET6
546 } else if (laddr->ai_family == AF_INET6) {
547 rip = (char *)&((struct sockaddr_in6 *)(void *)
548 raddr->ai_addr)->sin6_addr;
549 ret = fetch_ssl_ipaddr_match_bin(laddr, rip, 16);
550#endif
551 }
552
553 }
554 freeaddrinfo(raddr);
555 return (ret);
556}
557
558/*
559 * Verify server certificate by subjectAltName.
560 */
561static int
562fetch_ssl_verify_altname(STACK_OF(GENERAL_NAME) *altnames,
563 const char *host, struct addrinfo *ip)
564{
565 const GENERAL_NAME *name;
566 size_t nslen;
567 int i;
568 const char *ns;
569
570 for (i = 0; i < sk_GENERAL_NAME_num(altnames); ++i) {
571#if OPENSSL_VERSION_NUMBER < 0x10000000L
572 /*
573 * This is a workaround, since the following line causes
574 * alignment issues in clang:
575 * name = sk_GENERAL_NAME_value(altnames, i);
576 * OpenSSL explicitly warns not to use those macros
577 * directly, but there isn't much choice (and there
578 * shouldn't be any ill side effects)
579 */
580 name = (GENERAL_NAME *)SKM_sk_value(void, altnames, i);
581#else
582 name = sk_GENERAL_NAME_value(altnames, i);
583#endif
584 ns = (const char *)ASN1_STRING_data(name->d.ia5);
585 nslen = (size_t)ASN1_STRING_length(name->d.ia5);
586
587 if (name->type == GEN_DNS && ip == NULL &&
588 fetch_ssl_hname_match(host, strlen(host), ns, nslen))
589 return (1);
590 else if (name->type == GEN_IPADD && ip != NULL &&
591 fetch_ssl_ipaddr_match_bin(ip, ns, nslen))
592 return (1);
593 }
594 return (0);
595}
596
597/*
598 * Verify server certificate by CN.
599 */
600static int
601fetch_ssl_verify_cn(X509_NAME *subject, const char *host,
602 struct addrinfo *ip)
603{
604 ASN1_STRING *namedata;
605 X509_NAME_ENTRY *nameentry;
606 int cnlen, lastpos, loc, ret;
607 unsigned char *cn;
608
609 ret = 0;
610 lastpos = -1;
611 loc = -1;
612 cn = NULL;
613 /* get most specific CN (last entry in list) and compare */
614 while ((lastpos = X509_NAME_get_index_by_NID(subject,
615 NID_commonName, lastpos)) != -1)
616 loc = lastpos;
617
618 if (loc > -1) {
619 nameentry = X509_NAME_get_entry(subject, loc);
620 namedata = X509_NAME_ENTRY_get_data(nameentry);
621 cnlen = ASN1_STRING_to_UTF8(&cn, namedata);
622 if (ip == NULL &&
623 fetch_ssl_hname_match(host, strlen(host), cn, cnlen))
624 ret = 1;
625 else if (ip != NULL && fetch_ssl_ipaddr_match(ip, cn, cnlen))
626 ret = 1;
627 OPENSSL_free(cn);
628 }
629 return (ret);
630}
631
632/*
633 * Verify that server certificate subjectAltName/CN matches
634 * hostname. First check, if there are alternative subject names. If yes,
635 * those have to match. Only if those don't exist it falls back to
636 * checking the subject's CN.
637 */
638static int
639fetch_ssl_verify_hname(X509 *cert, const char *host)
640{
641 struct addrinfo *ip;
642 STACK_OF(GENERAL_NAME) *altnames;
643 X509_NAME *subject;
644 int ret;
645
646 ret = 0;
647 ip = fetch_ssl_get_numeric_addrinfo(host, strlen(host));
648 altnames = X509_get_ext_d2i(cert, NID_subject_alt_name,
649 NULL, NULL);
650
651 if (altnames != NULL) {
652 ret = fetch_ssl_verify_altname(altnames, host, ip);
653 } else {
654 subject = X509_get_subject_name(cert);
655 if (subject != NULL)
656 ret = fetch_ssl_verify_cn(subject, host, ip);
657 }
658
659 if (ip != NULL)
660 freeaddrinfo(ip);
661 if (altnames != NULL)
662 GENERAL_NAMES_free(altnames);
663 return (ret);
664}
665
666/*
667 * Configure transport security layer based on environment.
668 */
669static void
670fetch_ssl_setup_transport_layer(SSL_CTX *ctx, int verbose)
671{
672 long ssl_ctx_options;
673
674 ssl_ctx_options = SSL_OP_ALL | SSL_OP_NO_TICKET;
675 if (getenv("SSL_ALLOW_SSL2") == NULL)
676 ssl_ctx_options |= SSL_OP_NO_SSLv2;
677 if (getenv("SSL_NO_SSL3") != NULL)
678 ssl_ctx_options |= SSL_OP_NO_SSLv3;
679 if (getenv("SSL_NO_TLS1") != NULL)
680 ssl_ctx_options |= SSL_OP_NO_TLSv1;
681 if (verbose)
682 fetch_info("SSL options: %x", ssl_ctx_options);
683 SSL_CTX_set_options(ctx, ssl_ctx_options);
684}
685
686
687/*
688 * Configure peer verification based on environment.
689 */
690static int
691fetch_ssl_setup_peer_verification(SSL_CTX *ctx, int verbose)
692{
693 X509_LOOKUP *crl_lookup;
694 X509_STORE *crl_store;
695 const char *ca_cert_file, *ca_cert_path, *crl_file;
696
697 if (getenv("SSL_NO_VERIFY_PEER") == NULL) {
698 ca_cert_file = getenv("SSL_CA_CERT_FILE") != NULL ?
699 getenv("SSL_CA_CERT_FILE") : "/etc/ssl/cert.pem";
700 ca_cert_path = getenv("SSL_CA_CERT_PATH");
701 if (verbose) {
702 fetch_info("Peer verification enabled");
703 if (ca_cert_file != NULL)
704 fetch_info("Using CA cert file: %s",
705 ca_cert_file);
706 if (ca_cert_path != NULL)
707 fetch_info("Using CA cert path: %s",
708 ca_cert_path);
709 }
710 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER,
711 fetch_ssl_cb_verify_crt);
712 SSL_CTX_load_verify_locations(ctx, ca_cert_file,
713 ca_cert_path);
714 if ((crl_file = getenv("SSL_CRL_FILE")) != NULL) {
715 if (verbose)
716 fetch_info("Using CRL file: %s", crl_file);
717 crl_store = SSL_CTX_get_cert_store(ctx);
718 crl_lookup = X509_STORE_add_lookup(crl_store,
719 X509_LOOKUP_file());
720 if (crl_lookup == NULL ||
721 !X509_load_crl_file(crl_lookup, crl_file,
722 X509_FILETYPE_PEM)) {
723 fprintf(stderr,
724 "Could not load CRL file %s\n",
725 crl_file);
726 return (0);
727 }
728 X509_STORE_set_flags(crl_store,
729 X509_V_FLAG_CRL_CHECK |
730 X509_V_FLAG_CRL_CHECK_ALL);
731 }
732 }
733 return (1);
734}
735
736/*
737 * Configure client certificate based on environment.
738 */
739static int
740fetch_ssl_setup_client_certificate(SSL_CTX *ctx, int verbose)
741{
742 const char *client_cert_file, *client_key_file;
743
744 if ((client_cert_file = getenv("SSL_CLIENT_CERT_FILE")) != NULL) {
745 client_key_file = getenv("SSL_CLIENT_KEY_FILE") != NULL ?
746 getenv("SSL_CLIENT_KEY_FILE") : client_cert_file;
747 if (verbose) {
748 fetch_info("Using client cert file: %s",
749 client_cert_file);
750 fetch_info("Using client key file: %s",
751 client_key_file);
752 }
753 if (SSL_CTX_use_certificate_chain_file(ctx,
754 client_cert_file) != 1) {
755 fprintf(stderr,
756 "Could not load client certificate %s\n",
757 client_cert_file);
758 return (0);
759 }
760 if (SSL_CTX_use_PrivateKey_file(ctx, client_key_file,
761 SSL_FILETYPE_PEM) != 1) {
762 fprintf(stderr,
763 "Could not load client key %s\n",
764 client_key_file);
765 return (0);
766 }
767 }
768 return (1);
769}
770
771/*
772 * Callback for SSL certificate verification, this is called on server
773 * cert verification. It takes no decision, but informs the user in case
774 * verification failed.
775 */
776int
777fetch_ssl_cb_verify_crt(int verified, X509_STORE_CTX *ctx)
778{
779 X509 *crt;
780 X509_NAME *name;
781 char *str;
782
783 str = NULL;
784 if (!verified) {
785 if ((crt = X509_STORE_CTX_get_current_cert(ctx)) != NULL &&
786 (name = X509_get_subject_name(crt)) != NULL)
787 str = X509_NAME_oneline(name, 0, 0);
788 fprintf(stderr, "Certificate verification failed for %s\n",
789 str != NULL ? str : "no relevant certificate");
790 OPENSSL_free(str);
791 }
792 return (verified);
793}
794
795#endif
796
797/*
322 * Enable SSL on a connection.
323 */
324int
798 * Enable SSL on a connection.
799 */
800int
325fetch_ssl(conn_t *conn, int verbose)
801fetch_ssl(conn_t *conn, const struct url *URL, int verbose)
326{
327#ifdef WITH_SSL
328 int ret, ssl_err;
802{
803#ifdef WITH_SSL
804 int ret, ssl_err;
805 X509_NAME *name;
806 char *str;
329
330 /* Init the SSL library and context */
331 if (!SSL_library_init()){
332 fprintf(stderr, "SSL library init failed\n");
333 return (-1);
334 }
335
336 SSL_load_error_strings();
337
338 conn->ssl_meth = SSLv23_client_method();
339 conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth);
340 SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY);
341
807
808 /* Init the SSL library and context */
809 if (!SSL_library_init()){
810 fprintf(stderr, "SSL library init failed\n");
811 return (-1);
812 }
813
814 SSL_load_error_strings();
815
816 conn->ssl_meth = SSLv23_client_method();
817 conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth);
818 SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY);
819
820 fetch_ssl_setup_transport_layer(conn->ssl_ctx, verbose);
821 if (!fetch_ssl_setup_peer_verification(conn->ssl_ctx, verbose))
822 return (-1);
823 if (!fetch_ssl_setup_client_certificate(conn->ssl_ctx, verbose))
824 return (-1);
825
342 conn->ssl = SSL_new(conn->ssl_ctx);
826 conn->ssl = SSL_new(conn->ssl_ctx);
343 if (conn->ssl == NULL){
827 if (conn->ssl == NULL) {
344 fprintf(stderr, "SSL context creation failed\n");
345 return (-1);
346 }
347 SSL_set_fd(conn->ssl, conn->sd);
348 while ((ret = SSL_connect(conn->ssl)) == -1) {
349 ssl_err = SSL_get_error(conn->ssl, ret);
350 if (ssl_err != SSL_ERROR_WANT_READ &&
351 ssl_err != SSL_ERROR_WANT_WRITE) {
352 ERR_print_errors_fp(stderr);
353 return (-1);
354 }
355 }
828 fprintf(stderr, "SSL context creation failed\n");
829 return (-1);
830 }
831 SSL_set_fd(conn->ssl, conn->sd);
832 while ((ret = SSL_connect(conn->ssl)) == -1) {
833 ssl_err = SSL_get_error(conn->ssl, ret);
834 if (ssl_err != SSL_ERROR_WANT_READ &&
835 ssl_err != SSL_ERROR_WANT_WRITE) {
836 ERR_print_errors_fp(stderr);
837 return (-1);
838 }
839 }
840 conn->ssl_cert = SSL_get_peer_certificate(conn->ssl);
356
841
357 if (verbose) {
358 X509_NAME *name;
359 char *str;
842 if (conn->ssl_cert == NULL) {
843 fprintf(stderr, "No server SSL certificate\n");
844 return (-1);
845 }
360
846
361 fprintf(stderr, "SSL connection established using %s\n",
847 if (getenv("SSL_NO_VERIFY_HOSTNAME") == NULL) {
848 if (verbose)
849 fetch_info("Verify hostname");
850 if (!fetch_ssl_verify_hname(conn->ssl_cert, URL->host)) {
851 fprintf(stderr,
852 "SSL certificate subject doesn't match host %s\n",
853 URL->host);
854 return (-1);
855 }
856 }
857
858 if (verbose) {
859 fetch_info("SSL connection established using %s",
362 SSL_get_cipher(conn->ssl));
860 SSL_get_cipher(conn->ssl));
363 conn->ssl_cert = SSL_get_peer_certificate(conn->ssl);
364 name = X509_get_subject_name(conn->ssl_cert);
365 str = X509_NAME_oneline(name, 0, 0);
861 name = X509_get_subject_name(conn->ssl_cert);
862 str = X509_NAME_oneline(name, 0, 0);
366 printf("Certificate subject: %s\n", str);
367 free(str);
863 fetch_info("Certificate subject: %s", str);
864 OPENSSL_free(str);
368 name = X509_get_issuer_name(conn->ssl_cert);
369 str = X509_NAME_oneline(name, 0, 0);
865 name = X509_get_issuer_name(conn->ssl_cert);
866 str = X509_NAME_oneline(name, 0, 0);
370 printf("Certificate issuer: %s\n", str);
371 free(str);
867 fetch_info("Certificate issuer: %s", str);
868 OPENSSL_free(str);
372 }
373
374 return (0);
375#else
376 (void)conn;
377 (void)verbose;
378 fprintf(stderr, "SSL support disabled\n");
379 return (-1);

--- 341 unchanged lines hidden (view full) ---

721 */
722int
723fetch_close(conn_t *conn)
724{
725 int ret;
726
727 if (--conn->ref > 0)
728 return (0);
869 }
870
871 return (0);
872#else
873 (void)conn;
874 (void)verbose;
875 fprintf(stderr, "SSL support disabled\n");
876 return (-1);

--- 341 unchanged lines hidden (view full) ---

1218 */
1219int
1220fetch_close(conn_t *conn)
1221{
1222 int ret;
1223
1224 if (--conn->ref > 0)
1225 return (0);
1226#ifdef WITH_SSL
1227 if (conn->ssl) {
1228 SSL_shutdown(conn->ssl);
1229 SSL_set_connect_state(conn->ssl);
1230 SSL_free(conn->ssl);
1231 conn->ssl = NULL;
1232 }
1233 if (conn->ssl_ctx) {
1234 SSL_CTX_free(conn->ssl_ctx);
1235 conn->ssl_ctx = NULL;
1236 }
1237 if (conn->ssl_cert) {
1238 X509_free(conn->ssl_cert);
1239 conn->ssl_cert = NULL;
1240 }
1241#endif
729 ret = close(conn->sd);
730 free(conn->cache.buf);
731 free(conn->buf);
732 free(conn);
733 return (ret);
734}
735
736

--- 171 unchanged lines hidden ---
1242 ret = close(conn->sd);
1243 free(conn->cache.buf);
1244 free(conn->buf);
1245 free(conn);
1246 return (ret);
1247}
1248
1249

--- 171 unchanged lines hidden ---