From ce6d4c4a6e426fbee036993034abddf7975be771 Mon Sep 17 00:00:00 2001 From: des Date: Wed, 5 Jun 2002 12:46:36 +0000 Subject: Add SSL support + slight cleanup. Submitted by: Henry Whincup (in principle) --- lib/libfetch/common.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- lib/libfetch/common.h | 5 +++-- lib/libfetch/fetch.c | 36 ++++++++++++++++++++---------------- lib/libfetch/http.c | 7 ++++++- 4 files changed, 78 insertions(+), 20 deletions(-) diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index 6f49709..775b4c7 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include /* XXX */ #include #include #include @@ -265,6 +264,55 @@ _fetch_connect(const char *host, int port, int af, int verbose) /* + * Enable SSL on a connection. + */ +int +_fetch_ssl(conn_t *conn, int verbose) +{ + + /* Init the SSL library and context */ + if (!SSL_library_init()){ + fprintf(stderr, "SSL library init failed\n"); + return (-1); + } + + SSL_load_error_strings(); + + conn->ssl_meth = SSLv23_client_method(); + conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth); + + conn->ssl = SSL_new(conn->ssl_ctx); + if (conn->ssl == NULL){ + fprintf(stderr, "SSL context creation failed\n"); + return (-1); + } + SSL_set_fd(conn->ssl, conn->sd); + if (SSL_connect(conn->ssl) == -1){ + ERR_print_errors_fp(stderr); + return (-1); + } + + if (verbose) { + X509_NAME *name; + char *str; + + fprintf(stderr, "SSL connection established using %s\n", + SSL_get_cipher(conn->ssl)); + conn->ssl_cert = SSL_get_peer_certificate(conn->ssl); + name = X509_get_subject_name(conn->ssl_cert); + str = X509_NAME_oneline(name, 0, 0); + printf("Certificate subject: %s\n", str); + free(str); + name = X509_get_issuer_name(conn->ssl_cert); + str = X509_NAME_oneline(name, 0, 0); + printf("Certificate issuer: %s\n", str); + free(str); + } + + return (0); +} + +/* * Read a character from a connection w/ timeout */ ssize_t diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h index 8b2a026..06a805f 100644 --- a/lib/libfetch/common.h +++ b/lib/libfetch/common.h @@ -57,7 +57,7 @@ struct fetchconn { }; /* Structure used for error message lists */ -struct fetcherr { +struct fetcherr { const int num; const int cat; const char *string; @@ -69,7 +69,8 @@ void _fetch_info(const char *, ...); int _fetch_default_port(const char *); int _fetch_default_proxy_port(const char *); conn_t *_fetch_connect(const char *, int, int, int); -conn_t *_fetch_reopen(int sd); +conn_t *_fetch_reopen(int); +int _fetch_ssl(conn_t *, int); ssize_t _fetch_read(conn_t *, char *, size_t); int _fetch_getln(conn_t *); ssize_t _fetch_write(conn_t *, const char *, size_t); diff --git a/lib/libfetch/fetch.c b/lib/libfetch/fetch.c index 33b9787..394c39a 100644 --- a/lib/libfetch/fetch.c +++ b/lib/libfetch/fetch.c @@ -79,14 +79,14 @@ fetchXGet(struct url *URL, struct url_stat *us, const char *flags) direct = CHECK_FLAG('d'); if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) return (fetchXGetFile(URL, us, flags)); + else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) + return (fetchXGetFTP(URL, us, flags)); else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) return (fetchXGetHTTP(URL, us, flags)); - else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { - return (fetchXGetFTP(URL, us, flags)); - } else { - _url_seterr(URL_BAD_SCHEME); - return (NULL); - } + else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0) + return (fetchXGetHTTP(URL, us, flags)); + _url_seterr(URL_BAD_SCHEME); + return (NULL); } /* @@ -111,14 +111,14 @@ fetchPut(struct url *URL, const char *flags) direct = CHECK_FLAG('d'); if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) return (fetchPutFile(URL, flags)); + else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) + return (fetchPutFTP(URL, flags)); else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) return (fetchPutHTTP(URL, flags)); - else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { - return (fetchPutFTP(URL, flags)); - } else { - _url_seterr(URL_BAD_SCHEME); - return (NULL); - } + else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0) + return (fetchPutHTTP(URL, flags)); + _url_seterr(URL_BAD_SCHEME); + return (NULL); } /* @@ -133,10 +133,12 @@ fetchStat(struct url *URL, struct url_stat *us, const char *flags) direct = CHECK_FLAG('d'); if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) return (fetchStatFile(URL, us, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) - return (fetchStatHTTP(URL, us, flags)); else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) return (fetchStatFTP(URL, us, flags)); + else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) + return (fetchStatHTTP(URL, us, flags)); + else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0) + return (fetchStatHTTP(URL, us, flags)); _url_seterr(URL_BAD_SCHEME); return (-1); } @@ -153,10 +155,12 @@ fetchList(struct url *URL, const char *flags) direct = CHECK_FLAG('d'); if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) return (fetchListFile(URL, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) - return (fetchListHTTP(URL, flags)); else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) return (fetchListFTP(URL, flags)); + else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) + return (fetchListHTTP(URL, flags)); + else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0) + return (fetchListHTTP(URL, flags)); _url_seterr(URL_BAD_SCHEME); return (NULL); } diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index 8639e00..7b897a8 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -669,7 +669,7 @@ _http_connect(struct url *URL, struct url *purl, const char *flags) af = AF_INET6; #endif - if (purl) { + if (purl && strcasecmp(URL->scheme, SCHEME_HTTPS) != 0) { URL = purl; } else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { /* can't talk http to an ftp server */ @@ -680,6 +680,11 @@ _http_connect(struct url *URL, struct url *purl, const char *flags) if ((conn = _fetch_connect(URL->host, URL->port, af, verbose)) == NULL) /* _fetch_connect() has already set an error code */ return (NULL); + if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && + _fetch_ssl(conn, verbose) == -1) { + _fetch_close(conn); + return (NULL); + } return (conn); } -- cgit v1.1