diff options
author | Russ Cox <rsc@swtch.com> | 2008-08-03 07:42:27 -0700 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2008-08-03 07:42:27 -0700 |
commit | 18824b586835525594cde126fbc90b8281d5af8b (patch) | |
tree | e8b69c05eda4543b6d2f3d30777abe6109b48b7f /src/cmd/smugfs/openssl.c | |
parent | 3d36f4437348227c5bad62587dc12b5fd4a3e95e (diff) | |
download | plan9port-18824b586835525594cde126fbc90b8281d5af8b.tar.gz plan9port-18824b586835525594cde126fbc90b8281d5af8b.tar.bz2 plan9port-18824b586835525594cde126fbc90b8281d5af8b.zip |
smugfs(4): new program
Diffstat (limited to 'src/cmd/smugfs/openssl.c')
-rw-r--r-- | src/cmd/smugfs/openssl.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/cmd/smugfs/openssl.c b/src/cmd/smugfs/openssl.c new file mode 100644 index 00000000..baccd3ac --- /dev/null +++ b/src/cmd/smugfs/openssl.c @@ -0,0 +1,98 @@ +#include <u.h> +#include <openssl/bio.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include "a.h" + +AUTOLIB(ssl) + +static void +httpsinit(void) +{ + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); + SSL_load_error_strings(); + SSL_library_init(); +} + +struct Pfd +{ + BIO *sbio; +}; + +static Pfd* +opensslconnect(char *host) +{ + Pfd *pfd; + BIO *sbio; + SSL_CTX *ctx; + SSL *ssl; + static int didinit; + char buf[1024]; + + if(!didinit){ + httpsinit(); + didinit = 1; + } + + ctx = SSL_CTX_new(SSLv23_client_method()); + sbio = BIO_new_ssl_connect(ctx); + BIO_get_ssl(sbio, &ssl); + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + + snprint(buf, sizeof buf, "%s:https", host); + BIO_set_conn_hostname(sbio, buf); + + if(BIO_do_connect(sbio) <= 0 || BIO_do_handshake(sbio) <= 0){ + ERR_error_string_n(ERR_get_error(), buf, sizeof buf); + BIO_free_all(sbio); + werrstr("openssl: %s", buf); + return nil; + } + + pfd = emalloc(sizeof *pfd); + pfd->sbio = sbio; + return pfd; +} + +static void +opensslclose(Pfd *pfd) +{ + if(pfd == nil) + return; + BIO_free_all(pfd->sbio); + free(pfd); +} + +static int +opensslwrite(Pfd *pfd, void *v, int n) +{ + int m, total; + char *p; + + p = v; + total = 0; + while(total < n){ + if((m = BIO_write(pfd->sbio, p+total, n-total)) <= 0){ + if(total == 0) + return m; + return total; + } + total += m; + } + return total; +} + +static int +opensslread(Pfd *pfd, void *v, int n) +{ + return BIO_read(pfd->sbio, v, n); +} + +Protocol https = +{ + opensslconnect, + opensslread, + opensslwrite, + opensslclose +}; |