diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2010-10-01 22:59:02 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2010-10-01 22:59:02 +0000 |
commit | 367b2622e0527401666a65476f4111fdda2e3c12 (patch) | |
tree | dc507d2394eb3b616bd9eae56d17671899a24a05 /lib/libcrypto/bio | |
parent | ae9cbeba0dc25f0e95e6a0e50b6c161bf6384e17 (diff) |
resolve conflicts, fix local changes
Diffstat (limited to 'lib/libcrypto/bio')
-rw-r--r-- | lib/libcrypto/bio/Makefile.ssl | 216 | ||||
-rw-r--r-- | lib/libcrypto/bio/b_print.c | 9 | ||||
-rw-r--r-- | lib/libcrypto/bio/b_sock.c | 242 | ||||
-rw-r--r-- | lib/libcrypto/bio/bio.h | 64 | ||||
-rw-r--r-- | lib/libcrypto/bio/bio_cb.c | 24 | ||||
-rw-r--r-- | lib/libcrypto/bio/bio_err.c | 2 | ||||
-rw-r--r-- | lib/libcrypto/bio/bio_lib.c | 4 | ||||
-rw-r--r-- | lib/libcrypto/bio/bss_acpt.c | 8 | ||||
-rw-r--r-- | lib/libcrypto/bio/bss_dgram.c | 380 | ||||
-rw-r--r-- | lib/libcrypto/bio/bss_fd.c | 27 | ||||
-rw-r--r-- | lib/libcrypto/bio/bss_file.c | 67 | ||||
-rw-r--r-- | lib/libcrypto/bio/bss_log.c | 55 | ||||
-rw-r--r-- | lib/libcrypto/bio/bss_mem.c | 18 | ||||
-rw-r--r-- | lib/libcrypto/bio/bss_sock.c | 13 |
14 files changed, 688 insertions, 441 deletions
diff --git a/lib/libcrypto/bio/Makefile.ssl b/lib/libcrypto/bio/Makefile.ssl deleted file mode 100644 index d0b9e297b08..00000000000 --- a/lib/libcrypto/bio/Makefile.ssl +++ /dev/null @@ -1,216 +0,0 @@ -# -# SSLeay/crypto/bio/Makefile -# - -DIR= bio -TOP= ../.. -CC= cc -INCLUDES= -I.. -I$(TOP) -I../../include -CFLAG=-g -INSTALL_PREFIX= -OPENSSLDIR= /usr/local/ssl -INSTALLTOP=/usr/local/ssl -MAKE= make -f Makefile.ssl -MAKEDEPPROG= makedepend -MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) -MAKEFILE= Makefile.ssl -AR= ar r - -CFLAGS= $(INCLUDES) $(CFLAG) - -GENERAL=Makefile -TEST= -APPS= - -LIB=$(TOP)/libcrypto.a -LIBSRC= bio_lib.c bio_cb.c bio_err.c \ - bss_mem.c bss_null.c bss_fd.c \ - bss_file.c bss_sock.c bss_conn.c \ - bf_null.c bf_buff.c b_print.c b_dump.c \ - b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c -# bf_lbuf.c -LIBOBJ= bio_lib.o bio_cb.o bio_err.o \ - bss_mem.o bss_null.o bss_fd.o \ - bss_file.o bss_sock.o bss_conn.o \ - bf_null.o bf_buff.o b_print.o b_dump.o \ - b_sock.o bss_acpt.o bf_nbio.o bss_log.o bss_bio.o -# bf_lbuf.o - -SRC= $(LIBSRC) - -EXHEADER= bio.h -HEADER= bss_file.c $(EXHEADER) - -ALL= $(GENERAL) $(SRC) $(HEADER) - -top: - (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) - -all: lib - -lib: $(LIBOBJ) - $(AR) $(LIB) $(LIBOBJ) - $(RANLIB) $(LIB) || echo Never mind. - @touch lib - -files: - $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO - -links: - @sh $(TOP)/util/point.sh Makefile.ssl Makefile - @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) - @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) - @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) - -install: - @for i in $(EXHEADER); \ - do \ - (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ - chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ - done; - -tags: - ctags $(SRC) - -tests: - -lint: - lint -DLINT $(INCLUDES) $(SRC)>fluff - -depend: - $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) - -dclean: - $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new - mv -f Makefile.new $(MAKEFILE) - -clean: - rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -b_dump.o: ../../e_os.h ../../include/openssl/bio.h -b_dump.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -b_dump.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -b_dump.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -b_dump.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -b_dump.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -b_dump.o: ../cryptlib.h b_dump.c -b_print.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h -b_print.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -b_print.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -b_print.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -b_print.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -b_print.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -b_print.o: ../cryptlib.h b_print.c -b_sock.o: ../../e_os.h ../../include/openssl/bio.h -b_sock.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -b_sock.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -b_sock.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -b_sock.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -b_sock.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -b_sock.o: ../cryptlib.h b_sock.c -bf_buff.o: ../../e_os.h ../../include/openssl/bio.h -bf_buff.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bf_buff.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bf_buff.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bf_buff.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bf_buff.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bf_buff.o: ../cryptlib.h bf_buff.c -bf_nbio.o: ../../e_os.h ../../include/openssl/bio.h -bf_nbio.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bf_nbio.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bf_nbio.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bf_nbio.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h -bf_nbio.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h -bf_nbio.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bf_nbio.o: ../cryptlib.h bf_nbio.c -bf_null.o: ../../e_os.h ../../include/openssl/bio.h -bf_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bf_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bf_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bf_null.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bf_null.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bf_null.o: ../cryptlib.h bf_null.c -bio_cb.o: ../../e_os.h ../../include/openssl/bio.h -bio_cb.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bio_cb.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bio_cb.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bio_cb.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bio_cb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bio_cb.o: ../cryptlib.h bio_cb.c -bio_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h -bio_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bio_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bio_err.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bio_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bio_err.o: bio_err.c -bio_lib.o: ../../e_os.h ../../include/openssl/bio.h -bio_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bio_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bio_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bio_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bio_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bio_lib.o: ../cryptlib.h bio_lib.c -bss_acpt.o: ../../e_os.h ../../include/openssl/bio.h -bss_acpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bss_acpt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bss_acpt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bss_acpt.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bss_acpt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_acpt.o: ../cryptlib.h bss_acpt.c -bss_bio.o: ../../e_os.h ../../include/openssl/bio.h -bss_bio.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h -bss_bio.o: ../../include/openssl/err.h ../../include/openssl/lhash.h -bss_bio.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h -bss_bio.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_bio.o: ../../include/openssl/symhacks.h bss_bio.c -bss_conn.o: ../../e_os.h ../../include/openssl/bio.h -bss_conn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bss_conn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bss_conn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bss_conn.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bss_conn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_conn.o: ../cryptlib.h bss_conn.c -bss_fd.o: ../../e_os.h ../../include/openssl/bio.h -bss_fd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bss_fd.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bss_fd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bss_fd.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bss_fd.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_fd.o: ../cryptlib.h bss_fd.c -bss_file.o: ../../e_os.h ../../include/openssl/bio.h -bss_file.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bss_file.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bss_file.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bss_file.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bss_file.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_file.o: ../cryptlib.h bss_file.c -bss_log.o: ../../e_os.h ../../include/openssl/bio.h -bss_log.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bss_log.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bss_log.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bss_log.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bss_log.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_log.o: ../cryptlib.h bss_log.c -bss_mem.o: ../../e_os.h ../../include/openssl/bio.h -bss_mem.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bss_mem.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bss_mem.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bss_mem.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bss_mem.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_mem.o: ../cryptlib.h bss_mem.c -bss_null.o: ../../e_os.h ../../include/openssl/bio.h -bss_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bss_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bss_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bss_null.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bss_null.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_null.o: ../cryptlib.h bss_null.c -bss_sock.o: ../../e_os.h ../../include/openssl/bio.h -bss_sock.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -bss_sock.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h -bss_sock.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h -bss_sock.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h -bss_sock.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_sock.o: ../cryptlib.h bss_sock.c diff --git a/lib/libcrypto/bio/b_print.c b/lib/libcrypto/bio/b_print.c index 2fffcfc025a..143a7cfefa3 100644 --- a/lib/libcrypto/bio/b_print.c +++ b/lib/libcrypto/bio/b_print.c @@ -115,8 +115,8 @@ #define LDOUBLE double #endif -#if HAVE_LONG_LONG -# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__) +#ifdef HAVE_LONG_LONG +# if defined(_WIN32) && !defined(__GNUC__) # define LLONG __int64 # else # define LLONG long long @@ -808,7 +808,6 @@ int BIO_vprintf (BIO *bio, const char *format, va_list args) } /* As snprintf is not available everywhere, we provide our own implementation. - * In case of overflow or error, this returns -1. * This function has nothing to do with BIOs, but it's closely related * to BIO_printf, and we need *some* name prefix ... * (XXX the function should be renamed, but to what?) */ @@ -833,10 +832,10 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) _dopr(&buf, NULL, &n, &retlen, &truncated, format, args); if (truncated) - /* In case of truncation, return -1 unlike traditional snprintf. + /* In case of truncation, return -1 like traditional snprintf. * (Current drafts for ISO/IEC 9899 say snprintf should return * the number of characters that would have been written, - * had the buffer been large enough, as it did historically.) */ + * had the buffer been large enough.) */ return -1; else return (retlen <= INT_MAX) ? (int)retlen : -1; diff --git a/lib/libcrypto/bio/b_sock.c b/lib/libcrypto/bio/b_sock.c index ead477d8a29..12b0a53a81c 100644 --- a/lib/libcrypto/bio/b_sock.c +++ b/lib/libcrypto/bio/b_sock.c @@ -72,11 +72,9 @@ NETDB_DEFINE_CONTEXT #ifndef OPENSSL_NO_SOCK -#ifdef OPENSSL_SYS_WIN16 -#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ -#else +#include <openssl/dso.h> + #define SOCKET_PROTOCOL IPPROTO_TCP -#endif #ifdef SO_MAXCONN #define MAX_LISTEN SO_MAXCONN @@ -90,6 +88,17 @@ NETDB_DEFINE_CONTEXT static int wsa_init_done=0; #endif +/* + * WSAAPI specifier is required to make indirect calls to run-time + * linked WinSock 2 functions used in this module, to be specific + * [get|free]addrinfo and getnameinfo. This is because WinSock uses + * uses non-C calling convention, __stdcall vs. __cdecl, on x86 + * Windows. On non-WinSock platforms WSAAPI needs to be void. + */ +#ifndef WSAAPI +#define WSAAPI +#endif + #if 0 static unsigned long BIO_ghbn_hits=0L; static unsigned long BIO_ghbn_miss=0L; @@ -226,6 +235,10 @@ int BIO_sock_error(int sock) int j,i; int size; +#if defined(OPENSSL_SYS_BEOS_R5) + return 0; +#endif + size=sizeof(int); /* Note: under Windows the third parameter is of type (char *) * whereas under other systems it is (void *) if you don't have @@ -466,7 +479,12 @@ int BIO_sock_init(void) wsa_init_done=1; memset(&wsa_state,0,sizeof(wsa_state)); - if (WSAStartup(0x0101,&wsa_state)!=0) + /* Not making wsa_state available to the rest of the + * code is formally wrong. But the structures we use + * are [beleived to be] invariable among Winsock DLLs, + * while API availability is [expected to be] probed + * at run-time with DSO_global_lookup. */ + if (WSAStartup(0x0202,&wsa_state)!=0) { err=WSAGetLastError(); SYSerr(SYS_F_WSASTARTUP,err); @@ -510,8 +528,8 @@ void BIO_sock_cleanup(void) if (wsa_init_done) { wsa_init_done=0; -#ifndef OPENSSL_SYS_WINCE - WSACancelBlockingCall(); /* Winsock 1.1 specific */ +#if 0 /* this call is claimed to be non-present in Winsock2 */ + WSACancelBlockingCall(); #endif WSACleanup(); } @@ -581,12 +599,18 @@ static int get_ip(const char *str, unsigned char ip[4]) int BIO_get_accept_socket(char *host, int bind_mode) { int ret=0; - struct sockaddr_in server,client; - int s=INVALID_SOCKET,cs; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } server,client; + int s=INVALID_SOCKET,cs,addrlen; unsigned char ip[4]; unsigned short port; char *str=NULL,*e; - const char *h,*p; + char *h,*p; unsigned long l; int err_num; @@ -600,8 +624,7 @@ int BIO_get_accept_socket(char *host, int bind_mode) { if (*e == ':') { - p= &(e[1]); - *e='\0'; + p=e; } else if (*e == '/') { @@ -609,21 +632,70 @@ int BIO_get_accept_socket(char *host, int bind_mode) break; } } - - if (p == NULL) + if (p) *p++='\0'; /* points at last ':', '::port' is special [see below] */ + else p=h,h=NULL; + +#ifdef EAI_FAMILY + do { + static union { void *p; + int (WSAAPI *f)(const char *,const char *, + const struct addrinfo *, + struct addrinfo **); + } p_getaddrinfo = {NULL}; + static union { void *p; + void (WSAAPI *f)(struct addrinfo *); + } p_freeaddrinfo = {NULL}; + struct addrinfo *res,hint; + + if (p_getaddrinfo.p==NULL) + { + if ((p_getaddrinfo.p=DSO_global_lookup("getaddrinfo"))==NULL || + (p_freeaddrinfo.p=DSO_global_lookup("freeaddrinfo"))==NULL) + p_getaddrinfo.p=(void*)-1; + } + if (p_getaddrinfo.p==(void *)-1) break; + + /* '::port' enforces IPv6 wildcard listener. Some OSes, + * e.g. Solaris, default to IPv6 without any hint. Also + * note that commonly IPv6 wildchard socket can service + * IPv4 connections just as well... */ + memset(&hint,0,sizeof(hint)); + if (h) { - p=h; - h="*"; + if (strchr(h,':')) + { + if (h[1]=='\0') h=NULL; +#if OPENSSL_USE_IPV6 + hint.ai_family = AF_INET6; +#else + h=NULL; +#endif + } + else if (h[0]=='*' && h[1]=='\0') + h=NULL; } + if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break; + + addrlen = res->ai_addrlen<=sizeof(server) ? + res->ai_addrlen : + sizeof(server); + memcpy(&server, res->ai_addr, addrlen); + + (*p_freeaddrinfo.f)(res); + goto again; + } while (0); +#endif + if (!BIO_get_port(p,&port)) goto err; memset((char *)&server,0,sizeof(server)); - server.sin_family=AF_INET; - server.sin_port=htons(port); + server.sa_in.sin_family=AF_INET; + server.sa_in.sin_port=htons(port); + addrlen = sizeof(server.sa_in); - if (strcmp(h,"*") == 0) - server.sin_addr.s_addr=INADDR_ANY; + if (h == NULL || strcmp(h,"*") == 0) + server.sa_in.sin_addr.s_addr=INADDR_ANY; else { if (!BIO_get_host_ip(h,&(ip[0]))) goto err; @@ -632,11 +704,11 @@ int BIO_get_accept_socket(char *host, int bind_mode) ((unsigned long)ip[1]<<16L)| ((unsigned long)ip[2]<< 8L)| ((unsigned long)ip[3]); - server.sin_addr.s_addr=htonl(l); + server.sa_in.sin_addr.s_addr=htonl(l); } again: - s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); + s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL); if (s == INVALID_SOCKET) { SYSerr(SYS_F_SOCKET,get_last_socket_error()); @@ -654,22 +726,42 @@ again: bind_mode=BIO_BIND_NORMAL; } #endif - if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) + if (bind(s,&server.sa,addrlen) == -1) { #ifdef SO_REUSEADDR err_num=get_last_socket_error(); if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && +#ifdef OPENSSL_SYS_WINDOWS + /* Some versions of Windows define EADDRINUSE to + * a dummy value. + */ + (err_num == WSAEADDRINUSE)) +#else (err_num == EADDRINUSE)) +#endif { - memcpy((char *)&client,(char *)&server,sizeof(server)); - if (strcmp(h,"*") == 0) - client.sin_addr.s_addr=htonl(0x7F000001); - cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); + client = server; + if (h == NULL || strcmp(h,"*") == 0) + { +#if OPENSSL_USE_IPV6 + if (client.sa.sa_family == AF_INET6) + { + memset(&client.sa_in6.sin6_addr,0,sizeof(client.sa_in6.sin6_addr)); + client.sa_in6.sin6_addr.s6_addr[15]=1; + } + else +#endif + if (client.sa.sa_family == AF_INET) + { + client.sa_in.sin_addr.s_addr=htonl(0x7F000001); + } + else goto err; + } + cs=socket(client.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL); if (cs != INVALID_SOCKET) { int ii; - ii=connect(cs,(struct sockaddr *)&client, - sizeof(client)); + ii=connect(cs,&client.sa,addrlen); closesocket(cs); if (ii == INVALID_SOCKET) { @@ -708,20 +800,52 @@ err: int BIO_accept(int sock, char **addr) { int ret=INVALID_SOCKET; - static struct sockaddr_in from; unsigned long l; unsigned short port; - int len; char *p; - memset((char *)&from,0,sizeof(from)); - len=sizeof(from); - /* Note: under VMS with SOCKETSHR the fourth parameter is currently - * of type (int *) whereas under other systems it is (void *) if - * you don't have a cast it will choke the compiler: if you do - * have a cast then you can either go for (int *) or (void *). + struct { + /* + * As for following union. Trouble is that there are platforms + * that have socklen_t and there are platforms that don't, on + * some platforms socklen_t is int and on some size_t. So what + * one can do? One can cook #ifdef spaghetti, which is nothing + * but masochistic. Or one can do union between int and size_t. + * One naturally does it primarily for 64-bit platforms where + * sizeof(int) != sizeof(size_t). But would it work? Note that + * if size_t member is initialized to 0, then later int member + * assignment naturally does the job on little-endian platforms + * regardless accept's expectations! What about big-endians? + * If accept expects int*, then it works, and if size_t*, then + * length value would appear as unreasonably large. But this + * won't prevent it from filling in the address structure. The + * trouble of course would be if accept returns more data than + * actual buffer can accomodate and overwrite stack... That's + * where early OPENSSL_assert comes into picture. Besides, the + * only 64-bit big-endian platform found so far that expects + * size_t* is HP-UX, where stack grows towards higher address. + * <appro> */ - ret=accept(sock,(struct sockaddr *)&from,(void *)&len); + union { size_t s; int i; } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } from; + } sa; + + sa.len.s=0; + sa.len.i=sizeof(sa.from); + memset(&sa.from,0,sizeof(sa.from)); + ret=accept(sock,&sa.from.sa,(void *)&sa.len); + if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) + { + OPENSSL_assert(sa.len.s<=sizeof(sa.from)); + sa.len.i = (int)sa.len.s; + /* use sa.len.i from this point */ + } if (ret == INVALID_SOCKET) { if(BIO_sock_should_retry(ret)) return -2; @@ -732,8 +856,46 @@ int BIO_accept(int sock, char **addr) if (addr == NULL) goto end; - l=ntohl(from.sin_addr.s_addr); - port=ntohs(from.sin_port); +#ifdef EAI_FAMILY + do { + char h[NI_MAXHOST],s[NI_MAXSERV]; + size_t nl; + static union { void *p; + int (WSAAPI *f)(const struct sockaddr *,size_t/*socklen_t*/, + char *,size_t,char *,size_t,int); + } p_getnameinfo = {NULL}; + /* 2nd argument to getnameinfo is specified to + * be socklen_t. Unfortunately there is a number + * of environments where socklen_t is not defined. + * As it's passed by value, it's safe to pass it + * as size_t... <appro> */ + + if (p_getnameinfo.p==NULL) + { + if ((p_getnameinfo.p=DSO_global_lookup("getnameinfo"))==NULL) + p_getnameinfo.p=(void*)-1; + } + if (p_getnameinfo.p==(void *)-1) break; + + if ((*p_getnameinfo.f)(&sa.from.sa,sa.len.i,h,sizeof(h),s,sizeof(s), + NI_NUMERICHOST|NI_NUMERICSERV)) break; + nl = strlen(h)+strlen(s)+2; + p = *addr; + if (p) { *p = '\0'; p = OPENSSL_realloc(p,nl); } + else { p = OPENSSL_malloc(nl); } + if (p==NULL) + { + BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE); + goto end; + } + *addr = p; + BIO_snprintf(*addr,nl,"%s:%s",h,s); + goto end; + } while(0); +#endif + if (sa.from.sa.sa_family != AF_INET) goto end; + l=ntohl(sa.from.sa_in.sin_addr.s_addr); + port=ntohs(sa.from.sa_in.sin_port); if (*addr == NULL) { if ((p=OPENSSL_malloc(24)) == NULL) diff --git a/lib/libcrypto/bio/bio.h b/lib/libcrypto/bio/bio.h index cecb6a72077..152802fbdf2 100644 --- a/lib/libcrypto/bio/bio.h +++ b/lib/libcrypto/bio/bio.h @@ -95,6 +95,7 @@ extern "C" { #define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */ #define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */ #define BIO_TYPE_DGRAM (21|0x0400|0x0100) +#define BIO_TYPE_ASN1 (22|0x0200) /* filter */ #define BIO_TYPE_COMP (23|0x0200) /* filter */ #define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ @@ -156,8 +157,11 @@ extern "C" { * previous write * operation */ +#define BIO_CTRL_DGRAM_GET_PEER 46 #define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */ +#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to + * adjust socket timeouts */ /* modifiers */ #define BIO_FP_READ 0x02 @@ -262,7 +266,6 @@ int BIO_method_type(const BIO *b); typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long); -#ifndef OPENSSL_SYS_WIN16 typedef struct bio_method_st { int type; @@ -276,21 +279,6 @@ typedef struct bio_method_st int (*destroy)(BIO *); long (*callback_ctrl)(BIO *, int, bio_info_cb *); } BIO_METHOD; -#else -typedef struct bio_method_st - { - int type; - const char *name; - int (_far *bwrite)(); - int (_far *bread)(); - int (_far *bputs)(); - int (_far *bgets)(); - long (_far *ctrl)(); - int (_far *create)(); - int (_far *destroy)(); - long (_far *callback_ctrl)(); - } BIO_METHOD; -#endif struct bio_st { @@ -331,6 +319,9 @@ typedef struct bio_f_buffer_ctx_struct int obuf_off; /* write/read offset */ } BIO_F_BUFFER_CTX; +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg); + /* connect BIO stuff */ #define BIO_CONN_S_BEFORE 1 #define BIO_CONN_S_GET_IP 2 @@ -393,6 +384,13 @@ typedef struct bio_f_buffer_ctx_struct #define BIO_C_RESET_READ_REQUEST 147 #define BIO_C_SET_MD_CTX 148 +#define BIO_C_SET_PREFIX 149 +#define BIO_C_GET_PREFIX 150 +#define BIO_C_SET_SUFFIX 151 +#define BIO_C_GET_SUFFIX 152 + +#define BIO_C_SET_EX_ARG 153 +#define BIO_C_GET_EX_ARG 154 #define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) #define BIO_get_app_data(s) BIO_get_ex_data(s,0) @@ -405,7 +403,7 @@ typedef struct bio_f_buffer_ctx_struct #define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) #define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) #define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) -#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3) +#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0) #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) @@ -414,7 +412,7 @@ typedef struct bio_f_buffer_ctx_struct #define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) #define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) /* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ -#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL) +#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL) #define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) #define BIO_BIND_NORMAL 0 @@ -541,6 +539,8 @@ int BIO_ctrl_reset_read_request(BIO *b); (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) #define BIO_dgram_send_timedout(b) \ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +#define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) #define BIO_dgram_set_peer(b,peer) \ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) @@ -554,22 +554,21 @@ int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, unsigned long BIO_number_read(BIO *bio); unsigned long BIO_number_written(BIO *bio); +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + # ifndef OPENSSL_NO_FP_API -# if defined(OPENSSL_SYS_WIN16) && defined(_WINDLL) -BIO_METHOD *BIO_s_file_internal(void); -BIO *BIO_new_file_internal(char *filename, char *mode); -BIO *BIO_new_fp_internal(FILE *stream, int close_flag); -# define BIO_s_file BIO_s_file_internal -# define BIO_new_file BIO_new_file_internal -# define BIO_new_fp BIO_new_fp_internal -# else /* FP_API */ BIO_METHOD *BIO_s_file(void ); BIO *BIO_new_file(const char *filename, const char *mode); BIO *BIO_new_fp(FILE *stream, int close_flag); -# define BIO_s_file_internal BIO_s_file -# define BIO_new_file_internal BIO_new_file -# define BIO_new_fp_internal BIO_s_file -# endif /* FP_API */ +# define BIO_s_file_internal BIO_s_file # endif BIO * BIO_new(BIO_METHOD *type); int BIO_set(BIO *a,BIO_METHOD *type); @@ -598,13 +597,8 @@ int BIO_nread(BIO *bio, char **buf, int num); int BIO_nwrite0(BIO *bio, char **buf); int BIO_nwrite(BIO *bio, char **buf, int num); -#ifndef OPENSSL_SYS_WIN16 long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, long argl,long ret); -#else -long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, - long argl,long ret); -#endif BIO_METHOD *BIO_s_mem(void); BIO *BIO_new_mem_buf(void *buf, int len); diff --git a/lib/libcrypto/bio/bio_cb.c b/lib/libcrypto/bio/bio_cb.c index 6f4254a1141..9bcbc321d94 100644 --- a/lib/libcrypto/bio/bio_cb.c +++ b/lib/libcrypto/bio/bio_cb.c @@ -85,28 +85,32 @@ long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp, break; case BIO_CB_READ: if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p,p_maxlen,"read(%d,%d) - %s fd=%d\n", - bio->num,argi,bio->method->name,bio->num); + BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s fd=%d\n", + bio->num,(unsigned long)argi, + bio->method->name,bio->num); else - BIO_snprintf(p,p_maxlen,"read(%d,%d) - %s\n", - bio->num,argi,bio->method->name); + BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s\n", + bio->num,(unsigned long)argi, + bio->method->name); break; case BIO_CB_WRITE: if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p,p_maxlen,"write(%d,%d) - %s fd=%d\n", - bio->num,argi,bio->method->name,bio->num); + BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s fd=%d\n", + bio->num,(unsigned long)argi, + bio->method->name,bio->num); else - BIO_snprintf(p,p_maxlen,"write(%d,%d) - %s\n", - bio->num,argi,bio->method->name); + BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s\n", + bio->num,(unsigned long)argi, + bio->method->name); break; case BIO_CB_PUTS: BIO_snprintf(p,p_maxlen,"puts() - %s\n",bio->method->name); break; case BIO_CB_GETS: - BIO_snprintf(p,p_maxlen,"gets(%d) - %s\n",argi,bio->method->name); + BIO_snprintf(p,p_maxlen,"gets(%lu) - %s\n",(unsigned long)argi,bio->method->name); break; case BIO_CB_CTRL: - BIO_snprintf(p,p_maxlen,"ctrl(%d) - %s\n",argi,bio->method->name); + BIO_snprintf(p,p_maxlen,"ctrl(%lu) - %s\n",(unsigned long)argi,bio->method->name); break; case BIO_CB_RETURN|BIO_CB_READ: BIO_snprintf(p,p_maxlen,"read return %ld\n",ret); diff --git a/lib/libcrypto/bio/bio_err.c b/lib/libcrypto/bio/bio_err.c index 6603f1c74dc..a224edd5a0a 100644 --- a/lib/libcrypto/bio/bio_err.c +++ b/lib/libcrypto/bio/bio_err.c @@ -1,6 +1,6 @@ /* crypto/bio/bio_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/lib/libcrypto/bio/bio_lib.c b/lib/libcrypto/bio/bio_lib.c index 3f52ae953c2..77f4de9c324 100644 --- a/lib/libcrypto/bio/bio_lib.c +++ b/lib/libcrypto/bio/bio_lib.c @@ -429,7 +429,7 @@ BIO *BIO_push(BIO *b, BIO *bio) if (bio != NULL) bio->prev_bio=lb; /* called to do internal processing */ - BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL); + BIO_ctrl(b,BIO_CTRL_PUSH,0,lb); return(b); } @@ -441,7 +441,7 @@ BIO *BIO_pop(BIO *b) if (b == NULL) return(NULL); ret=b->next_bio; - BIO_ctrl(b,BIO_CTRL_POP,0,NULL); + BIO_ctrl(b,BIO_CTRL_POP,0,b); if (b->prev_bio != NULL) b->prev_bio->next_bio=b->next_bio; diff --git a/lib/libcrypto/bio/bss_acpt.c b/lib/libcrypto/bio/bss_acpt.c index d090b7272fb..826f761143c 100644 --- a/lib/libcrypto/bio/bss_acpt.c +++ b/lib/libcrypto/bio/bss_acpt.c @@ -100,8 +100,8 @@ static int acpt_new(BIO *h); static int acpt_free(BIO *data); static int acpt_state(BIO *b, BIO_ACCEPT *c); static void acpt_close_socket(BIO *data); -BIO_ACCEPT *BIO_ACCEPT_new(void ); -void BIO_ACCEPT_free(BIO_ACCEPT *a); +static BIO_ACCEPT *BIO_ACCEPT_new(void ); +static void BIO_ACCEPT_free(BIO_ACCEPT *a); #define ACPT_S_BEFORE 1 #define ACPT_S_GET_ACCEPT_SOCKET 2 @@ -141,7 +141,7 @@ static int acpt_new(BIO *bi) return(1); } -BIO_ACCEPT *BIO_ACCEPT_new(void) +static BIO_ACCEPT *BIO_ACCEPT_new(void) { BIO_ACCEPT *ret; @@ -154,7 +154,7 @@ BIO_ACCEPT *BIO_ACCEPT_new(void) return(ret); } -void BIO_ACCEPT_free(BIO_ACCEPT *a) +static void BIO_ACCEPT_free(BIO_ACCEPT *a) { if(a == NULL) return; diff --git a/lib/libcrypto/bio/bss_dgram.c b/lib/libcrypto/bio/bss_dgram.c index c3da6dc82fa..eb7e3654677 100644 --- a/lib/libcrypto/bio/bss_dgram.c +++ b/lib/libcrypto/bio/bss_dgram.c @@ -66,7 +66,13 @@ #include <openssl/bio.h> +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) +#include <sys/timeb.h> +#endif + +#ifdef OPENSSL_SYS_LINUX #define IP_MTU 14 /* linux is lame */ +#endif #ifdef WATT32 #define sock_write SockWrite /* Watt-32 uses same names */ @@ -84,6 +90,8 @@ static int dgram_clear(BIO *bio); static int BIO_dgram_should_retry(int s); +static void get_current_time(struct timeval *t); + static BIO_METHOD methods_dgramp= { BIO_TYPE_DGRAM, @@ -100,10 +108,18 @@ static BIO_METHOD methods_dgramp= typedef struct bio_dgram_data_st { - struct sockaddr peer; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } peer; unsigned int connected; unsigned int _errno; unsigned int mtu; + struct timeval next_timeout; + struct timeval socket_timeout; } bio_dgram_data; BIO_METHOD *BIO_s_datagram(void) @@ -165,31 +181,140 @@ static int dgram_clear(BIO *a) } return(1); } - + +static void dgram_adjust_rcv_timeout(BIO *b) + { +#if defined(SO_RCVTIMEO) + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + int sz = sizeof(int); + + /* Is a timer active? */ + if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) + { + struct timeval timenow, timeleft; + + /* Read current socket timeout */ +#ifdef OPENSSL_SYS_WINDOWS + int timeout; + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void*)&timeout, &sz) < 0) + { perror("getsockopt"); } + else + { + data->socket_timeout.tv_sec = timeout / 1000; + data->socket_timeout.tv_usec = (timeout % 1000) * 1000; + } +#else + if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + &(data->socket_timeout), (void *)&sz) < 0) + { perror("getsockopt"); } +#endif + + /* Get current time */ + get_current_time(&timenow); + + /* Calculate time left until timer expires */ + memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); + timeleft.tv_sec -= timenow.tv_sec; + timeleft.tv_usec -= timenow.tv_usec; + if (timeleft.tv_usec < 0) + { + timeleft.tv_sec--; + timeleft.tv_usec += 1000000; + } + + if (timeleft.tv_sec < 0) + { + timeleft.tv_sec = 0; + timeleft.tv_usec = 1; + } + + /* Adjust socket timeout if next handhake message timer + * will expire earlier. + */ + if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) || + (data->socket_timeout.tv_sec > timeleft.tv_sec) || + (data->socket_timeout.tv_sec == timeleft.tv_sec && + data->socket_timeout.tv_usec >= timeleft.tv_usec)) + { +#ifdef OPENSSL_SYS_WINDOWS + timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void*)&timeout, sizeof(timeout)) < 0) + { perror("setsockopt"); } +#else + if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, + sizeof(struct timeval)) < 0) + { perror("setsockopt"); } +#endif + } + } +#endif + } + +static void dgram_reset_rcv_timeout(BIO *b) + { +#if defined(SO_RCVTIMEO) + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + + /* Is a timer active? */ + if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) + { +#ifdef OPENSSL_SYS_WINDOWS + int timeout = data->socket_timeout.tv_sec * 1000 + + data->socket_timeout.tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void*)&timeout, sizeof(timeout)) < 0) + { perror("setsockopt"); } +#else + if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), + sizeof(struct timeval)) < 0) + { perror("setsockopt"); } +#endif + } +#endif + } + static int dgram_read(BIO *b, char *out, int outl) { int ret=0; bio_dgram_data *data = (bio_dgram_data *)b->ptr; - struct sockaddr peer; - int peerlen = sizeof(peer); + struct { + /* + * See commentary in b_sock.c. <appro> + */ + union { size_t s; int i; } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } peer; + } sa; + + sa.len.s=0; + sa.len.i=sizeof(sa.peer); if (out != NULL) { clear_socket_error(); - memset(&peer, 0x00, peerlen); - /* Last arg in recvfrom is signed on some platforms and - * unsigned on others. It is of type socklen_t on some - * but this is not universal. Cast to (void *) to avoid - * compiler warnings. - */ - ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); + memset(&sa.peer, 0x00, sizeof(sa.peer)); + dgram_adjust_rcv_timeout(b); + ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len); + if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) + { + OPENSSL_assert(sa.len.s<=sizeof(sa.peer)); + sa.len.i = (int)sa.len.s; + } + dgram_reset_rcv_timeout(b); - if ( ! data->connected && ret > 0) - BIO_ctrl(b, BIO_CTRL_DGRAM_CONNECT, 0, &peer); + if ( ! data->connected && ret >= 0) + BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); BIO_clear_retry_flags(b); - if (ret <= 0) + if (ret < 0) { if (BIO_dgram_should_retry(ret)) { @@ -207,19 +332,29 @@ static int dgram_write(BIO *b, const char *in, int inl) bio_dgram_data *data = (bio_dgram_data *)b->ptr; clear_socket_error(); - if ( data->connected ) - ret=writesocket(b->num,in,inl); - else + if ( data->connected ) + ret=writesocket(b->num,in,inl); + else + { + int peerlen = sizeof(data->peer); + + if (data->peer.sa.sa_family == AF_INET) + peerlen = sizeof(data->peer.sa_in); +#if OPENSSL_USE_IVP6 + else if (data->peer.sa.sa_family == AF_INET6) + peerlen = sizeof(data->peer.sa_in6); +#endif #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) - ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer)); + ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); #else - ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer)); + ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); #endif + } BIO_clear_retry_flags(b); if (ret <= 0) { - if (BIO_sock_should_retry(ret)) + if (BIO_dgram_should_retry(ret)) { BIO_set_retry_write(b); data->_errno = get_last_socket_error(); @@ -240,8 +375,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) int *ip; struct sockaddr *to = NULL; bio_dgram_data *data = NULL; +#if defined(IP_MTU_DISCOVER) || defined(IP_MTU) long sockopt_val = 0; unsigned int sockopt_len = 0; +#endif +#ifdef OPENSSL_SYS_LINUX + socklen_t addr_len; + union { + struct sockaddr sa; + struct sockaddr_in s4; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 s6; +#endif + } addr; +#endif data = (bio_dgram_data *)b->ptr; @@ -294,30 +441,110 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) else { #endif - memcpy(&(data->peer),to, sizeof(struct sockaddr)); + switch (to->sa_family) + { + case AF_INET: + memcpy(&data->peer,to,sizeof(data->peer.sa_in)); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); + break; +#endif + default: + memcpy(&data->peer,to,sizeof(data->peer.sa)); + break; + } #if 0 } #endif break; /* (Linux)kernel sets DF bit on outgoing IP packets */ -#ifdef IP_MTU_DISCOVER case BIO_CTRL_DGRAM_MTU_DISCOVER: - sockopt_val = IP_PMTUDISC_DO; - if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, - &sockopt_val, sizeof(sockopt_val))) < 0) - perror("setsockopt"); +#ifdef OPENSSL_SYS_LINUX + addr_len = (socklen_t)sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) + { + ret = 0; + break; + } + sockopt_len = sizeof(sockopt_val); + switch (addr.sa.sa_family) + { + case AF_INET: + sockopt_val = IP_PMTUDISC_DO; + if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val))) < 0) + perror("setsockopt"); + break; +#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) + case AF_INET6: + sockopt_val = IPV6_PMTUDISC_DO; + if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val))) < 0) + perror("setsockopt"); + break; +#endif + default: + ret = -1; + break; + } + ret = -1; +#else break; #endif case BIO_CTRL_DGRAM_QUERY_MTU: - sockopt_len = sizeof(sockopt_val); - if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, - &sockopt_len)) < 0 || sockopt_val < 0) - { ret = 0; } - else +#ifdef OPENSSL_SYS_LINUX + addr_len = (socklen_t)sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) + { + ret = 0; + break; + } + sockopt_len = sizeof(sockopt_val); + switch (addr.sa.sa_family) { - data->mtu = sockopt_val; - ret = data->mtu; + case AF_INET: + if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, + &sockopt_len)) < 0 || sockopt_val < 0) + { + ret = 0; + } + else + { + /* we assume that the transport protocol is UDP and no + * IP options are used. + */ + data->mtu = sockopt_val - 8 - 20; + ret = data->mtu; + } + break; +#if OPENSSL_USE_IPV6 && defined(IPV6_MTU) + case AF_INET6: + if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val, + &sockopt_len)) < 0 || sockopt_val < 0) + { + ret = 0; + } + else + { + /* we assume that the transport protocol is UDP and no + * IPV6 options are used. + */ + data->mtu = sockopt_val - 8 - 40; + ret = data->mtu; + } + break; +#endif + default: + ret = 0; + break; } +#else + ret = 0; +#endif break; case BIO_CTRL_DGRAM_GET_MTU: return data->mtu; @@ -332,19 +559,66 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) if ( to != NULL) { data->connected = 1; - memcpy(&(data->peer),to, sizeof(struct sockaddr)); + switch (to->sa_family) + { + case AF_INET: + memcpy(&data->peer,to,sizeof(data->peer.sa_in)); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); + break; +#endif + default: + memcpy(&data->peer,to,sizeof(data->peer.sa)); + break; + } } else { data->connected = 0; - memset(&(data->peer), 0x00, sizeof(struct sockaddr)); + memset(&(data->peer), 0x00, sizeof(data->peer)); } break; - case BIO_CTRL_DGRAM_SET_PEER: - to = (struct sockaddr *) ptr; - - memcpy(&(data->peer), to, sizeof(struct sockaddr)); - break; + case BIO_CTRL_DGRAM_GET_PEER: + switch (data->peer.sa.sa_family) + { + case AF_INET: + ret=sizeof(data->peer.sa_in); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + ret=sizeof(data->peer.sa_in6); + break; +#endif + default: + ret=sizeof(data->peer.sa); + break; + } + if (num==0 || num>ret) + num=ret; + memcpy(ptr,&data->peer,(ret=num)); + break; + case BIO_CTRL_DGRAM_SET_PEER: + to = (struct sockaddr *) ptr; + switch (to->sa_family) + { + case AF_INET: + memcpy(&data->peer,to,sizeof(data->peer.sa_in)); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); + break; +#endif + default: + memcpy(&data->peer,to,sizeof(data->peer.sa)); + break; + } + break; + case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: + memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); + break; #if defined(SO_RCVTIMEO) case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: #ifdef OPENSSL_SYS_WINDOWS @@ -507,10 +781,6 @@ int BIO_dgram_non_fatal_error(int err) # endif #endif -#if defined(ENOTCONN) - case ENOTCONN: -#endif - #ifdef EINTR case EINTR: #endif @@ -533,11 +803,6 @@ int BIO_dgram_non_fatal_error(int err) case EALREADY: #endif -/* DF bit set, and packet larger than MTU */ -#ifdef EMSGSIZE - case EMSGSIZE: -#endif - return(1); /* break; */ default: @@ -546,3 +811,20 @@ int BIO_dgram_non_fatal_error(int err) return(0); } #endif + +static void get_current_time(struct timeval *t) + { +#ifdef OPENSSL_SYS_WIN32 + struct _timeb tb; + _ftime(&tb); + t->tv_sec = (long)tb.time; + t->tv_usec = (long)tb.millitm * 1000; +#elif defined(OPENSSL_SYS_VMS) + struct timeb tb; + ftime(&tb); + t->tv_sec = (long)tb.time; + t->tv_usec = (long)tb.millitm * 1000; +#else + gettimeofday(t, NULL); +#endif + } diff --git a/lib/libcrypto/bio/bss_fd.c b/lib/libcrypto/bio/bss_fd.c index 4c229bf6410..d1bf85aae17 100644 --- a/lib/libcrypto/bio/bss_fd.c +++ b/lib/libcrypto/bio/bss_fd.c @@ -60,6 +60,13 @@ #include <errno.h> #define USE_SOCKETS #include "cryptlib.h" + +#if defined(OPENSSL_NO_POSIX_IO) +/* + * One can argue that one should implement dummy placeholder for + * BIO_s_fd here... + */ +#else /* * As for unconditional usage of "UPLINK" interface in this module. * Trouble is that unlike Unix file descriptors [which are indexes @@ -77,6 +84,7 @@ static int fd_write(BIO *h, const char *buf, int num); static int fd_read(BIO *h, char *buf, int size); static int fd_puts(BIO *h, const char *str); +static int fd_gets(BIO *h, char *buf, int size); static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int fd_new(BIO *h); static int fd_free(BIO *data); @@ -88,7 +96,7 @@ static BIO_METHOD methods_fdp= fd_write, fd_read, fd_puts, - NULL, /* fd_gets, */ + fd_gets, fd_ctrl, fd_new, fd_free, @@ -227,6 +235,22 @@ static int fd_puts(BIO *bp, const char *str) return(ret); } +static int fd_gets(BIO *bp, char *buf, int size) + { + int ret=0; + char *ptr=buf; + char *end=buf+size-1; + + while ( (ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n') ) + ptr++; + + ptr[0]='\0'; + + if (buf[0] != '\0') + ret=strlen(buf); + return(ret); + } + int BIO_fd_should_retry(int i) { int err; @@ -292,3 +316,4 @@ int BIO_fd_non_fatal_error(int err) } return(0); } +#endif diff --git a/lib/libcrypto/bio/bss_file.c b/lib/libcrypto/bio/bss_file.c index e692a08e586..8bfa0bcd97d 100644 --- a/lib/libcrypto/bio/bss_file.c +++ b/lib/libcrypto/bio/bss_file.c @@ -118,10 +118,47 @@ static BIO_METHOD methods_filep= BIO *BIO_new_file(const char *filename, const char *mode) { - BIO *ret; - FILE *file; + BIO *ret; + FILE *file=NULL; + +#if defined(_WIN32) && defined(CP_UTF8) + int sz, len_0 = (int)strlen(filename)+1; - if ((file=fopen(filename,mode)) == NULL) + /* + * Basically there are three cases to cover: a) filename is + * pure ASCII string; b) actual UTF-8 encoded string and + * c) locale-ized string, i.e. one containing 8-bit + * characters that are meaningful in current system locale. + * If filename is pure ASCII or real UTF-8 encoded string, + * MultiByteToWideChar succeeds and _wfopen works. If + * filename is locale-ized string, chances are that + * MultiByteToWideChar fails reporting + * ERROR_NO_UNICODE_TRANSLATION, in which case we fall + * back to fopen... + */ + if ((sz=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, + filename,len_0,NULL,0))>0) + { + WCHAR wmode[8]; + WCHAR *wfilename = _alloca(sz*sizeof(WCHAR)); + + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, + filename,len_0,wfilename,sz) && + MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1, + wmode,sizeof(wmode)/sizeof(wmode[0])) && + (file=_wfopen(wfilename,wmode))==NULL && errno==ENOENT + ) /* UTF-8 decode succeeded, but no file, filename + * could still have been locale-ized... */ + file = fopen(filename,mode); + } + else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION) + { + file = fopen(filename,mode); + } +#else + file=fopen(filename,mode); +#endif + if (file == NULL) { SYSerr(SYS_F_FOPEN,get_last_sys_error()); ERR_add_error_data(5,"fopen('",filename,"','",mode,"')"); @@ -131,7 +168,7 @@ BIO *BIO_new_file(const char *filename, const char *mode) BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB); return(NULL); } - if ((ret=BIO_new(BIO_s_file_internal())) == NULL) + if ((ret=BIO_new(BIO_s_file())) == NULL) { fclose(file); return(NULL); @@ -241,7 +278,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) if (b->flags&BIO_FLAGS_UPLINK) ret=(long)UP_fseek(b->ptr,num,0); else - ret=(long)fseek(fp,num,SEEK_SET); + ret=(long)fseek(fp,num,0); break; case BIO_CTRL_EOF: if (b->flags&BIO_FLAGS_UPLINK) @@ -272,9 +309,9 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_clear_flags(b,BIO_FLAGS_UPLINK); #endif #endif -#ifdef UP_fsetmode +#ifdef UP_fsetmod if (b->flags&BIO_FLAGS_UPLINK) - UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b'); + UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b')); else #endif { @@ -286,8 +323,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) _setmode(fd,_O_BINARY); #elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) int fd = fileno((FILE*)ptr); - /* Under CLib there are differences in file modes - */ + /* Under CLib there are differences in file modes */ if (num & BIO_FP_TEXT) setmode(fd,O_TEXT); else @@ -308,7 +344,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) else _setmode(fd,_O_BINARY); } -#elif defined(OPENSSL_SYS_OS2) +#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) int fd = fileno((FILE*)ptr); if (num & BIO_FP_TEXT) setmode(fd, O_TEXT); @@ -404,11 +440,18 @@ static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) buf[0]='\0'; if (bp->flags&BIO_FLAGS_UPLINK) - UP_fgets(buf,size,bp->ptr); + { + if (!UP_fgets(buf,size,bp->ptr)) + goto err; + } else - fgets(buf,size,(FILE *)bp->ptr); + { + if (!fgets(buf,size,(FILE *)bp->ptr)) + goto err; + } if (buf[0] != '\0') ret=strlen(buf); + err: return(ret); } diff --git a/lib/libcrypto/bio/bss_log.c b/lib/libcrypto/bio/bss_log.c index 6360dbc820b..7ead044b376 100644 --- a/lib/libcrypto/bio/bss_log.c +++ b/lib/libcrypto/bio/bss_log.c @@ -70,7 +70,6 @@ #if defined(OPENSSL_SYS_WINCE) #elif defined(OPENSSL_SYS_WIN32) -# include <process.h> #elif defined(OPENSSL_SYS_VMS) # include <opcdef.h> # include <descrip.h> @@ -122,18 +121,6 @@ static int MS_CALLBACK slg_free(BIO *data); static void xopenlog(BIO* bp, char* name, int level); static void xsyslog(BIO* bp, int priority, const char* string); static void xcloselog(BIO* bp); -#ifdef OPENSSL_SYS_WIN32 -LONG (WINAPI *go_for_advapi)() = RegOpenKeyEx; -HANDLE (WINAPI *register_event_source)() = NULL; -BOOL (WINAPI *deregister_event_source)() = NULL; -BOOL (WINAPI *report_event)() = NULL; -#define DL_PROC(m,f) (GetProcAddress( m, f )) -#ifdef UNICODE -#define DL_PROC_X(m,f) DL_PROC( m, f "W" ) -#else -#define DL_PROC_X(m,f) DL_PROC( m, f "A" ) -#endif -#endif static BIO_METHOD methods_slg= { @@ -175,7 +162,7 @@ static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) char* buf; char* pp; int priority, i; - static struct + static const struct { int strl; char str[10]; @@ -249,35 +236,20 @@ static int MS_CALLBACK slg_puts(BIO *bp, const char *str) static void xopenlog(BIO* bp, char* name, int level) { - if ( !register_event_source ) - { - HANDLE advapi; - if ( !(advapi = GetModuleHandle("advapi32")) ) - return; - register_event_source = (HANDLE (WINAPI *)())DL_PROC_X(advapi, - "RegisterEventSource" ); - deregister_event_source = (BOOL (WINAPI *)())DL_PROC(advapi, - "DeregisterEventSource"); - report_event = (BOOL (WINAPI *)())DL_PROC_X(advapi, - "ReportEvent" ); - if ( !(register_event_source && deregister_event_source && - report_event) ) - { - register_event_source = NULL; - deregister_event_source = NULL; - report_event = NULL; - return; - } - } - bp->ptr= (char *)register_event_source(NULL, name); + if (GetVersion() < 0x80000000) + bp->ptr = RegisterEventSourceA(NULL,name); + else + bp->ptr = NULL; } static void xsyslog(BIO *bp, int priority, const char *string) { LPCSTR lpszStrings[2]; WORD evtype= EVENTLOG_ERROR_TYPE; - int pid = _getpid(); - char pidbuf[DECIMAL_SIZE(pid)+4]; + char pidbuf[DECIMAL_SIZE(DWORD)+4]; + + if (bp->ptr == NULL) + return; switch (priority) { @@ -301,19 +273,18 @@ static void xsyslog(BIO *bp, int priority, const char *string) break; } - sprintf(pidbuf, "[%d] ", pid); + sprintf(pidbuf, "[%u] ", GetCurrentProcessId()); lpszStrings[0] = pidbuf; lpszStrings[1] = string; - if(report_event && bp->ptr) - report_event(bp->ptr, evtype, 0, 1024, NULL, 2, 0, + ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL); } static void xcloselog(BIO* bp) { - if(deregister_event_source && bp->ptr) - deregister_event_source((HANDLE)(bp->ptr)); + if(bp->ptr) + DeregisterEventSource((HANDLE)(bp->ptr)); bp->ptr= NULL; } diff --git a/lib/libcrypto/bio/bss_mem.c b/lib/libcrypto/bio/bss_mem.c index e7ab9cb3a3f..37d4194e4bb 100644 --- a/lib/libcrypto/bio/bss_mem.c +++ b/lib/libcrypto/bio/bss_mem.c @@ -94,16 +94,18 @@ BIO *BIO_new_mem_buf(void *buf, int len) { BIO *ret; BUF_MEM *b; + size_t sz; + if (!buf) { BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER); return NULL; } - if(len == -1) len = strlen(buf); + sz = (len<0) ? strlen(buf) : (size_t)len; if(!(ret = BIO_new(BIO_s_mem())) ) return NULL; b = (BUF_MEM *)ret->ptr; b->data = buf; - b->length = len; - b->max = len; + b->length = sz; + b->max = sz; ret->flags |= BIO_FLAGS_MEM_RDONLY; /* Since this is static data retrying wont help */ ret->num = 0; @@ -144,22 +146,16 @@ static int mem_read(BIO *b, char *out, int outl) { int ret= -1; BUF_MEM *bm; - int i; - char *from,*to; bm=(BUF_MEM *)b->ptr; BIO_clear_retry_flags(b); - ret=(outl > bm->length)?bm->length:outl; + ret=(outl >=0 && (size_t)outl > bm->length)?(int)bm->length:outl; if ((out != NULL) && (ret > 0)) { memcpy(out,bm->data,ret); bm->length-=ret; - /* memmove(&(bm->data[0]),&(bm->data[ret]), bm->length); */ if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret; else { - from=(char *)&(bm->data[ret]); - to=(char *)&(bm->data[0]); - for (i=0; i<bm->length; i++) - to[i]=from[i]; + memmove(&(bm->data[0]),&(bm->data[ret]),bm->length); } } else if (bm->length == 0) { diff --git a/lib/libcrypto/bio/bss_sock.c b/lib/libcrypto/bio/bss_sock.c index 30c3ceab468..3df31938c18 100644 --- a/lib/libcrypto/bio/bss_sock.c +++ b/lib/libcrypto/bio/bss_sock.c @@ -172,15 +172,6 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) switch (cmd) { - case BIO_CTRL_RESET: - num=0; - case BIO_C_FILE_SEEK: - ret=0; - break; - case BIO_C_FILE_TELL: - case BIO_CTRL_INFO: - ret=0; - break; case BIO_C_SET_FD: sock_free(b); b->num= *((int *)ptr); @@ -203,10 +194,6 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_SET_CLOSE: b->shutdown=(int)num; break; - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - ret=0; - break; case BIO_CTRL_DUP: case BIO_CTRL_FLUSH: ret=1; |