X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=starttls.c;h=a3ddf945f9856d5f744f8fa2a6ec3ff9c31f0444;hb=bcbb663d3249baf4731ce670fef341da10655f54;hp=93c562bbbc3cfed805f501075271d2be168dd244;hpb=4ec76228a26794f600159f572e4a98b1cf46d5ff;p=elisp%2Fstarttls.git diff --git a/starttls.c b/starttls.c index 93c562b..a3ddf94 100644 --- a/starttls.c +++ b/starttls.c @@ -29,20 +29,11 @@ #include #include #include +#include #include -#include -#include -#include -#include -#include -#include - -#ifdef NEED_ADDRINFO_H -#include "addrinfo.h" -#endif - +#include #include #include #include @@ -56,144 +47,78 @@ #ifdef HAVE_POLL_H #include #endif -#define _GNU_SOURCE -#include +#include "getopt.h" +#include "getaddrinfo.h" +#include "gettext.h" +#include "inet_ntop.h" +#include "strdup.h" -static SSL_CTX *tls_ctx = NULL; -static SSL *tls_conn = NULL; -static int tls_fd; +extern void tls_negotiate (int, const char *, const char *); +extern int tls_write(int, const char *, int); +extern int tls_read(int, char *, int); +extern int tls_pending(); static char *opt_cert_file = NULL, *opt_key_file = NULL; -static int opt_verify = 0; +static int tls_fd; -static int -tls_ssl_ctx_new (cert_file, key_file) - const char *cert_file, *key_file; +static void +usage (progname) + const char *progname; { - SSL_load_error_strings (); - SSLeay_add_ssl_algorithms (); - - tls_ctx = SSL_CTX_new (TLSv1_client_method()); - if (!tls_ctx) - return -1; - - SSL_CTX_set_options (tls_ctx, SSL_OP_ALL /* Work around all known bugs */); - - if (cert_file) - { - if (SSL_CTX_use_certificate_file (tls_ctx, cert_file, - SSL_FILETYPE_PEM) <= 0) - return -1; - if (!key_file) - key_file = cert_file; - if (SSL_CTX_use_PrivateKey_file (tls_ctx, key_file, - SSL_FILETYPE_PEM) <= 0) - return -1; - if (!SSL_CTX_check_private_key (tls_ctx)) - return -1; - } - - SSL_CTX_set_verify (tls_ctx, SSL_VERIFY_NONE, NULL); - - return 0; + printf ("%s (%s) %s\n" + "Copyright (C) 1999 Free Software Foundation, Inc.\n" + "This program comes with ABSOLUTELY NO WARRANTY.\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions. See the file COPYING for details.\n\n" + "Usage: %s [options] host port\n\n" + "Options:\n\n" + " --cert-file [file] specify certificate file\n" + " --key-file [file] specify private key file\n", + progname, PACKAGE, VERSION, progname); } -static int -tls_ssl_new(ctx, s) - SSL_CTX *ctx; - int s; +static void +do_tls_negotiate(sig) + int sig; { - SSL_SESSION *session; - SSL_CIPHER *cipher; - X509 *peer; - - tls_conn = (SSL *) SSL_new (ctx); - if (!tls_conn) - return -1; - SSL_clear(tls_conn); - - if (!SSL_set_fd (tls_conn, s)) - return -1; - - SSL_set_connect_state (tls_conn); - - if (SSL_connect (tls_conn) <= 0) - { - session = SSL_get_session (tls_conn); - if (session) - SSL_CTX_remove_session (ctx, session); - if (tls_conn!=NULL) - SSL_free (tls_conn); - return -1; - } - - return 0; + tls_negotiate(tls_fd, opt_cert_file, opt_key_file); } -static int -tls_connect (hostname, service) +int +tcp_connect (hostname, service) const char *hostname, *service; { - struct protoent *proto; - struct addrinfo *in, hints; - int server, false = 0; - - proto = getprotobyname ("tcp"); - if (!proto) - return -1; + int server, _false = 0; + struct addrinfo *in, *in0, hints; memset (&hints, 0, sizeof (hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = proto->p_proto; - - if (getaddrinfo (hostname, service, &hints, &in) < 0) + if (getaddrinfo (hostname, service, &hints, &in0)) return -1; - server = socket (in->ai_family, in->ai_socktype, 0); - if (server < 0) - return -1; + for (in = in0; in; in = in->ai_next) + { + server = socket (in->ai_family, in->ai_socktype, in->ai_protocol); + if (server < 0) + continue; + if (connect (server, in->ai_addr, in->ai_addrlen) < 0) + { + server = -1; + continue; + } + break; + } - if (setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, - (const char *) &false, sizeof (false))) + if (server < 0) return -1; - if (connect (server, in->ai_addr, in->ai_addrlen) < 0) - { - close (server); - return -1; - } + setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, (const char *) &_false, + sizeof (_false)); return server; } -static void -tls_negotiate (sig) - int sig; -{ - if (tls_ssl_ctx_new (opt_cert_file, opt_key_file) == -1) - return; - - (void) tls_ssl_new (tls_ctx, tls_fd); /* Negotiation has done. */ -} - -static void -usage (progname) - const char *progname; -{ - printf ("%s (%s) %s\n" - "Copyright (C) 1999 Free Software Foundation, Inc.\n" - "This program comes with ABSOLUTELY NO WARRANTY.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions. See the file COPYING for details.\n\n" - "Usage: %s [options] host port\n\n" - "Options:\n\n" - " --cert-file [file] specify certificate file\n" - " --key-file [file] specify private key file\n" - " --verify [level] set verification level\n", - progname, PACKAGE, VERSION, progname); -} - int main (argc, argv) int argc; @@ -215,13 +140,12 @@ main (argc, argv) { {"cert-file", 1, 0, 'c'}, {"key-file", 1, 0, 'k'}, - {"verify", 1, 0, 'v'}, {0, 0, 0, 0} }; while (1) { - c = getopt_long (argc, argv, "c:k:v:f", long_options, &option_index); + c = getopt_long (argc, argv, "c:k:", long_options, &option_index); if (c == -1) break; @@ -233,30 +157,27 @@ main (argc, argv) case 'k': opt_key_file = optarg; break; - case 'v': - opt_verify = atoi (optarg); - break; default: - usage (basename (argv[0])); + usage (argv[0]); return 1; } } if (optind+2 != argc) { - usage (basename (argv[0])); + usage (argv[0]); return 1; } - tls_fd = tls_connect (argv[optind], argv[optind+1]); + tls_fd = tcp_connect (argv[optind], argv[optind+1]); if (tls_fd < 0) { - perror ("tls_connect"); + perror ("tcp_connect"); return 1; } memset (&act, 0, sizeof (act)); - act.sa_handler = tls_negotiate; + act.sa_handler = do_tls_negotiate; sigemptyset (&act.sa_mask); act.sa_flags = SA_RESTART|SA_RESETHAND; sigaction (SIGALRM, &act, NULL); @@ -308,10 +229,7 @@ main (argc, argv) perror ("poll"); return 1; } - if (tls_conn) - wrote = SSL_write (tls_conn, retry, nbuffer); - else - wrote = write (tls_fd, retry, nbuffer); + wrote = tls_write(tls_fd, retry, nbuffer); if (wrote < 0) goto finish; } } @@ -321,10 +239,8 @@ main (argc, argv) if (FD_ISSET (tls_fd, &readfds)) #endif { - if (tls_conn) - nbuffer = SSL_read (tls_conn, buffer, sizeof buffer -1); - else - nbuffer = read (tls_fd, buffer, sizeof buffer -1); +readtop: + nbuffer = tls_read(tls_fd, buffer, sizeof buffer -1); if (nbuffer == 0) goto finish; for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote) @@ -344,6 +260,8 @@ main (argc, argv) wrote = write (out, retry, nbuffer); if (wrote < 0) goto finish; } + if (tls_pending()) + goto readtop; } }