diff options
author | Richard Levitte <levitte@openssl.org> | 2010-01-27 11:14:46 +0000 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2010-01-27 11:14:46 +0000 |
commit | e6d8d6a89ae491106ff5860bcd339f1469ca350f (patch) | |
tree | bf5eb7cff5c855f24213c665470d57d9bc96b969 /crypto/bio | |
parent | 0e785e5e093d4c24eaf531dd5ffc655e3a91c6b5 (diff) | |
download | openssl-new-BRANCH_VMS_64BIT.tar.gz |
Merge main -> VMS_64BITBRANCH_VMS_64BIT
Diffstat (limited to 'crypto/bio')
-rw-r--r-- | crypto/bio/.cvsignore | 2 | ||||
-rw-r--r-- | crypto/bio/Makefile.ssl | 217 | ||||
-rw-r--r-- | crypto/bio/b_dump.c | 4 | ||||
-rw-r--r-- | crypto/bio/b_print.c | 16 | ||||
-rw-r--r-- | crypto/bio/b_sock.c | 270 | ||||
-rw-r--r-- | crypto/bio/bio.h | 183 | ||||
-rw-r--r-- | crypto/bio/bio_cb.c | 24 | ||||
-rw-r--r-- | crypto/bio/bio_err.c | 141 | ||||
-rw-r--r-- | crypto/bio/bio_lcl.h | 36 | ||||
-rw-r--r-- | crypto/bio/bio_lib.c | 52 | ||||
-rw-r--r-- | crypto/bio/bss_acpt.c | 8 | ||||
-rw-r--r-- | crypto/bio/bss_bio.c | 2 | ||||
-rw-r--r-- | crypto/bio/bss_conn.c | 6 | ||||
-rw-r--r-- | crypto/bio/bss_dgram.c | 830 | ||||
-rw-r--r-- | crypto/bio/bss_fd.c | 57 | ||||
-rw-r--r-- | crypto/bio/bss_file.c | 117 | ||||
-rw-r--r-- | crypto/bio/bss_log.c | 55 | ||||
-rw-r--r-- | crypto/bio/bss_mem.c | 40 | ||||
-rw-r--r-- | crypto/bio/bss_sock.c | 5 |
19 files changed, 1537 insertions, 528 deletions
diff --git a/crypto/bio/.cvsignore b/crypto/bio/.cvsignore index c6d03a9dbc..439e6d3eb6 100644 --- a/crypto/bio/.cvsignore +++ b/crypto/bio/.cvsignore @@ -1,2 +1,4 @@ lib Makefile.save +*.flc +semantic.cache diff --git a/crypto/bio/Makefile.ssl b/crypto/bio/Makefile.ssl deleted file mode 100644 index 85be2ed010..0000000000 --- a/crypto/bio/Makefile.ssl +++ /dev/null @@ -1,217 +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: - @headerlist="$(EXHEADER)"; for i in $$headerlist; \ - 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/ossl_typ.h -b_dump.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -b_dump.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -b_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -b_print.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -b_sock.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -b_sock.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bf_buff.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bf_buff.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bf_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bf_null.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bio_cb.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bio_cb.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bio_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bio_err.o: ../../include/openssl/symhacks.h 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/ossl_typ.h -bio_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bio_lib.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bss_acpt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_acpt.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h ../../include/openssl/safestack.h -bss_bio.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -bss_bio.o: 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/ossl_typ.h -bss_conn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_conn.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bss_fd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_fd.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bss_file.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_file.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bss_log.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_log.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bss_mem.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_mem.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bss_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_null.o: ../../include/openssl/symhacks.h ../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/ossl_typ.h -bss_sock.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -bss_sock.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_sock.c diff --git a/crypto/bio/b_dump.c b/crypto/bio/b_dump.c index a07b79437f..c80ecc4295 100644 --- a/crypto/bio/b_dump.c +++ b/crypto/bio/b_dump.c @@ -62,7 +62,7 @@ #include <stdio.h> #include "cryptlib.h" -#include <openssl/bio.h> +#include "bio_lcl.h" #define TRUNCATE #define DUMP_WIDTH 16 @@ -160,7 +160,7 @@ int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u), #ifndef OPENSSL_NO_FP_API static int write_fp(const void *data, size_t len, void *fp) { - return fwrite(data, len, 1, (FILE *)fp); + return UP_fwrite(data, len, 1, fp); } int BIO_dump_fp(FILE *fp, const char *s, int len) { diff --git a/crypto/bio/b_print.c b/crypto/bio/b_print.c index 47b04396d7..143a7cfefa 100644 --- a/crypto/bio/b_print.c +++ b/crypto/bio/b_print.c @@ -79,7 +79,7 @@ #include <openssl/bn.h> /* To get BN_LLONG properly defined */ #include <openssl/bio.h> -#ifdef BN_LLONG +#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT) # ifndef HAVE_LONG_LONG # define HAVE_LONG_LONG 1 # endif @@ -115,9 +115,9 @@ #define LDOUBLE double #endif -#if HAVE_LONG_LONG -# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__) -# define LLONG _int64 +#ifdef HAVE_LONG_LONG +# if defined(_WIN32) && !defined(__GNUC__) +# define LLONG __int64 # else # define LLONG long long # endif @@ -482,7 +482,7 @@ fmtint( int flags) { int signvalue = 0; - char *prefix = ""; + const char *prefix = ""; unsigned LLONG uvalue; char convert[DECIMAL_SIZE(value)+3]; int place = 0; @@ -576,7 +576,7 @@ abs_val(LDOUBLE value) } static LDOUBLE -pow10(int in_exp) +pow_10(int in_exp) { LDOUBLE result = 1; while (in_exp) { @@ -640,8 +640,8 @@ fmtfp( /* we "cheat" by converting the fractional part to integer by multiplying by a factor of 10 */ - max10 = roundv(pow10(max)); - fracpart = roundv(pow10(max) * (ufvalue - intpart)); + max10 = roundv(pow_10(max)); + fracpart = roundv(pow_10(max) * (ufvalue - intpart)); if (fracpart >= max10) { intpart++; diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c index c964e40c54..582ce2e05f 100644 --- a/crypto/bio/b_sock.c +++ b/crypto/bio/b_sock.c @@ -62,14 +62,19 @@ #define USE_SOCKETS #include "cryptlib.h" #include <openssl/bio.h> +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK) +#include <netdb.h> +#if defined(NETWARE_CLIB) +#include <sys/ioctl.h> +NETDB_DEFINE_CONTEXT +#endif +#endif #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 @@ -79,10 +84,21 @@ #define MAX_LISTEN 32 #endif -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) 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; @@ -203,11 +219,11 @@ int BIO_get_port(const char *str, unsigned short *port_ptr) /* Note: under VMS with SOCKETSHR, it seems like the first * parameter is 'char *', instead of 'const char *' */ - s=getservbyname( #ifndef CONST_STRICT - (char *) + s=getservbyname((char *)str,"tcp"); +#else + s=getservbyname(str,"tcp"); #endif - str,"tcp"); if(s != NULL) *port_ptr=ntohs((unsigned short)s->s_port); CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); @@ -247,6 +263,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 @@ -385,7 +405,11 @@ struct hostent *BIO_gethostbyname(const char *name) #if 1 /* Caching gethostbyname() results forever is wrong, * so we have to let the true gethostbyname() worry about this */ +#if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__)) + return gethostbyname((char*)name); +#else return gethostbyname(name); +#endif #else struct hostent *ret; int i,lowi=0,j; @@ -425,11 +449,11 @@ struct hostent *BIO_gethostbyname(const char *name) /* Note: under VMS with SOCKETSHR, it seems like the first * parameter is 'char *', instead of 'const char *' */ - ret=gethostbyname( # ifndef CONST_STRICT - (char *) + ret=gethostbyname((char *)name); +# else + ret=gethostbyname(name); # endif - name); if (ret == NULL) goto end; @@ -481,12 +505,14 @@ int BIO_sock_init(void) { int err; -#ifdef SIGINT - signal(SIGINT,(void (*)(int))BIO_sock_cleanup); -#endif 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); @@ -502,18 +528,13 @@ int BIO_sock_init(void) return (-1); #endif -#if defined(OPENSSL_SYS_NETWARE) +#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) WORD wVerReq; WSADATA wsaData; int err; if (!wsa_init_done) { - -# ifdef SIGINT - signal(SIGINT,(void (*)(int))BIO_sock_cleanup); -# endif - wsa_init_done=1; wVerReq = MAKEWORD( 2, 0 ); err = WSAStartup(wVerReq,&wsaData); @@ -535,12 +556,12 @@ void BIO_sock_cleanup(void) if (wsa_init_done) { wsa_init_done=0; -#ifndef OPENSSL_SYS_WINCE +#if 0 /* this call is claimed to be non-present in Winsock2 */ WSACancelBlockingCall(); #endif WSACleanup(); } -#elif defined(OPENSSL_SYS_NETWARE) +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) if (wsa_init_done) { wsa_init_done=0; @@ -610,12 +631,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; @@ -629,8 +656,7 @@ int BIO_get_accept_socket(char *host, int bind_mode) { if (*e == ':') { - p= &(e[1]); - *e='\0'; + p=e; } else if (*e == '/') { @@ -638,21 +664,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; @@ -661,11 +736,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()); @@ -683,22 +758,35 @@ 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) && (err_num == EADDRINUSE)) { - 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) { @@ -737,20 +825,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; @@ -761,8 +881,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/crypto/bio/bio.h b/crypto/bio/bio.h index 70e0f4fdcb..f0d4d06692 100644 --- a/crypto/bio/bio.h +++ b/crypto/bio/bio.h @@ -94,6 +94,9 @@ extern "C" { #define BIO_TYPE_BER (18|0x0200) /* BER -> bin filter */ #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 */ #define BIO_TYPE_FILTER 0x0200 @@ -125,6 +128,41 @@ extern "C" { #define BIO_CTRL_SET_FILENAME 30 /* BIO_s_file special */ +/* dgram BIO stuff */ +#define BIO_CTRL_DGRAM_CONNECT 31 /* BIO dgram special */ +#define BIO_CTRL_DGRAM_SET_CONNECTED 32 /* allow for an externally + * connected socket to be + * passed in */ +#define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */ +#define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */ +#define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */ +#define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36 /* getsockopt, essentially */ + +#define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37 /* flag whether the last */ +#define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38 /* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +#define BIO_CTRL_DGRAM_MTU_DISCOVER 39 /* set DF bit on egress packets */ +/* #endif */ + +#define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */ +#define BIO_CTRL_DGRAM_GET_MTU 41 /* get cached value for MTU */ +#define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for + * MTU. want to use this + * if asking the kernel + * fails */ + +#define BIO_CTRL_DGRAM_MTU_EXCEEDED 43 /* check whether the MTU + * was exceed in the + * 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 #define BIO_FP_WRITE 0x04 @@ -136,6 +174,11 @@ extern "C" { #define BIO_FLAGS_IO_SPECIAL 0x04 #define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) #define BIO_FLAGS_SHOULD_RETRY 0x08 +#ifndef BIO_FLAGS_UPLINK +/* "UPLINK" flag denotes file descriptors provided by application. + It defaults to 0, as most platforms don't require UPLINK interface. */ +#define BIO_FLAGS_UPLINK 0 +#endif /* Used in BIO_gethostbyname() */ #define BIO_GHBN_CTRL_HITS 1 @@ -158,28 +201,32 @@ extern "C" { */ #define BIO_FLAGS_MEM_RDONLY 0x200 -#define BIO_set_flags(b,f) ((b)->flags|=(f)) -#define BIO_get_flags(b) ((b)->flags) +typedef struct bio_st BIO; + +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +#define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) #define BIO_set_retry_special(b) \ - ((b)->flags|=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) #define BIO_set_retry_read(b) \ - ((b)->flags|=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) #define BIO_set_retry_write(b) \ - ((b)->flags|=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) /* These are normally used internally in BIOs */ -#define BIO_clear_flags(b,f) ((b)->flags&= ~(f)) #define BIO_clear_retry_flags(b) \ - ((b)->flags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) #define BIO_get_retry_flags(b) \ - ((b)->flags&(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) /* These should be used by the application to tell why we should retry */ -#define BIO_should_read(a) ((a)->flags & BIO_FLAGS_READ) -#define BIO_should_write(a) ((a)->flags & BIO_FLAGS_WRITE) -#define BIO_should_io_special(a) ((a)->flags & BIO_FLAGS_IO_SPECIAL) -#define BIO_retry_type(a) ((a)->flags & BIO_FLAGS_RWS) -#define BIO_should_retry(a) ((a)->flags & BIO_FLAGS_SHOULD_RETRY) +#define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +#define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +#define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +#define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +#define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) /* The next three are used in conjunction with the * BIO_should_io_special() condition. After this returns true, @@ -208,18 +255,17 @@ extern "C" { #define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) #define BIO_cb_post(a) ((a)&BIO_CB_RETURN) -#define BIO_set_callback(b,cb) ((b)->callback=(cb)) -#define BIO_set_callback_arg(b,arg) ((b)->cb_arg=(char *)(arg)) -#define BIO_get_callback_arg(b) ((b)->cb_arg) -#define BIO_get_callback(b) ((b)->callback) -#define BIO_method_name(b) ((b)->method->name) -#define BIO_method_type(b) ((b)->method->type) +long (*BIO_get_callback(const BIO *b)) (struct bio_st *,int,const char *,int, long,long); +void BIO_set_callback(BIO *b, + long (*callback)(struct bio_st *,int,const char *,int, long,long)); +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); -typedef struct bio_st BIO; +const char * BIO_method_name(const BIO *b); +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; @@ -233,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 { @@ -288,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 @@ -348,7 +382,15 @@ typedef struct bio_f_buffer_ctx_struct #define BIO_C_NWRITE0 145 #define BIO_C_NWRITE 146 #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) @@ -361,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) @@ -370,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 @@ -488,6 +530,20 @@ size_t BIO_ctrl_get_write_guarantee(BIO *b); size_t BIO_ctrl_get_read_request(BIO *b); int BIO_ctrl_reset_read_request(BIO *b); +/* ctrl macros for dgram */ +#define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer) +#define BIO_ctrl_set_connected(b, state, peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer) +#define BIO_dgram_recv_timedout(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) + /* These two aren't currently implemented */ /* int BIO_get_ex_num(BIO *bio); */ /* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */ @@ -498,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); @@ -542,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); @@ -567,10 +617,16 @@ BIO_METHOD *BIO_f_buffer(void); BIO_METHOD *BIO_f_linebuffer(void); #endif BIO_METHOD *BIO_f_nbio_test(void); +#ifndef OPENSSL_NO_DGRAM +BIO_METHOD *BIO_s_datagram(void); +#endif + /* BIO_METHOD *BIO_f_ber(void); */ int BIO_sock_should_retry(int i); int BIO_sock_non_fatal_error(int error); +int BIO_dgram_non_fatal_error(int error); + int BIO_fd_should_retry(int i); int BIO_fd_non_fatal_error(int error); int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u), @@ -623,6 +679,7 @@ void BIO_sock_cleanup(void); int BIO_set_tcp_ndelay(int sock,int turn_on); BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_dgram(int fd, int close_flag); BIO *BIO_new_fd(int fd, int close_flag); BIO *BIO_new_connect(char *host_port); BIO *BIO_new_accept(char *host_port); @@ -638,17 +695,20 @@ void BIO_copy_next_retry(BIO *b); /*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/ -#ifndef __GNUC__ -#define __attribute__(x) +#ifdef __GNUC__ +# define __bio_h__attr__ __attribute__ +#else +# define __bio_h__attr__(x) #endif int BIO_printf(BIO *bio, const char *format, ...) - __attribute__((__format__(__printf__,2,3))); + __bio_h__attr__((__format__(__printf__,2,3))); int BIO_vprintf(BIO *bio, const char *format, va_list args) - __attribute__((__format__(__printf__,2,0))); + __bio_h__attr__((__format__(__printf__,2,0))); int BIO_snprintf(char *buf, size_t n, const char *format, ...) - __attribute__((__format__(__printf__,3,4))); + __bio_h__attr__((__format__(__printf__,3,4))); int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) - __attribute__((__format__(__printf__,3,0))); + __bio_h__attr__((__format__(__printf__,3,0))); +#undef __bio_h__attr__ /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes @@ -662,6 +722,7 @@ void ERR_load_BIO_strings(void); #define BIO_F_ACPT_STATE 100 #define BIO_F_BIO_ACCEPT 101 #define BIO_F_BIO_BER_GET_HEADER 102 +#define BIO_F_BIO_CALLBACK_CTRL 131 #define BIO_F_BIO_CTRL 103 #define BIO_F_BIO_GETHOSTBYNAME 120 #define BIO_F_BIO_GETS 104 diff --git a/crypto/bio/bio_cb.c b/crypto/bio/bio_cb.c index 6f4254a114..9bcbc321d9 100644 --- a/crypto/bio/bio_cb.c +++ b/crypto/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/crypto/bio/bio_err.c b/crypto/bio/bio_err.c index 5df17ff892..a224edd5a0 100644 --- a/crypto/bio/bio_err.c +++ b/crypto/bio/bio_err.c @@ -1,6 +1,6 @@ /* crypto/bio/bio_err.c */ /* ==================================================================== - * Copyright (c) 1999 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 @@ -61,77 +61,81 @@ #include <stdio.h> #include <openssl/err.h> #include <openssl/bio.h> -#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_ERR is defined */ /* BEGIN ERROR CODES */ #ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason) + static ERR_STRING_DATA BIO_str_functs[]= { -{ERR_PACK(0,BIO_F_ACPT_STATE,0), "ACPT_STATE"}, -{ERR_PACK(0,BIO_F_BIO_ACCEPT,0), "BIO_accept"}, -{ERR_PACK(0,BIO_F_BIO_BER_GET_HEADER,0), "BIO_BER_GET_HEADER"}, -{ERR_PACK(0,BIO_F_BIO_CTRL,0), "BIO_ctrl"}, -{ERR_PACK(0,BIO_F_BIO_GETHOSTBYNAME,0), "BIO_gethostbyname"}, -{ERR_PACK(0,BIO_F_BIO_GETS,0), "BIO_gets"}, -{ERR_PACK(0,BIO_F_BIO_GET_ACCEPT_SOCKET,0), "BIO_get_accept_socket"}, -{ERR_PACK(0,BIO_F_BIO_GET_HOST_IP,0), "BIO_get_host_ip"}, -{ERR_PACK(0,BIO_F_BIO_GET_PORT,0), "BIO_get_port"}, -{ERR_PACK(0,BIO_F_BIO_MAKE_PAIR,0), "BIO_MAKE_PAIR"}, -{ERR_PACK(0,BIO_F_BIO_NEW,0), "BIO_new"}, -{ERR_PACK(0,BIO_F_BIO_NEW_FILE,0), "BIO_new_file"}, -{ERR_PACK(0,BIO_F_BIO_NEW_MEM_BUF,0), "BIO_new_mem_buf"}, -{ERR_PACK(0,BIO_F_BIO_NREAD,0), "BIO_nread"}, -{ERR_PACK(0,BIO_F_BIO_NREAD0,0), "BIO_nread0"}, -{ERR_PACK(0,BIO_F_BIO_NWRITE,0), "BIO_nwrite"}, -{ERR_PACK(0,BIO_F_BIO_NWRITE0,0), "BIO_nwrite0"}, -{ERR_PACK(0,BIO_F_BIO_PUTS,0), "BIO_puts"}, -{ERR_PACK(0,BIO_F_BIO_READ,0), "BIO_read"}, -{ERR_PACK(0,BIO_F_BIO_SOCK_INIT,0), "BIO_sock_init"}, -{ERR_PACK(0,BIO_F_BIO_WRITE,0), "BIO_write"}, -{ERR_PACK(0,BIO_F_BUFFER_CTRL,0), "BUFFER_CTRL"}, -{ERR_PACK(0,BIO_F_CONN_CTRL,0), "CONN_CTRL"}, -{ERR_PACK(0,BIO_F_CONN_STATE,0), "CONN_STATE"}, -{ERR_PACK(0,BIO_F_FILE_CTRL,0), "FILE_CTRL"}, -{ERR_PACK(0,BIO_F_FILE_READ,0), "FILE_READ"}, -{ERR_PACK(0,BIO_F_LINEBUFFER_CTRL,0), "LINEBUFFER_CTRL"}, -{ERR_PACK(0,BIO_F_MEM_READ,0), "MEM_READ"}, -{ERR_PACK(0,BIO_F_MEM_WRITE,0), "MEM_WRITE"}, -{ERR_PACK(0,BIO_F_SSL_NEW,0), "SSL_new"}, -{ERR_PACK(0,BIO_F_WSASTARTUP,0), "WSASTARTUP"}, +{ERR_FUNC(BIO_F_ACPT_STATE), "ACPT_STATE"}, +{ERR_FUNC(BIO_F_BIO_ACCEPT), "BIO_accept"}, +{ERR_FUNC(BIO_F_BIO_BER_GET_HEADER), "BIO_BER_GET_HEADER"}, +{ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL), "BIO_callback_ctrl"}, +{ERR_FUNC(BIO_F_BIO_CTRL), "BIO_ctrl"}, +{ERR_FUNC(BIO_F_BIO_GETHOSTBYNAME), "BIO_gethostbyname"}, +{ERR_FUNC(BIO_F_BIO_GETS), "BIO_gets"}, +{ERR_FUNC(BIO_F_BIO_GET_ACCEPT_SOCKET), "BIO_get_accept_socket"}, +{ERR_FUNC(BIO_F_BIO_GET_HOST_IP), "BIO_get_host_ip"}, +{ERR_FUNC(BIO_F_BIO_GET_PORT), "BIO_get_port"}, +{ERR_FUNC(BIO_F_BIO_MAKE_PAIR), "BIO_MAKE_PAIR"}, +{ERR_FUNC(BIO_F_BIO_NEW), "BIO_new"}, +{ERR_FUNC(BIO_F_BIO_NEW_FILE), "BIO_new_file"}, +{ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF), "BIO_new_mem_buf"}, +{ERR_FUNC(BIO_F_BIO_NREAD), "BIO_nread"}, +{ERR_FUNC(BIO_F_BIO_NREAD0), "BIO_nread0"}, +{ERR_FUNC(BIO_F_BIO_NWRITE), "BIO_nwrite"}, +{ERR_FUNC(BIO_F_BIO_NWRITE0), "BIO_nwrite0"}, +{ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"}, +{ERR_FUNC(BIO_F_BIO_READ), "BIO_read"}, +{ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"}, +{ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"}, +{ERR_FUNC(BIO_F_BUFFER_CTRL), "BUFFER_CTRL"}, +{ERR_FUNC(BIO_F_CONN_CTRL), "CONN_CTRL"}, +{ERR_FUNC(BIO_F_CONN_STATE), "CONN_STATE"}, +{ERR_FUNC(BIO_F_FILE_CTRL), "FILE_CTRL"}, +{ERR_FUNC(BIO_F_FILE_READ), "FILE_READ"}, +{ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "LINEBUFFER_CTRL"}, +{ERR_FUNC(BIO_F_MEM_READ), "MEM_READ"}, +{ERR_FUNC(BIO_F_MEM_WRITE), "MEM_WRITE"}, +{ERR_FUNC(BIO_F_SSL_NEW), "SSL_new"}, +{ERR_FUNC(BIO_F_WSASTARTUP), "WSASTARTUP"}, {0,NULL} }; static ERR_STRING_DATA BIO_str_reasons[]= { -{BIO_R_ACCEPT_ERROR ,"accept error"}, -{BIO_R_BAD_FOPEN_MODE ,"bad fopen mode"}, -{BIO_R_BAD_HOSTNAME_LOOKUP ,"bad hostname lookup"}, -{BIO_R_BROKEN_PIPE ,"broken pipe"}, -{BIO_R_CONNECT_ERROR ,"connect error"}, -{BIO_R_EOF_ON_MEMORY_BIO ,"EOF on memory BIO"}, -{BIO_R_ERROR_SETTING_NBIO ,"error setting nbio"}, -{BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET,"error setting nbio on accepted socket"}, -{BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET,"error setting nbio on accept socket"}, -{BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET ,"gethostbyname addr is not af inet"}, -{BIO_R_INVALID_ARGUMENT ,"invalid argument"}, -{BIO_R_INVALID_IP_ADDRESS ,"invalid ip address"}, -{BIO_R_IN_USE ,"in use"}, -{BIO_R_KEEPALIVE ,"keepalive"}, -{BIO_R_NBIO_CONNECT_ERROR ,"nbio connect error"}, -{BIO_R_NO_ACCEPT_PORT_SPECIFIED ,"no accept port specified"}, -{BIO_R_NO_HOSTNAME_SPECIFIED ,"no hostname specified"}, -{BIO_R_NO_PORT_DEFINED ,"no port defined"}, -{BIO_R_NO_PORT_SPECIFIED ,"no port specified"}, -{BIO_R_NO_SUCH_FILE ,"no such file"}, -{BIO_R_NULL_PARAMETER ,"null parameter"}, -{BIO_R_TAG_MISMATCH ,"tag mismatch"}, -{BIO_R_UNABLE_TO_BIND_SOCKET ,"unable to bind socket"}, -{BIO_R_UNABLE_TO_CREATE_SOCKET ,"unable to create socket"}, -{BIO_R_UNABLE_TO_LISTEN_SOCKET ,"unable to listen socket"}, -{BIO_R_UNINITIALIZED ,"uninitialized"}, -{BIO_R_UNSUPPORTED_METHOD ,"unsupported method"}, -{BIO_R_WRITE_TO_READ_ONLY_BIO ,"write to read only BIO"}, -{BIO_R_WSASTARTUP ,"WSAStartup"}, +{ERR_REASON(BIO_R_ACCEPT_ERROR) ,"accept error"}, +{ERR_REASON(BIO_R_BAD_FOPEN_MODE) ,"bad fopen mode"}, +{ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP) ,"bad hostname lookup"}, +{ERR_REASON(BIO_R_BROKEN_PIPE) ,"broken pipe"}, +{ERR_REASON(BIO_R_CONNECT_ERROR) ,"connect error"}, +{ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO) ,"EOF on memory BIO"}, +{ERR_REASON(BIO_R_ERROR_SETTING_NBIO) ,"error setting nbio"}, +{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET),"error setting nbio on accepted socket"}, +{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET),"error setting nbio on accept socket"}, +{ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),"gethostbyname addr is not af inet"}, +{ERR_REASON(BIO_R_INVALID_ARGUMENT) ,"invalid argument"}, +{ERR_REASON(BIO_R_INVALID_IP_ADDRESS) ,"invalid ip address"}, +{ERR_REASON(BIO_R_IN_USE) ,"in use"}, +{ERR_REASON(BIO_R_KEEPALIVE) ,"keepalive"}, +{ERR_REASON(BIO_R_NBIO_CONNECT_ERROR) ,"nbio connect error"}, +{ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED),"no accept port specified"}, +{ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED) ,"no hostname specified"}, +{ERR_REASON(BIO_R_NO_PORT_DEFINED) ,"no port defined"}, +{ERR_REASON(BIO_R_NO_PORT_SPECIFIED) ,"no port specified"}, +{ERR_REASON(BIO_R_NO_SUCH_FILE) ,"no such file"}, +{ERR_REASON(BIO_R_NULL_PARAMETER) ,"null parameter"}, +{ERR_REASON(BIO_R_TAG_MISMATCH) ,"tag mismatch"}, +{ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET) ,"unable to bind socket"}, +{ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET),"unable to create socket"}, +{ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET),"unable to listen socket"}, +{ERR_REASON(BIO_R_UNINITIALIZED) ,"uninitialized"}, +{ERR_REASON(BIO_R_UNSUPPORTED_METHOD) ,"unsupported method"}, +{ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO),"write to read only BIO"}, +{ERR_REASON(BIO_R_WSASTARTUP) ,"WSAStartup"}, {0,NULL} }; @@ -139,15 +143,12 @@ static ERR_STRING_DATA BIO_str_reasons[]= void ERR_load_BIO_strings(void) { - static int init=1; - - if (init) - { - init=0; #ifndef OPENSSL_NO_ERR - ERR_load_strings(ERR_LIB_BIO,BIO_str_functs); - ERR_load_strings(ERR_LIB_BIO,BIO_str_reasons); -#endif + if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) + { + ERR_load_strings(0,BIO_str_functs); + ERR_load_strings(0,BIO_str_reasons); } +#endif } diff --git a/crypto/bio/bio_lcl.h b/crypto/bio/bio_lcl.h new file mode 100644 index 0000000000..e7f7ec8d8b --- /dev/null +++ b/crypto/bio/bio_lcl.h @@ -0,0 +1,36 @@ +#include <openssl/bio.h> + +#if BIO_FLAGS_UPLINK==0 +/* Shortcut UPLINK calls on most platforms... */ +#define UP_stdin stdin +#define UP_stdout stdout +#define UP_stderr stderr +#define UP_fprintf fprintf +#define UP_fgets fgets +#define UP_fread fread +#define UP_fwrite fwrite +#undef UP_fsetmod +#define UP_feof feof +#define UP_fclose fclose + +#define UP_fopen fopen +#define UP_fseek fseek +#define UP_ftell ftell +#define UP_fflush fflush +#define UP_ferror ferror +#ifdef _WIN32 +#define UP_fileno _fileno +#define UP_open _open +#define UP_read _read +#define UP_write _write +#define UP_lseek _lseek +#define UP_close _close +#else +#define UP_fileno fileno +#define UP_open open +#define UP_read read +#define UP_write write +#define UP_lseek lseek +#define UP_close close +#endif +#endif diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index 5e96772ca5..77f4de9c32 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -141,6 +141,52 @@ int BIO_free(BIO *a) void BIO_vfree(BIO *a) { BIO_free(a); } +void BIO_clear_flags(BIO *b, int flags) + { + b->flags &= ~flags; + } + +int BIO_test_flags(const BIO *b, int flags) + { + return (b->flags & flags); + } + +void BIO_set_flags(BIO *b, int flags) + { + b->flags |= flags; + } + +long (*BIO_get_callback(const BIO *b))(struct bio_st *,int,const char *,int, long,long) + { + return b->callback; + } + +void BIO_set_callback(BIO *b, long (*cb)(struct bio_st *,int,const char *,int, long,long)) + { + b->callback = cb; + } + +void BIO_set_callback_arg(BIO *b, char *arg) + { + b->cb_arg = arg; + } + +char * BIO_get_callback_arg(const BIO *b) + { + return b->cb_arg; + } + +const char * BIO_method_name(const BIO *b) + { + return b->method->name; + } + +int BIO_method_type(const BIO *b) + { + return b->method->type; + } + + int BIO_read(BIO *b, void *out, int outl) { int i; @@ -338,7 +384,7 @@ long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const c if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) { - BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD); + BIOerr(BIO_F_BIO_CALLBACK_CTRL,BIO_R_UNSUPPORTED_METHOD); return(-2); } @@ -383,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); } @@ -395,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/crypto/bio/bss_acpt.c b/crypto/bio/bss_acpt.c index d090b7272f..826f761143 100644 --- a/crypto/bio/bss_acpt.c +++ b/crypto/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/crypto/bio/bss_bio.c b/crypto/bio/bss_bio.c index 0f9f0955b4..76bd48e767 100644 --- a/crypto/bio/bss_bio.c +++ b/crypto/bio/bss_bio.c @@ -919,6 +919,6 @@ int BIO_nwrite(BIO *bio, char **buf, int num) ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); if (ret > 0) - bio->num_read += ret; + bio->num_write += ret; return ret; } diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c index 8dc77abc53..51fbd1525c 100644 --- a/crypto/bio/bss_conn.c +++ b/crypto/bio/bss_conn.c @@ -535,7 +535,7 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_C_DO_STATE_MACHINE: /* use this one to start the connection */ - if (!data->state != BIO_CONN_S_OK) + if (data->state != BIO_CONN_S_OK) ret=(long)conn_state(b,data); else ret=1; @@ -656,9 +656,9 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_CTRL_GET_CALLBACK: { - int (**fptr)(); + int (**fptr)(const BIO *bio,int state,int xret); - fptr=(int (**)())ptr; + fptr=(int (**)(const BIO *bio,int state,int xret))ptr; *fptr=data->info_callback; } break; diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c new file mode 100644 index 0000000000..eb7e365467 --- /dev/null +++ b/crypto/bio/bss_dgram.c @@ -0,0 +1,830 @@ +/* crypto/bio/bio_dgram.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef OPENSSL_NO_DGRAM + +#include <stdio.h> +#include <errno.h> +#define USE_SOCKETS +#include "cryptlib.h" + +#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 */ +#define sock_read SockRead +#define sock_puts SockPuts +#endif + +static int dgram_write(BIO *h, const char *buf, int num); +static int dgram_read(BIO *h, char *buf, int size); +static int dgram_puts(BIO *h, const char *str); +static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int dgram_new(BIO *h); +static int dgram_free(BIO *data); +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, + "datagram socket", + dgram_write, + dgram_read, + dgram_puts, + NULL, /* dgram_gets, */ + dgram_ctrl, + dgram_new, + dgram_free, + NULL, + }; + +typedef struct bio_dgram_data_st + { + 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) + { + return(&methods_dgramp); + } + +BIO *BIO_new_dgram(int fd, int close_flag) + { + BIO *ret; + + ret=BIO_new(BIO_s_datagram()); + if (ret == NULL) return(NULL); + BIO_set_fd(ret,fd,close_flag); + return(ret); + } + +static int dgram_new(BIO *bi) + { + bio_dgram_data *data = NULL; + + bi->init=0; + bi->num=0; + data = OPENSSL_malloc(sizeof(bio_dgram_data)); + if (data == NULL) + return 0; + memset(data, 0x00, sizeof(bio_dgram_data)); + bi->ptr = data; + + bi->flags=0; + return(1); + } + +static int dgram_free(BIO *a) + { + bio_dgram_data *data; + + if (a == NULL) return(0); + if ( ! dgram_clear(a)) + return 0; + + data = (bio_dgram_data *)a->ptr; + if(data != NULL) OPENSSL_free(data); + + return(1); + } + +static int dgram_clear(BIO *a) + { + if (a == NULL) return(0); + if (a->shutdown) + { + if (a->init) + { + SHUTDOWN2(a->num); + } + a->init=0; + a->flags=0; + } + 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 { + /* + * 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(&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_SET_PEER, 0, &sa.peer); + + BIO_clear_retry_flags(b); + if (ret < 0) + { + if (BIO_dgram_should_retry(ret)) + { + BIO_set_retry_read(b); + data->_errno = get_last_socket_error(); + } + } + } + return(ret); + } + +static int dgram_write(BIO *b, const char *in, int inl) + { + int ret; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + clear_socket_error(); + + 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.sa, peerlen); +#else + ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); +#endif + } + + BIO_clear_retry_flags(b); + if (ret <= 0) + { + if (BIO_dgram_should_retry(ret)) + { + BIO_set_retry_write(b); + data->_errno = get_last_socket_error(); + +#if 0 /* higher layers are responsible for querying MTU, if necessary */ + if ( data->_errno == EMSGSIZE) + /* retrieve the new MTU */ + BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); +#endif + } + } + return(ret); + } + +static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) + { + long ret=1; + 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; + + 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: + dgram_clear(b); + b->num= *((int *)ptr); + b->shutdown=(int)num; + b->init=1; + break; + case BIO_C_GET_FD: + if (b->init) + { + ip=(int *)ptr; + if (ip != NULL) *ip=b->num; + ret=b->num; + } + else + ret= -1; + break; + case BIO_CTRL_GET_CLOSE: + ret=b->shutdown; + break; + 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; + break; + case BIO_CTRL_DGRAM_CONNECT: + to = (struct sockaddr *)ptr; +#if 0 + if (connect(b->num, to, sizeof(struct sockaddr)) < 0) + { perror("connect"); ret = 0; } + else + { +#endif + 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 */ + case BIO_CTRL_DGRAM_MTU_DISCOVER: +#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: +#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: + 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; + break; + case BIO_CTRL_DGRAM_SET_MTU: + data->mtu = num; + ret = num; + break; + case BIO_CTRL_DGRAM_SET_CONNECTED: + to = (struct sockaddr *)ptr; + + if ( to != NULL) + { + data->connected = 1; + 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(data->peer)); + } + 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 + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void*)&timeout, sizeof(timeout)) < 0) + { perror("setsockopt"); ret = -1; } + } +#else + if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, + sizeof(struct timeval)) < 0) + { perror("setsockopt"); ret = -1; } +#endif + break; + case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: +#ifdef OPENSSL_SYS_WINDOWS + { + int timeout, sz = sizeof(timeout); + struct timeval *tv = (struct timeval *)ptr; + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void*)&timeout, &sz) < 0) + { perror("getsockopt"); ret = -1; } + else + { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } + } +#else + if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + ptr, (void *)&ret) < 0) + { perror("getsockopt"); ret = -1; } +#endif + break; +#endif +#if defined(SO_SNDTIMEO) + case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: +#ifdef OPENSSL_SYS_WINDOWS + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; + if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void*)&timeout, sizeof(timeout)) < 0) + { perror("setsockopt"); ret = -1; } + } +#else + if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, + sizeof(struct timeval)) < 0) + { perror("setsockopt"); ret = -1; } +#endif + break; + case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: +#ifdef OPENSSL_SYS_WINDOWS + { + int timeout, sz = sizeof(timeout); + struct timeval *tv = (struct timeval *)ptr; + if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void*)&timeout, &sz) < 0) + { perror("getsockopt"); ret = -1; } + else + { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } + } +#else + if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + ptr, (void *)&ret) < 0) + { perror("getsockopt"); ret = -1; } +#endif + break; +#endif + case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: + /* fall-through */ + case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: +#ifdef OPENSSL_SYS_WINDOWS + if ( data->_errno == WSAETIMEDOUT) +#else + if ( data->_errno == EAGAIN) +#endif + { + ret = 1; + data->_errno = 0; + } + else + ret = 0; + break; +#ifdef EMSGSIZE + case BIO_CTRL_DGRAM_MTU_EXCEEDED: + if ( data->_errno == EMSGSIZE) + { + ret = 1; + data->_errno = 0; + } + else + ret = 0; + break; +#endif + default: + ret=0; + break; + } + return(ret); + } + +static int dgram_puts(BIO *bp, const char *str) + { + int n,ret; + + n=strlen(str); + ret=dgram_write(bp,str,n); + return(ret); + } + +static int BIO_dgram_should_retry(int i) + { + int err; + + if ((i == 0) || (i == -1)) + { + err=get_last_socket_error(); + +#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ + if ((i == -1) && (err == 0)) + return(1); +#endif + + return(BIO_dgram_non_fatal_error(err)); + } + return(0); + } + +int BIO_dgram_non_fatal_error(int err) + { + switch (err) + { +#if defined(OPENSSL_SYS_WINDOWS) +# if defined(WSAEWOULDBLOCK) + case WSAEWOULDBLOCK: +# endif + +# if 0 /* This appears to always be an error */ +# if defined(WSAENOTCONN) + case WSAENOTCONN: +# endif +# endif +#endif + +#ifdef EWOULDBLOCK +# ifdef WSAEWOULDBLOCK +# if WSAEWOULDBLOCK != EWOULDBLOCK + case EWOULDBLOCK: +# endif +# else + case EWOULDBLOCK: +# endif +#endif + +#ifdef EINTR + case EINTR: +#endif + +#ifdef EAGAIN +#if EWOULDBLOCK != EAGAIN + case EAGAIN: +# endif +#endif + +#ifdef EPROTO + case EPROTO: +#endif + +#ifdef EINPROGRESS + case EINPROGRESS: +#endif + +#ifdef EALREADY + case EALREADY: +#endif + + return(1); + /* break; */ + default: + break; + } + 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/crypto/bio/bss_fd.c b/crypto/bio/bss_fd.c index 5e3e187de6..d1bf85aae1 100644 --- a/crypto/bio/bss_fd.c +++ b/crypto/bio/bss_fd.c @@ -60,11 +60,31 @@ #include <errno.h> #define USE_SOCKETS #include "cryptlib.h" -#include <openssl/bio.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 + * in kernel-side per-process table], corresponding descriptors on + * platforms which require "UPLINK" interface seem to be indexes + * in a user-land, non-global table. Well, in fact they are indexes + * in stdio _iob[], and recall that _iob[] was the very reason why + * "UPLINK" interface was introduced in first place. But one way on + * another. Neither libcrypto or libssl use this BIO meaning that + * file descriptors can only be provided by application. Therefore + * "UPLINK" calls are due... + */ +#include "bio_lcl.h" 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); @@ -76,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, @@ -100,9 +120,9 @@ BIO *BIO_new_fd(int fd,int close_flag) static int fd_new(BIO *bi) { bi->init=0; - bi->num=0; + bi->num=-1; bi->ptr=NULL; - bi->flags=0; + bi->flags=BIO_FLAGS_UPLINK; /* essentially redundant */ return(1); } @@ -113,10 +133,10 @@ static int fd_free(BIO *a) { if (a->init) { - close(a->num); + UP_close(a->num); } a->init=0; - a->flags=0; + a->flags=BIO_FLAGS_UPLINK; } return(1); } @@ -128,7 +148,7 @@ static int fd_read(BIO *b, char *out,int outl) if (out != NULL) { clear_sys_error(); - ret=read(b->num,out,outl); + ret=UP_read(b->num,out,outl); BIO_clear_retry_flags(b); if (ret <= 0) { @@ -143,7 +163,7 @@ static int fd_write(BIO *b, const char *in, int inl) { int ret; clear_sys_error(); - ret=write(b->num,in,inl); + ret=UP_write(b->num,in,inl); BIO_clear_retry_flags(b); if (ret <= 0) { @@ -163,11 +183,11 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_RESET: num=0; case BIO_C_FILE_SEEK: - ret=(long)lseek(b->num,num,0); + ret=(long)UP_lseek(b->num,num,0); break; case BIO_C_FILE_TELL: case BIO_CTRL_INFO: - ret=(long)lseek(b->num,0,1); + ret=(long)UP_lseek(b->num,0,1); break; case BIO_C_SET_FD: fd_free(b); @@ -215,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; @@ -280,3 +316,4 @@ int BIO_fd_non_fatal_error(int err) } return(0); } +#endif diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c index 764b7f8372..a85ac209f0 100644 --- a/crypto/bio/bss_file.c +++ b/crypto/bio/bss_file.c @@ -65,12 +65,34 @@ #ifndef HEADER_BSS_FILE_C #define HEADER_BSS_FILE_C +#if defined(__linux) || defined(__sun) || defined(__hpux) +/* Following definition aliases fopen to fopen64 on above mentioned + * platforms. This makes it possible to open and sequentially access + * files larger than 2GB from 32-bit application. It does not allow to + * traverse them beyond 2GB with fseek/ftell, but on the other hand *no* + * 32-bit platform permits that, not with fseek/ftell. Not to mention + * that breaking 2GB limit for seeking would require surgery to *our* + * API. But sequential access suffices for practical cases when you + * can run into large files, such as fingerprinting, so we can let API + * alone. For reference, the list of 32-bit platforms which allow for + * sequential access of large files without extra "magic" comprise *BSD, + * Darwin, IRIX... + */ +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif +#endif + #include <stdio.h> #include <errno.h> #include "cryptlib.h" -#include <openssl/bio.h> +#include "bio_lcl.h" #include <openssl/err.h> +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) +#include <nwfileio.h> +#endif + #if !defined(OPENSSL_NO_STDIO) static int MS_CALLBACK file_write(BIO *h, const char *buf, int num); @@ -109,9 +131,13 @@ 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); + } + BIO_clear_flags(ret,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */ BIO_set_fp(ret,file,BIO_CLOSE); return(ret); } @@ -123,6 +149,7 @@ BIO *BIO_new_fp(FILE *stream, int close_flag) if ((ret=BIO_new(BIO_s_file())) == NULL) return(NULL); + BIO_set_flags(ret,BIO_FLAGS_UPLINK); /* redundant, left for documentation puposes */ BIO_set_fp(ret,stream,close_flag); return(ret); } @@ -137,6 +164,7 @@ static int MS_CALLBACK file_new(BIO *bi) bi->init=0; bi->num=0; bi->ptr=NULL; + bi->flags=BIO_FLAGS_UPLINK; /* default to UPLINK */ return(1); } @@ -147,8 +175,12 @@ static int MS_CALLBACK file_free(BIO *a) { if ((a->init) && (a->ptr != NULL)) { - fclose((FILE *)a->ptr); + if (a->flags&BIO_FLAGS_UPLINK) + UP_fclose (a->ptr); + else + fclose (a->ptr); a->ptr=NULL; + a->flags=BIO_FLAGS_UPLINK; } a->init=0; } @@ -161,8 +193,11 @@ static int MS_CALLBACK file_read(BIO *b, char *out, int outl) if (b->init && (out != NULL)) { - ret=fread(out,1,(int)outl,(FILE *)b->ptr); - if(ret == 0 && ferror((FILE *)b->ptr)) + if (b->flags&BIO_FLAGS_UPLINK) + ret=UP_fread(out,1,(int)outl,b->ptr); + else + ret=fread(out,1,(int)outl,(FILE *)b->ptr); + if(ret == 0 && (b->flags&BIO_FLAGS_UPLINK)?UP_ferror((FILE *)b->ptr):ferror((FILE *)b->ptr)) { SYSerr(SYS_F_FREAD,get_last_sys_error()); BIOerr(BIO_F_FILE_READ,ERR_R_SYS_LIB); @@ -178,7 +213,11 @@ static int MS_CALLBACK file_write(BIO *b, const char *in, int inl) if (b->init && (in != NULL)) { - if (fwrite(in,(int)inl,1,(FILE *)b->ptr)) + if (b->flags&BIO_FLAGS_UPLINK) + ret=UP_fwrite(in,(int)inl,1,b->ptr); + else + ret=fwrite(in,(int)inl,1,(FILE *)b->ptr); + if (ret) ret=inl; /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */ /* according to Tim Hudson <tjh@cryptsoft.com>, the commented @@ -199,35 +238,59 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) { case BIO_C_FILE_SEEK: case BIO_CTRL_RESET: - ret=(long)fseek(fp,num,0); + if (b->flags&BIO_FLAGS_UPLINK) + ret=(long)UP_fseek(b->ptr,num,0); + else + ret=(long)fseek(fp,num,0); break; case BIO_CTRL_EOF: - ret=(long)feof(fp); + if (b->flags&BIO_FLAGS_UPLINK) + ret=(long)UP_feof(fp); + else + ret=(long)feof(fp); break; case BIO_C_FILE_TELL: case BIO_CTRL_INFO: - ret=ftell(fp); + if (b->flags&BIO_FLAGS_UPLINK) + ret=UP_ftell(b->ptr); + else + ret=ftell(fp); break; case BIO_C_SET_FILE_PTR: file_free(b); b->shutdown=(int)num&BIO_CLOSE; - b->ptr=(char *)ptr; + b->ptr=ptr; b->init=1; +#if BIO_FLAGS_UPLINK!=0 +#if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) +#define _IOB_ENTRIES 20 +#endif +#if defined(_IOB_ENTRIES) + /* Safety net to catch purely internal BIO_set_fp calls */ + if ((size_t)ptr >= (size_t)stdin && + (size_t)ptr < (size_t)(stdin+_IOB_ENTRIES)) + BIO_clear_flags(b,BIO_FLAGS_UPLINK); +#endif +#endif +#ifdef UP_fsetmode + if (b->flags&BIO_FLAGS_UPLINK) + UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b'); + else +#endif { #if defined(OPENSSL_SYS_WINDOWS) - int fd = fileno((FILE*)ptr); + int fd = _fileno((FILE*)ptr); if (num & BIO_FP_TEXT) _setmode(fd,_O_TEXT); else _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); + setmode(fd,O_TEXT); else - _setmode(fd,O_BINARY); + setmode(fd,O_BINARY); #elif defined(OPENSSL_SYS_MSDOS) int fd = fileno((FILE*)ptr); /* Set correct text/binary mode */ @@ -244,7 +307,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); @@ -286,7 +349,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) else strcat(p,"t"); #endif -fp=fopen(ptr,p); + fp=fopen(ptr,p); if (fp == NULL) { SYSerr(SYS_F_FOPEN,get_last_sys_error()); @@ -295,8 +358,9 @@ fp=fopen(ptr,p); ret=0; break; } - b->ptr=(char *)fp; + b->ptr=fp; b->init=1; + BIO_clear_flags(b,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */ break; case BIO_C_GET_FILE_PTR: /* the ptr parameter is actually a FILE ** in this case. */ @@ -313,7 +377,10 @@ fp=fopen(ptr,p); b->shutdown=(int)num; break; case BIO_CTRL_FLUSH: - fflush((FILE *)b->ptr); + if (b->flags&BIO_FLAGS_UPLINK) + UP_fflush(b->ptr); + else + fflush((FILE *)b->ptr); break; case BIO_CTRL_DUP: ret=1; @@ -335,9 +402,19 @@ static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) int ret=0; buf[0]='\0'; - fgets(buf,size,(FILE *)bp->ptr); + if (bp->flags&BIO_FLAGS_UPLINK) + { + if (!UP_fgets(buf,size,bp->ptr)) + goto err; + } + else + { + if (!fgets(buf,size,(FILE *)bp->ptr)) + goto err; + } if (buf[0] != '\0') ret=strlen(buf); + err: return(ret); } diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c index 5a5de26c9b..ff95d9cd60 100644 --- a/crypto/bio/bss_log.c +++ b/crypto/bio/bss_log.c @@ -71,7 +71,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> @@ -123,18 +122,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= { @@ -176,7 +163,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]; @@ -250,35 +237,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) { @@ -302,19 +274,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/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c index a4edb711ae..37d4194e4b 100644 --- a/crypto/bio/bss_mem.c +++ b/crypto/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) { @@ -284,6 +280,7 @@ static int mem_gets(BIO *bp, char *buf, int size) BIO_clear_retry_flags(bp); j=bm->length; + if ((size-1) < j) j=size-1; if (j <= 0) { *buf='\0'; @@ -292,17 +289,18 @@ static int mem_gets(BIO *bp, char *buf, int size) p=bm->data; for (i=0; i<j; i++) { - if (p[i] == '\n') break; - } - if (i == j) - { - BIO_set_retry_read(bp); - /* return(-1); change the semantics 0.6.6a */ + if (p[i] == '\n') + { + i++; + break; + } } - else - i++; - /* i is the max to copy */ - if ((size-1) < i) i=size-1; + + /* + * i is now the max num of bytes to copy, either j or up to + * and including the first newline + */ + i=mem_read(bp,buf,i); if (i > 0) buf[i]='\0'; ret=i; diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c index a21358bc88..9bf5b3df0b 100644 --- a/crypto/bio/bss_sock.c +++ b/crypto/bio/bss_sock.c @@ -61,6 +61,9 @@ #include <errno.h> #define USE_SOCKETS #include "cryptlib.h" + +#ifndef OPENSSL_NO_SOCK + #include <openssl/bio.h> /* The following types are required to work in a 64-bit environment on @@ -375,3 +378,5 @@ int BIO_sock_non_fatal_error(int err) } return(0); } + +#endif /* #ifndef OPENSSL_NO_SOCK */ |