Add SSL support + slight cleanup.
Submitted by: Henry Whincup <henry@techiebod.com> (in principle)
This commit is contained in:
parent
080ef30b20
commit
111e251009
@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include <ctype.h> /* XXX */
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -264,6 +263,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
|
* Read a character from a connection w/ timeout
|
||||||
*/
|
*/
|
||||||
|
@ -57,7 +57,7 @@ struct fetchconn {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Structure used for error message lists */
|
/* Structure used for error message lists */
|
||||||
struct fetcherr {
|
struct fetcherr {
|
||||||
const int num;
|
const int num;
|
||||||
const int cat;
|
const int cat;
|
||||||
const char *string;
|
const char *string;
|
||||||
@ -69,7 +69,8 @@ void _fetch_info(const char *, ...);
|
|||||||
int _fetch_default_port(const char *);
|
int _fetch_default_port(const char *);
|
||||||
int _fetch_default_proxy_port(const char *);
|
int _fetch_default_proxy_port(const char *);
|
||||||
conn_t *_fetch_connect(const char *, int, int, int);
|
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);
|
ssize_t _fetch_read(conn_t *, char *, size_t);
|
||||||
int _fetch_getln(conn_t *);
|
int _fetch_getln(conn_t *);
|
||||||
ssize_t _fetch_write(conn_t *, const char *, size_t);
|
ssize_t _fetch_write(conn_t *, const char *, size_t);
|
||||||
|
@ -79,14 +79,14 @@ fetchXGet(struct url *URL, struct url_stat *us, const char *flags)
|
|||||||
direct = CHECK_FLAG('d');
|
direct = CHECK_FLAG('d');
|
||||||
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
||||||
return (fetchXGetFile(URL, us, flags));
|
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)
|
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
|
||||||
return (fetchXGetHTTP(URL, us, flags));
|
return (fetchXGetHTTP(URL, us, flags));
|
||||||
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) {
|
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
|
||||||
return (fetchXGetFTP(URL, us, flags));
|
return (fetchXGetHTTP(URL, us, flags));
|
||||||
} else {
|
_url_seterr(URL_BAD_SCHEME);
|
||||||
_url_seterr(URL_BAD_SCHEME);
|
return (NULL);
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -111,14 +111,14 @@ fetchPut(struct url *URL, const char *flags)
|
|||||||
direct = CHECK_FLAG('d');
|
direct = CHECK_FLAG('d');
|
||||||
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
||||||
return (fetchPutFile(URL, flags));
|
return (fetchPutFile(URL, flags));
|
||||||
|
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
|
||||||
|
return (fetchPutFTP(URL, flags));
|
||||||
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
|
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
|
||||||
return (fetchPutHTTP(URL, flags));
|
return (fetchPutHTTP(URL, flags));
|
||||||
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) {
|
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
|
||||||
return (fetchPutFTP(URL, flags));
|
return (fetchPutHTTP(URL, flags));
|
||||||
} else {
|
_url_seterr(URL_BAD_SCHEME);
|
||||||
_url_seterr(URL_BAD_SCHEME);
|
return (NULL);
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -133,10 +133,12 @@ fetchStat(struct url *URL, struct url_stat *us, const char *flags)
|
|||||||
direct = CHECK_FLAG('d');
|
direct = CHECK_FLAG('d');
|
||||||
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
||||||
return (fetchStatFile(URL, us, flags));
|
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)
|
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
|
||||||
return (fetchStatFTP(URL, us, flags));
|
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);
|
_url_seterr(URL_BAD_SCHEME);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
@ -153,10 +155,12 @@ fetchList(struct url *URL, const char *flags)
|
|||||||
direct = CHECK_FLAG('d');
|
direct = CHECK_FLAG('d');
|
||||||
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
||||||
return (fetchListFile(URL, flags));
|
return (fetchListFile(URL, flags));
|
||||||
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
|
|
||||||
return (fetchListHTTP(URL, flags));
|
|
||||||
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
|
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
|
||||||
return (fetchListFTP(URL, flags));
|
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);
|
_url_seterr(URL_BAD_SCHEME);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
@ -669,7 +669,7 @@ _http_connect(struct url *URL, struct url *purl, const char *flags)
|
|||||||
af = AF_INET6;
|
af = AF_INET6;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (purl) {
|
if (purl && strcasecmp(URL->scheme, SCHEME_HTTPS) != 0) {
|
||||||
URL = purl;
|
URL = purl;
|
||||||
} else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) {
|
} else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) {
|
||||||
/* can't talk http to an ftp server */
|
/* 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)
|
if ((conn = _fetch_connect(URL->host, URL->port, af, verbose)) == NULL)
|
||||||
/* _fetch_connect() has already set an error code */
|
/* _fetch_connect() has already set an error code */
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 &&
|
||||||
|
_fetch_ssl(conn, verbose) == -1) {
|
||||||
|
_fetch_close(conn);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
return (conn);
|
return (conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user