Support for Signal calls.

Merge in RedPhone

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2015-09-09 13:54:29 -07:00
parent 3d4ae60d81
commit d83a3d71bc
2585 changed files with 803492 additions and 45 deletions

View File

@@ -0,0 +1,187 @@
/* crypto/bio/b_dump.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/*
* Stolen from tjh's ssl/ssl_trc.c stuff.
*/
#include <stdio.h>
#include "cryptlib.h"
#include "bio_lcl.h"
#define TRUNCATE
#define DUMP_WIDTH 16
#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4))
int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
void *u, const char *s, int len)
{
return BIO_dump_indent_cb(cb, u, s, len, 0);
}
int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
void *u, const char *s, int len, int indent)
{
int ret=0;
char buf[288+1],tmp[20],str[128+1];
int i,j,rows,trc;
unsigned char ch;
int dump_width;
trc=0;
#ifdef TRUNCATE
for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--)
trc++;
#endif
if (indent < 0)
indent = 0;
if (indent)
{
if (indent > 128) indent=128;
memset(str,' ',indent);
}
str[indent]='\0';
dump_width=DUMP_WIDTH_LESS_INDENT(indent);
rows=(len/dump_width);
if ((rows*dump_width)<len)
rows++;
for(i=0;i<rows;i++)
{
buf[0]='\0'; /* start with empty string */
BUF_strlcpy(buf,str,sizeof buf);
BIO_snprintf(tmp,sizeof tmp,"%04x - ",i*dump_width);
BUF_strlcat(buf,tmp,sizeof buf);
for(j=0;j<dump_width;j++)
{
if (((i*dump_width)+j)>=len)
{
BUF_strlcat(buf," ",sizeof buf);
}
else
{
ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
BIO_snprintf(tmp,sizeof tmp,"%02x%c",ch,
j==7?'-':' ');
BUF_strlcat(buf,tmp,sizeof buf);
}
}
BUF_strlcat(buf," ",sizeof buf);
for(j=0;j<dump_width;j++)
{
if (((i*dump_width)+j)>=len)
break;
ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
#ifndef CHARSET_EBCDIC
BIO_snprintf(tmp,sizeof tmp,"%c",
((ch>=' ')&&(ch<='~'))?ch:'.');
#else
BIO_snprintf(tmp,sizeof tmp,"%c",
((ch>=os_toascii[' '])&&(ch<=os_toascii['~']))
? os_toebcdic[ch]
: '.');
#endif
BUF_strlcat(buf,tmp,sizeof buf);
}
BUF_strlcat(buf,"\n",sizeof buf);
/* if this is the last call then update the ddt_dump thing so
* that we will move the selection point in the debug window
*/
ret+=cb((void *)buf,strlen(buf),u);
}
#ifdef TRUNCATE
if (trc > 0)
{
BIO_snprintf(buf,sizeof buf,"%s%04x - <SPACES/NULS>\n",str,
len+trc);
ret+=cb((void *)buf,strlen(buf),u);
}
#endif
return(ret);
}
#ifndef OPENSSL_NO_FP_API
static int write_fp(const void *data, size_t len, void *fp)
{
return UP_fwrite(data, len, 1, fp);
}
int BIO_dump_fp(FILE *fp, const char *s, int len)
{
return BIO_dump_cb(write_fp, fp, s, len);
}
int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
{
return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
}
#endif
static int write_bio(const void *data, size_t len, void *bp)
{
return BIO_write((BIO *)bp, (const char *)data, len);
}
int BIO_dump(BIO *bp, const char *s, int len)
{
return BIO_dump_cb(write_bio, bp, s, len);
}
int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
{
return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
}

View File

@@ -0,0 +1,842 @@
/* crypto/bio/b_print.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* disable assert() unless BIO_DEBUG has been defined */
#ifndef BIO_DEBUG
# ifndef NDEBUG
# define NDEBUG
# endif
#endif
/*
* Stolen from tjh's ssl/ssl_trc.c stuff.
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <limits.h>
#include "cryptlib.h"
#ifndef NO_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <openssl/bn.h> /* To get BN_LLONG properly defined */
#include <openssl/bio.h>
#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
# ifndef HAVE_LONG_LONG
# define HAVE_LONG_LONG 1
# endif
#endif
/***************************************************************************/
/*
* Copyright Patrick Powell 1995
* This code is based on code written by Patrick Powell <papowell@astart.com>
* It may be used for any purpose as long as this notice remains intact
* on all source code distributions.
*/
/*
* This code contains numerious changes and enhancements which were
* made by lots of contributors over the last years to Patrick Powell's
* original code:
*
* o Patrick Powell <papowell@astart.com> (1995)
* o Brandon Long <blong@fiction.net> (1996, for Mutt)
* o Thomas Roessler <roessler@guug.de> (1998, for Mutt)
* o Michael Elkins <me@cs.hmc.edu> (1998, for Mutt)
* o Andrew Tridgell <tridge@samba.org> (1998, for Samba)
* o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP)
* o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
* o ... (for OpenSSL)
*/
#ifdef HAVE_LONG_DOUBLE
#define LDOUBLE long double
#else
#define LDOUBLE double
#endif
#ifdef HAVE_LONG_LONG
# if defined(_WIN32) && !defined(__GNUC__)
# define LLONG __int64
# else
# define LLONG long long
# endif
#else
#define LLONG long
#endif
static void fmtstr (char **, char **, size_t *, size_t *,
const char *, int, int, int);
static void fmtint (char **, char **, size_t *, size_t *,
LLONG, int, int, int, int);
static void fmtfp (char **, char **, size_t *, size_t *,
LDOUBLE, int, int, int);
static void doapr_outch (char **, char **, size_t *, size_t *, int);
static void _dopr(char **sbuffer, char **buffer,
size_t *maxlen, size_t *retlen, int *truncated,
const char *format, va_list args);
/* format read states */
#define DP_S_DEFAULT 0
#define DP_S_FLAGS 1
#define DP_S_MIN 2
#define DP_S_DOT 3
#define DP_S_MAX 4
#define DP_S_MOD 5
#define DP_S_CONV 6
#define DP_S_DONE 7
/* format flags - Bits */
#define DP_F_MINUS (1 << 0)
#define DP_F_PLUS (1 << 1)
#define DP_F_SPACE (1 << 2)
#define DP_F_NUM (1 << 3)
#define DP_F_ZERO (1 << 4)
#define DP_F_UP (1 << 5)
#define DP_F_UNSIGNED (1 << 6)
/* conversion flags */
#define DP_C_SHORT 1
#define DP_C_LONG 2
#define DP_C_LDOUBLE 3
#define DP_C_LLONG 4
/* some handy macros */
#define char_to_int(p) (p - '0')
#define OSSL_MAX(p,q) ((p >= q) ? p : q)
static void
_dopr(
char **sbuffer,
char **buffer,
size_t *maxlen,
size_t *retlen,
int *truncated,
const char *format,
va_list args)
{
char ch;
LLONG value;
LDOUBLE fvalue;
char *strvalue;
int min;
int max;
int state;
int flags;
int cflags;
size_t currlen;
state = DP_S_DEFAULT;
flags = currlen = cflags = min = 0;
max = -1;
ch = *format++;
while (state != DP_S_DONE) {
if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
state = DP_S_DONE;
switch (state) {
case DP_S_DEFAULT:
if (ch == '%')
state = DP_S_FLAGS;
else
doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
ch = *format++;
break;
case DP_S_FLAGS:
switch (ch) {
case '-':
flags |= DP_F_MINUS;
ch = *format++;
break;
case '+':
flags |= DP_F_PLUS;
ch = *format++;
break;
case ' ':
flags |= DP_F_SPACE;
ch = *format++;
break;
case '#':
flags |= DP_F_NUM;
ch = *format++;
break;
case '0':
flags |= DP_F_ZERO;
ch = *format++;
break;
default:
state = DP_S_MIN;
break;
}
break;
case DP_S_MIN:
if (isdigit((unsigned char)ch)) {
min = 10 * min + char_to_int(ch);
ch = *format++;
} else if (ch == '*') {
min = va_arg(args, int);
ch = *format++;
state = DP_S_DOT;
} else
state = DP_S_DOT;
break;
case DP_S_DOT:
if (ch == '.') {
state = DP_S_MAX;
ch = *format++;
} else
state = DP_S_MOD;
break;
case DP_S_MAX:
if (isdigit((unsigned char)ch)) {
if (max < 0)
max = 0;
max = 10 * max + char_to_int(ch);
ch = *format++;
} else if (ch == '*') {
max = va_arg(args, int);
ch = *format++;
state = DP_S_MOD;
} else
state = DP_S_MOD;
break;
case DP_S_MOD:
switch (ch) {
case 'h':
cflags = DP_C_SHORT;
ch = *format++;
break;
case 'l':
if (*format == 'l') {
cflags = DP_C_LLONG;
format++;
} else
cflags = DP_C_LONG;
ch = *format++;
break;
case 'q':
cflags = DP_C_LLONG;
ch = *format++;
break;
case 'L':
cflags = DP_C_LDOUBLE;
ch = *format++;
break;
default:
break;
}
state = DP_S_CONV;
break;
case DP_S_CONV:
switch (ch) {
case 'd':
case 'i':
switch (cflags) {
case DP_C_SHORT:
value = (short int)va_arg(args, int);
break;
case DP_C_LONG:
value = va_arg(args, long int);
break;
case DP_C_LLONG:
value = va_arg(args, LLONG);
break;
default:
value = va_arg(args, int);
break;
}
fmtint(sbuffer, buffer, &currlen, maxlen,
value, 10, min, max, flags);
break;
case 'X':
flags |= DP_F_UP;
/* FALLTHROUGH */
case 'x':
case 'o':
case 'u':
flags |= DP_F_UNSIGNED;
switch (cflags) {
case DP_C_SHORT:
value = (unsigned short int)va_arg(args, unsigned int);
break;
case DP_C_LONG:
value = (LLONG) va_arg(args,
unsigned long int);
break;
case DP_C_LLONG:
value = va_arg(args, unsigned LLONG);
break;
default:
value = (LLONG) va_arg(args,
unsigned int);
break;
}
fmtint(sbuffer, buffer, &currlen, maxlen, value,
ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
min, max, flags);
break;
case 'f':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg(args, LDOUBLE);
else
fvalue = va_arg(args, double);
fmtfp(sbuffer, buffer, &currlen, maxlen,
fvalue, min, max, flags);
break;
case 'E':
flags |= DP_F_UP;
case 'e':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg(args, LDOUBLE);
else
fvalue = va_arg(args, double);
break;
case 'G':
flags |= DP_F_UP;
case 'g':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg(args, LDOUBLE);
else
fvalue = va_arg(args, double);
break;
case 'c':
doapr_outch(sbuffer, buffer, &currlen, maxlen,
va_arg(args, int));
break;
case 's':
strvalue = va_arg(args, char *);
if (max < 0) {
if (buffer)
max = INT_MAX;
else
max = *maxlen;
}
fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
flags, min, max);
break;
case 'p':
value = (long)va_arg(args, void *);
fmtint(sbuffer, buffer, &currlen, maxlen,
value, 16, min, max, flags|DP_F_NUM);
break;
case 'n': /* XXX */
if (cflags == DP_C_SHORT) {
short int *num;
num = va_arg(args, short int *);
*num = currlen;
} else if (cflags == DP_C_LONG) { /* XXX */
long int *num;
num = va_arg(args, long int *);
*num = (long int) currlen;
} else if (cflags == DP_C_LLONG) { /* XXX */
LLONG *num;
num = va_arg(args, LLONG *);
*num = (LLONG) currlen;
} else {
int *num;
num = va_arg(args, int *);
*num = currlen;
}
break;
case '%':
doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
break;
case 'w':
/* not supported yet, treat as next char */
ch = *format++;
break;
default:
/* unknown, skip */
break;
}
ch = *format++;
state = DP_S_DEFAULT;
flags = cflags = min = 0;
max = -1;
break;
case DP_S_DONE:
break;
default:
break;
}
}
*truncated = (currlen > *maxlen - 1);
if (*truncated)
currlen = *maxlen - 1;
doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
*retlen = currlen - 1;
return;
}
static void
fmtstr(
char **sbuffer,
char **buffer,
size_t *currlen,
size_t *maxlen,
const char *value,
int flags,
int min,
int max)
{
int padlen, strln;
int cnt = 0;
if (value == 0)
value = "<NULL>";
for (strln = 0; value[strln]; ++strln)
;
padlen = min - strln;
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen;
while ((padlen > 0) && (cnt < max)) {
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
--padlen;
++cnt;
}
while (*value && (cnt < max)) {
doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
++cnt;
}
while ((padlen < 0) && (cnt < max)) {
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
++padlen;
++cnt;
}
}
static void
fmtint(
char **sbuffer,
char **buffer,
size_t *currlen,
size_t *maxlen,
LLONG value,
int base,
int min,
int max,
int flags)
{
int signvalue = 0;
const char *prefix = "";
unsigned LLONG uvalue;
char convert[DECIMAL_SIZE(value)+3];
int place = 0;
int spadlen = 0;
int zpadlen = 0;
int caps = 0;
if (max < 0)
max = 0;
uvalue = value;
if (!(flags & DP_F_UNSIGNED)) {
if (value < 0) {
signvalue = '-';
uvalue = -value;
} else if (flags & DP_F_PLUS)
signvalue = '+';
else if (flags & DP_F_SPACE)
signvalue = ' ';
}
if (flags & DP_F_NUM) {
if (base == 8) prefix = "0";
if (base == 16) prefix = "0x";
}
if (flags & DP_F_UP)
caps = 1;
do {
convert[place++] =
(caps ? "0123456789ABCDEF" : "0123456789abcdef")
[uvalue % (unsigned) base];
uvalue = (uvalue / (unsigned) base);
} while (uvalue && (place < (int)sizeof(convert)));
if (place == sizeof(convert))
place--;
convert[place] = 0;
zpadlen = max - place;
spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
if (zpadlen < 0)
zpadlen = 0;
if (spadlen < 0)
spadlen = 0;
if (flags & DP_F_ZERO) {
zpadlen = OSSL_MAX(zpadlen, spadlen);
spadlen = 0;
}
if (flags & DP_F_MINUS)
spadlen = -spadlen;
/* spaces */
while (spadlen > 0) {
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
--spadlen;
}
/* sign */
if (signvalue)
doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
/* prefix */
while (*prefix) {
doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
prefix++;
}
/* zeros */
if (zpadlen > 0) {
while (zpadlen > 0) {
doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
--zpadlen;
}
}
/* digits */
while (place > 0)
doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
/* left justified spaces */
while (spadlen < 0) {
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
++spadlen;
}
return;
}
static LDOUBLE
abs_val(LDOUBLE value)
{
LDOUBLE result = value;
if (value < 0)
result = -value;
return result;
}
static LDOUBLE
pow_10(int in_exp)
{
LDOUBLE result = 1;
while (in_exp) {
result *= 10;
in_exp--;
}
return result;
}
static long
roundv(LDOUBLE value)
{
long intpart;
intpart = (long) value;
value = value - intpart;
if (value >= 0.5)
intpart++;
return intpart;
}
static void
fmtfp(
char **sbuffer,
char **buffer,
size_t *currlen,
size_t *maxlen,
LDOUBLE fvalue,
int min,
int max,
int flags)
{
int signvalue = 0;
LDOUBLE ufvalue;
char iconvert[20];
char fconvert[20];
int iplace = 0;
int fplace = 0;
int padlen = 0;
int zpadlen = 0;
int caps = 0;
long intpart;
long fracpart;
long max10;
if (max < 0)
max = 6;
ufvalue = abs_val(fvalue);
if (fvalue < 0)
signvalue = '-';
else if (flags & DP_F_PLUS)
signvalue = '+';
else if (flags & DP_F_SPACE)
signvalue = ' ';
intpart = (long)ufvalue;
/* sorry, we only support 9 digits past the decimal because of our
conversion method */
if (max > 9)
max = 9;
/* we "cheat" by converting the fractional part to integer by
multiplying by a factor of 10 */
max10 = roundv(pow_10(max));
fracpart = roundv(pow_10(max) * (ufvalue - intpart));
if (fracpart >= max10) {
intpart++;
fracpart -= max10;
}
/* convert integer part */
do {
iconvert[iplace++] =
(caps ? "0123456789ABCDEF"
: "0123456789abcdef")[intpart % 10];
intpart = (intpart / 10);
} while (intpart && (iplace < (int)sizeof(iconvert)));
if (iplace == sizeof iconvert)
iplace--;
iconvert[iplace] = 0;
/* convert fractional part */
do {
fconvert[fplace++] =
(caps ? "0123456789ABCDEF"
: "0123456789abcdef")[fracpart % 10];
fracpart = (fracpart / 10);
} while (fplace < max);
if (fplace == sizeof fconvert)
fplace--;
fconvert[fplace] = 0;
/* -1 for decimal point, another -1 if we are printing a sign */
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
zpadlen = max - fplace;
if (zpadlen < 0)
zpadlen = 0;
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen;
if ((flags & DP_F_ZERO) && (padlen > 0)) {
if (signvalue) {
doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
--padlen;
signvalue = 0;
}
while (padlen > 0) {
doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
--padlen;
}
}
while (padlen > 0) {
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
--padlen;
}
if (signvalue)
doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
while (iplace > 0)
doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
/*
* Decimal point. This should probably use locale to find the correct
* char to print out.
*/
if (max > 0 || (flags & DP_F_NUM)) {
doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
while (fplace > 0)
doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
}
while (zpadlen > 0) {
doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
--zpadlen;
}
while (padlen < 0) {
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
++padlen;
}
}
static void
doapr_outch(
char **sbuffer,
char **buffer,
size_t *currlen,
size_t *maxlen,
int c)
{
/* If we haven't at least one buffer, someone has doe a big booboo */
assert(*sbuffer != NULL || buffer != NULL);
if (buffer) {
while (*currlen >= *maxlen) {
if (*buffer == NULL) {
if (*maxlen == 0)
*maxlen = 1024;
*buffer = OPENSSL_malloc(*maxlen);
if (*currlen > 0) {
assert(*sbuffer != NULL);
memcpy(*buffer, *sbuffer, *currlen);
}
*sbuffer = NULL;
} else {
*maxlen += 1024;
*buffer = OPENSSL_realloc(*buffer, *maxlen);
}
}
/* What to do if *buffer is NULL? */
assert(*sbuffer != NULL || *buffer != NULL);
}
if (*currlen < *maxlen) {
if (*sbuffer)
(*sbuffer)[(*currlen)++] = (char)c;
else
(*buffer)[(*currlen)++] = (char)c;
}
return;
}
/***************************************************************************/
int BIO_printf (BIO *bio, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = BIO_vprintf(bio, format, args);
va_end(args);
return(ret);
}
int BIO_vprintf (BIO *bio, const char *format, va_list args)
{
int ret;
size_t retlen;
char hugebuf[1024*2]; /* Was previously 10k, which is unreasonable
in small-stack environments, like threads
or DOS programs. */
char *hugebufp = hugebuf;
size_t hugebufsize = sizeof(hugebuf);
char *dynbuf = NULL;
int ignored;
dynbuf = NULL;
CRYPTO_push_info("doapr()");
_dopr(&hugebufp, &dynbuf, &hugebufsize,
&retlen, &ignored, format, args);
if (dynbuf)
{
ret=BIO_write(bio, dynbuf, (int)retlen);
OPENSSL_free(dynbuf);
}
else
{
ret=BIO_write(bio, hugebuf, (int)retlen);
}
CRYPTO_pop_info();
return(ret);
}
/* As snprintf is not available everywhere, we provide our own implementation.
* 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?) */
int BIO_snprintf(char *buf, size_t n, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = BIO_vsnprintf(buf, n, format, args);
va_end(args);
return(ret);
}
int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
{
size_t retlen;
int truncated;
_dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
if (truncated)
/* 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.) */
return -1;
else
return (retlen <= INT_MAX) ? (int)retlen : -1;
}

View File

@@ -0,0 +1,976 @@
/* crypto/bio/b_sock.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#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
#include <openssl/dso.h>
#define SOCKET_PROTOCOL IPPROTO_TCP
#ifdef SO_MAXCONN
#define MAX_LISTEN SO_MAXCONN
#elif defined(SOMAXCONN)
#define MAX_LISTEN SOMAXCONN
#else
#define MAX_LISTEN 32
#endif
#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;
#define GHBN_NUM 4
static struct ghbn_cache_st
{
char name[129];
struct hostent *ent;
unsigned long order;
} ghbn_cache[GHBN_NUM];
#endif
static int get_ip(const char *str,unsigned char *ip);
#if 0
static void ghbn_free(struct hostent *a);
static struct hostent *ghbn_dup(struct hostent *a);
#endif
int BIO_get_host_ip(const char *str, unsigned char *ip)
{
int i;
int err = 1;
int locked = 0;
struct hostent *he;
i=get_ip(str,ip);
if (i < 0)
{
BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
goto err;
}
/* At this point, we have something that is most probably correct
in some way, so let's init the socket. */
if (BIO_sock_init() != 1)
return 0; /* don't generate another error code here */
/* If the string actually contained an IP address, we need not do
anything more */
if (i > 0) return(1);
/* do a gethostbyname */
CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
locked = 1;
he=BIO_gethostbyname(str);
if (he == NULL)
{
BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
goto err;
}
/* cast to short because of win16 winsock definition */
if ((short)he->h_addrtype != AF_INET)
{
BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
goto err;
}
for (i=0; i<4; i++)
ip[i]=he->h_addr_list[0][i];
err = 0;
err:
if (locked)
CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
if (err)
{
ERR_add_error_data(2,"host=",str);
return 0;
}
else
return 1;
}
int BIO_get_port(const char *str, unsigned short *port_ptr)
{
int i;
struct servent *s;
if (str == NULL)
{
BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
return(0);
}
i=atoi(str);
if (i != 0)
*port_ptr=(unsigned short)i;
else
{
CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
/* Note: under VMS with SOCKETSHR, it seems like the first
* parameter is 'char *', instead of 'const char *'
*/
#ifndef CONST_STRICT
s=getservbyname((char *)str,"tcp");
#else
s=getservbyname(str,"tcp");
#endif
if(s != NULL)
*port_ptr=ntohs((unsigned short)s->s_port);
CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
if(s == NULL)
{
if (strcmp(str,"http") == 0)
*port_ptr=80;
else if (strcmp(str,"telnet") == 0)
*port_ptr=23;
else if (strcmp(str,"socks") == 0)
*port_ptr=1080;
else if (strcmp(str,"https") == 0)
*port_ptr=443;
else if (strcmp(str,"ssl") == 0)
*port_ptr=443;
else if (strcmp(str,"ftp") == 0)
*port_ptr=21;
else if (strcmp(str,"gopher") == 0)
*port_ptr=70;
#if 0
else if (strcmp(str,"wais") == 0)
*port_ptr=21;
#endif
else
{
SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
ERR_add_error_data(3,"service='",str,"'");
return(0);
}
}
}
return(1);
}
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
* a cast it will choke the compiler: if you do have a cast then
* you can either go for (char *) or (void *).
*/
i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
if (i < 0)
return(1);
else
return(j);
}
#if 0
long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
{
int i;
char **p;
switch (cmd)
{
case BIO_GHBN_CTRL_HITS:
return(BIO_ghbn_hits);
/* break; */
case BIO_GHBN_CTRL_MISSES:
return(BIO_ghbn_miss);
/* break; */
case BIO_GHBN_CTRL_CACHE_SIZE:
return(GHBN_NUM);
/* break; */
case BIO_GHBN_CTRL_GET_ENTRY:
if ((iarg >= 0) && (iarg <GHBN_NUM) &&
(ghbn_cache[iarg].order > 0))
{
p=(char **)parg;
if (p == NULL) return(0);
*p=ghbn_cache[iarg].name;
ghbn_cache[iarg].name[128]='\0';
return(1);
}
return(0);
/* break; */
case BIO_GHBN_CTRL_FLUSH:
for (i=0; i<GHBN_NUM; i++)
ghbn_cache[i].order=0;
break;
default:
return(0);
}
return(1);
}
#endif
#if 0
static struct hostent *ghbn_dup(struct hostent *a)
{
struct hostent *ret;
int i,j;
MemCheck_off();
ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
if (ret == NULL) return(NULL);
memset(ret,0,sizeof(struct hostent));
for (i=0; a->h_aliases[i] != NULL; i++)
;
i++;
ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
if (ret->h_aliases == NULL)
goto err;
memset(ret->h_aliases, 0, i*sizeof(char *));
for (i=0; a->h_addr_list[i] != NULL; i++)
;
i++;
ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
if (ret->h_addr_list == NULL)
goto err;
memset(ret->h_addr_list, 0, i*sizeof(char *));
j=strlen(a->h_name)+1;
if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
memcpy((char *)ret->h_name,a->h_name,j);
for (i=0; a->h_aliases[i] != NULL; i++)
{
j=strlen(a->h_aliases[i])+1;
if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
memcpy(ret->h_aliases[i],a->h_aliases[i],j);
}
ret->h_length=a->h_length;
ret->h_addrtype=a->h_addrtype;
for (i=0; a->h_addr_list[i] != NULL; i++)
{
if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
goto err;
memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
}
if (0)
{
err:
if (ret != NULL)
ghbn_free(ret);
ret=NULL;
}
MemCheck_on();
return(ret);
}
static void ghbn_free(struct hostent *a)
{
int i;
if(a == NULL)
return;
if (a->h_aliases != NULL)
{
for (i=0; a->h_aliases[i] != NULL; i++)
OPENSSL_free(a->h_aliases[i]);
OPENSSL_free(a->h_aliases);
}
if (a->h_addr_list != NULL)
{
for (i=0; a->h_addr_list[i] != NULL; i++)
OPENSSL_free(a->h_addr_list[i]);
OPENSSL_free(a->h_addr_list);
}
if (a->h_name != NULL) OPENSSL_free(a->h_name);
OPENSSL_free(a);
}
#endif
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;
unsigned long low= (unsigned long)-1;
# if 0
/* It doesn't make sense to use locking here: The function interface
* is not thread-safe, because threads can never be sure when
* some other thread destroys the data they were given a pointer to.
*/
CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
# endif
j=strlen(name);
if (j < 128)
{
for (i=0; i<GHBN_NUM; i++)
{
if (low > ghbn_cache[i].order)
{
low=ghbn_cache[i].order;
lowi=i;
}
if (ghbn_cache[i].order > 0)
{
if (strncmp(name,ghbn_cache[i].name,128) == 0)
break;
}
}
}
else
i=GHBN_NUM;
if (i == GHBN_NUM) /* no hit*/
{
BIO_ghbn_miss++;
/* Note: under VMS with SOCKETSHR, it seems like the first
* parameter is 'char *', instead of 'const char *'
*/
# ifndef CONST_STRICT
ret=gethostbyname((char *)name);
# else
ret=gethostbyname(name);
# endif
if (ret == NULL)
goto end;
if (j > 128) /* too big to cache */
{
# if 0
/* If we were trying to make this function thread-safe (which
* is bound to fail), we'd have to give up in this case
* (or allocate more memory). */
ret = NULL;
# endif
goto end;
}
/* else add to cache */
if (ghbn_cache[lowi].ent != NULL)
ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
ghbn_cache[lowi].name[0] = '\0';
if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
{
BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
goto end;
}
strncpy(ghbn_cache[lowi].name,name,128);
ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
}
else
{
BIO_ghbn_hits++;
ret= ghbn_cache[i].ent;
ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
}
end:
# if 0
CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
# endif
return(ret);
#endif
}
int BIO_sock_init(void)
{
#ifdef OPENSSL_SYS_WINDOWS
static struct WSAData wsa_state;
if (!wsa_init_done)
{
int err;
wsa_init_done=1;
memset(&wsa_state,0,sizeof(wsa_state));
/* 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);
BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
return(-1);
}
}
#endif /* OPENSSL_SYS_WINDOWS */
#ifdef WATT32
extern int _watt_do_exit;
_watt_do_exit = 0; /* don't make sock_init() call exit() */
if (sock_init())
return (-1);
#endif
#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
WORD wVerReq;
WSADATA wsaData;
int err;
if (!wsa_init_done)
{
wsa_init_done=1;
wVerReq = MAKEWORD( 2, 0 );
err = WSAStartup(wVerReq,&wsaData);
if (err != 0)
{
SYSerr(SYS_F_WSASTARTUP,err);
BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
return(-1);
}
}
#endif
return(1);
}
void BIO_sock_cleanup(void)
{
#ifdef OPENSSL_SYS_WINDOWS
if (wsa_init_done)
{
wsa_init_done=0;
#if 0 /* this call is claimed to be non-present in Winsock2 */
WSACancelBlockingCall();
#endif
WSACleanup();
}
#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
if (wsa_init_done)
{
wsa_init_done=0;
WSACleanup();
}
#endif
}
#if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
int BIO_socket_ioctl(int fd, long type, void *arg)
{
int i;
#ifdef __DJGPP__
i=ioctlsocket(fd,type,(char *)arg);
#else
# if defined(OPENSSL_SYS_VMS)
/* 2011-02-18 SMS.
* VMS ioctl() can't tolerate a 64-bit "void *arg", but we
* observe that all the consumers pass in an "unsigned long *",
* so we arrange a local copy with a short pointer, and use
* that, instead.
*/
# if __INITIAL_POINTER_SIZE == 64
# define ARG arg_32p
# pragma pointer_size save
# pragma pointer_size 32
unsigned long arg_32;
unsigned long *arg_32p;
# pragma pointer_size restore
arg_32p = &arg_32;
arg_32 = *((unsigned long *) arg);
# else /* __INITIAL_POINTER_SIZE == 64 */
# define ARG arg
# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
# else /* defined(OPENSSL_SYS_VMS) */
# define ARG arg
# endif /* defined(OPENSSL_SYS_VMS) [else] */
i=ioctlsocket(fd,type,ARG);
#endif /* __DJGPP__ */
if (i < 0)
SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
return(i);
}
#endif /* __VMS_VER */
/* The reason I have implemented this instead of using sscanf is because
* Visual C 1.52c gives an unresolved external when linking a DLL :-( */
static int get_ip(const char *str, unsigned char ip[4])
{
unsigned int tmp[4];
int num=0,c,ok=0;
tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
for (;;)
{
c= *(str++);
if ((c >= '0') && (c <= '9'))
{
ok=1;
tmp[num]=tmp[num]*10+c-'0';
if (tmp[num] > 255) return(0);
}
else if (c == '.')
{
if (!ok) return(-1);
if (num == 3) return(0);
num++;
ok=0;
}
else if (c == '\0' && (num == 3) && ok)
break;
else
return(0);
}
ip[0]=tmp[0];
ip[1]=tmp[1];
ip[2]=tmp[2];
ip[3]=tmp[3];
return(1);
}
int BIO_get_accept_socket(char *host, int bind_mode)
{
int ret=0;
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;
socklen_t addrlen;
unsigned char ip[4];
unsigned short port;
char *str=NULL,*e;
char *h,*p;
unsigned long l;
int err_num;
if (BIO_sock_init() != 1) return(INVALID_SOCKET);
if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);
h=p=NULL;
h=str;
for (e=str; *e; e++)
{
if (*e == ':')
{
p=e;
}
else if (*e == '/')
{
*e='\0';
break;
}
}
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));
hint.ai_flags = AI_PASSIVE;
if (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')
{
hint.ai_family = AF_INET;
h=NULL;
}
}
if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break;
addrlen = res->ai_addrlen <= (socklen_t)sizeof(server) ?
res->ai_addrlen :
(socklen_t)sizeof(server);
memcpy(&server, res->ai_addr, (size_t)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.sa_in.sin_family=AF_INET;
server.sa_in.sin_port=htons(port);
addrlen = (socklen_t)sizeof(server.sa_in);
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;
l=(unsigned long)
((unsigned long)ip[0]<<24L)|
((unsigned long)ip[1]<<16L)|
((unsigned long)ip[2]<< 8L)|
((unsigned long)ip[3]);
server.sa_in.sin_addr.s_addr=htonl(l);
}
again:
s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
if (s == INVALID_SOCKET)
{
SYSerr(SYS_F_SOCKET,get_last_socket_error());
ERR_add_error_data(3,"port='",host,"'");
BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
goto err;
}
#ifdef SO_REUSEADDR
if (bind_mode == BIO_BIND_REUSEADDR)
{
int i=1;
ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
bind_mode=BIO_BIND_NORMAL;
}
#endif
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
{
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,&client.sa,addrlen);
closesocket(cs);
if (ii == INVALID_SOCKET)
{
bind_mode=BIO_BIND_REUSEADDR;
closesocket(s);
goto again;
}
/* else error */
}
/* else error */
}
#endif
SYSerr(SYS_F_BIND,err_num);
ERR_add_error_data(3,"port='",host,"'");
BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
goto err;
}
if (listen(s,MAX_LISTEN) == -1)
{
SYSerr(SYS_F_BIND,get_last_socket_error());
ERR_add_error_data(3,"port='",host,"'");
BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
goto err;
}
ret=1;
err:
if (str != NULL) OPENSSL_free(str);
if ((ret == 0) && (s != INVALID_SOCKET))
{
closesocket(s);
s= INVALID_SOCKET;
}
return(s);
}
int BIO_accept(int sock, char **addr)
{
int ret=INVALID_SOCKET;
unsigned long l;
unsigned short port;
char *p;
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>
*/
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;
SYSerr(SYS_F_ACCEPT,get_last_socket_error());
BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
goto end;
}
if (addr == NULL) goto end;
#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)
{
BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
goto end;
}
*addr=p;
}
BIO_snprintf(*addr,24,"%d.%d.%d.%d:%d",
(unsigned char)(l>>24L)&0xff,
(unsigned char)(l>>16L)&0xff,
(unsigned char)(l>> 8L)&0xff,
(unsigned char)(l )&0xff,
port);
end:
return(ret);
}
int BIO_set_tcp_ndelay(int s, int on)
{
int ret=0;
#if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
int opt;
#ifdef SOL_TCP
opt=SOL_TCP;
#else
#ifdef IPPROTO_TCP
opt=IPPROTO_TCP;
#endif
#endif
ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
#endif
return(ret == 0);
}
int BIO_socket_nbio(int s, int mode)
{
int ret= -1;
int l;
l=mode;
#ifdef FIONBIO
ret=BIO_socket_ioctl(s,FIONBIO,&l);
#endif
return(ret == 0);
}
#endif

View File

@@ -0,0 +1,512 @@
/* crypto/bio/bf_buff.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#include "cryptlib.h"
#include <openssl/bio.h>
static int buffer_write(BIO *h, const char *buf,int num);
static int buffer_read(BIO *h, char *buf, int size);
static int buffer_puts(BIO *h, const char *str);
static int buffer_gets(BIO *h, char *str, int size);
static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int buffer_new(BIO *h);
static int buffer_free(BIO *data);
static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
#define DEFAULT_BUFFER_SIZE 4096
static BIO_METHOD methods_buffer=
{
BIO_TYPE_BUFFER,
"buffer",
buffer_write,
buffer_read,
buffer_puts,
buffer_gets,
buffer_ctrl,
buffer_new,
buffer_free,
buffer_callback_ctrl,
};
BIO_METHOD *BIO_f_buffer(void)
{
return(&methods_buffer);
}
static int buffer_new(BIO *bi)
{
BIO_F_BUFFER_CTX *ctx;
ctx=(BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
if (ctx == NULL) return(0);
ctx->ibuf=(char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->ibuf == NULL) { OPENSSL_free(ctx); return(0); }
ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->obuf == NULL) { OPENSSL_free(ctx->ibuf); OPENSSL_free(ctx); return(0); }
ctx->ibuf_size=DEFAULT_BUFFER_SIZE;
ctx->obuf_size=DEFAULT_BUFFER_SIZE;
ctx->ibuf_len=0;
ctx->ibuf_off=0;
ctx->obuf_len=0;
ctx->obuf_off=0;
bi->init=1;
bi->ptr=(char *)ctx;
bi->flags=0;
return(1);
}
static int buffer_free(BIO *a)
{
BIO_F_BUFFER_CTX *b;
if (a == NULL) return(0);
b=(BIO_F_BUFFER_CTX *)a->ptr;
if (b->ibuf != NULL) OPENSSL_free(b->ibuf);
if (b->obuf != NULL) OPENSSL_free(b->obuf);
OPENSSL_free(a->ptr);
a->ptr=NULL;
a->init=0;
a->flags=0;
return(1);
}
static int buffer_read(BIO *b, char *out, int outl)
{
int i,num=0;
BIO_F_BUFFER_CTX *ctx;
if (out == NULL) return(0);
ctx=(BIO_F_BUFFER_CTX *)b->ptr;
if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
num=0;
BIO_clear_retry_flags(b);
start:
i=ctx->ibuf_len;
/* If there is stuff left over, grab it */
if (i != 0)
{
if (i > outl) i=outl;
memcpy(out,&(ctx->ibuf[ctx->ibuf_off]),i);
ctx->ibuf_off+=i;
ctx->ibuf_len-=i;
num+=i;
if (outl == i) return(num);
outl-=i;
out+=i;
}
/* We may have done a partial read. try to do more.
* We have nothing in the buffer.
* If we get an error and have read some data, just return it
* and let them retry to get the error again.
* copy direct to parent address space */
if (outl > ctx->ibuf_size)
{
for (;;)
{
i=BIO_read(b->next_bio,out,outl);
if (i <= 0)
{
BIO_copy_next_retry(b);
if (i < 0) return((num > 0)?num:i);
if (i == 0) return(num);
}
num+=i;
if (outl == i) return(num);
out+=i;
outl-=i;
}
}
/* else */
/* we are going to be doing some buffering */
i=BIO_read(b->next_bio,ctx->ibuf,ctx->ibuf_size);
if (i <= 0)
{
BIO_copy_next_retry(b);
if (i < 0) return((num > 0)?num:i);
if (i == 0) return(num);
}
ctx->ibuf_off=0;
ctx->ibuf_len=i;
/* Lets re-read using ourselves :-) */
goto start;
}
static int buffer_write(BIO *b, const char *in, int inl)
{
int i,num=0;
BIO_F_BUFFER_CTX *ctx;
if ((in == NULL) || (inl <= 0)) return(0);
ctx=(BIO_F_BUFFER_CTX *)b->ptr;
if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
BIO_clear_retry_flags(b);
start:
i=ctx->obuf_size-(ctx->obuf_len+ctx->obuf_off);
/* add to buffer and return */
if (i >= inl)
{
memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,inl);
ctx->obuf_len+=inl;
return(num+inl);
}
/* else */
/* stuff already in buffer, so add to it first, then flush */
if (ctx->obuf_len != 0)
{
if (i > 0) /* lets fill it up if we can */
{
memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,i);
in+=i;
inl-=i;
num+=i;
ctx->obuf_len+=i;
}
/* we now have a full buffer needing flushing */
for (;;)
{
i=BIO_write(b->next_bio,&(ctx->obuf[ctx->obuf_off]),
ctx->obuf_len);
if (i <= 0)
{
BIO_copy_next_retry(b);
if (i < 0) return((num > 0)?num:i);
if (i == 0) return(num);
}
ctx->obuf_off+=i;
ctx->obuf_len-=i;
if (ctx->obuf_len == 0) break;
}
}
/* we only get here if the buffer has been flushed and we
* still have stuff to write */
ctx->obuf_off=0;
/* we now have inl bytes to write */
while (inl >= ctx->obuf_size)
{
i=BIO_write(b->next_bio,in,inl);
if (i <= 0)
{
BIO_copy_next_retry(b);
if (i < 0) return((num > 0)?num:i);
if (i == 0) return(num);
}
num+=i;
in+=i;
inl-=i;
if (inl == 0) return(num);
}
/* copy the rest into the buffer since we have only a small
* amount left */
goto start;
}
static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BIO *dbio;
BIO_F_BUFFER_CTX *ctx;
long ret=1;
char *p1,*p2;
int r,i,*ip;
int ibs,obs;
ctx=(BIO_F_BUFFER_CTX *)b->ptr;
switch (cmd)
{
case BIO_CTRL_RESET:
ctx->ibuf_off=0;
ctx->ibuf_len=0;
ctx->obuf_off=0;
ctx->obuf_len=0;
if (b->next_bio == NULL) return(0);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
case BIO_CTRL_INFO:
ret=(long)ctx->obuf_len;
break;
case BIO_C_GET_BUFF_NUM_LINES:
ret=0;
p1=ctx->ibuf;
for (i=0; i<ctx->ibuf_len; i++)
{
if (p1[ctx->ibuf_off + i] == '\n') ret++;
}
break;
case BIO_CTRL_WPENDING:
ret=(long)ctx->obuf_len;
if (ret == 0)
{
if (b->next_bio == NULL) return(0);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
}
break;
case BIO_CTRL_PENDING:
ret=(long)ctx->ibuf_len;
if (ret == 0)
{
if (b->next_bio == NULL) return(0);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
}
break;
case BIO_C_SET_BUFF_READ_DATA:
if (num > ctx->ibuf_size)
{
p1=OPENSSL_malloc((int)num);
if (p1 == NULL) goto malloc_error;
if (ctx->ibuf != NULL) OPENSSL_free(ctx->ibuf);
ctx->ibuf=p1;
}
ctx->ibuf_off=0;
ctx->ibuf_len=(int)num;
memcpy(ctx->ibuf,ptr,(int)num);
ret=1;
break;
case BIO_C_SET_BUFF_SIZE:
if (ptr != NULL)
{
ip=(int *)ptr;
if (*ip == 0)
{
ibs=(int)num;
obs=ctx->obuf_size;
}
else /* if (*ip == 1) */
{
ibs=ctx->ibuf_size;
obs=(int)num;
}
}
else
{
ibs=(int)num;
obs=(int)num;
}
p1=ctx->ibuf;
p2=ctx->obuf;
if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size))
{
p1=(char *)OPENSSL_malloc((int)num);
if (p1 == NULL) goto malloc_error;
}
if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size))
{
p2=(char *)OPENSSL_malloc((int)num);
if (p2 == NULL)
{
if (p1 != ctx->ibuf) OPENSSL_free(p1);
goto malloc_error;
}
}
if (ctx->ibuf != p1)
{
OPENSSL_free(ctx->ibuf);
ctx->ibuf=p1;
ctx->ibuf_off=0;
ctx->ibuf_len=0;
ctx->ibuf_size=ibs;
}
if (ctx->obuf != p2)
{
OPENSSL_free(ctx->obuf);
ctx->obuf=p2;
ctx->obuf_off=0;
ctx->obuf_len=0;
ctx->obuf_size=obs;
}
break;
case BIO_C_DO_STATE_MACHINE:
if (b->next_bio == NULL) return(0);
BIO_clear_retry_flags(b);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_FLUSH:
if (b->next_bio == NULL) return(0);
if (ctx->obuf_len <= 0)
{
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
}
for (;;)
{
BIO_clear_retry_flags(b);
if (ctx->obuf_len > 0)
{
r=BIO_write(b->next_bio,
&(ctx->obuf[ctx->obuf_off]),
ctx->obuf_len);
#if 0
fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len,r);
#endif
BIO_copy_next_retry(b);
if (r <= 0) return((long)r);
ctx->obuf_off+=r;
ctx->obuf_len-=r;
}
else
{
ctx->obuf_len=0;
ctx->obuf_off=0;
ret=1;
break;
}
}
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
case BIO_CTRL_DUP:
dbio=(BIO *)ptr;
if ( !BIO_set_read_buffer_size(dbio,ctx->ibuf_size) ||
!BIO_set_write_buffer_size(dbio,ctx->obuf_size))
ret=0;
break;
default:
if (b->next_bio == NULL) return(0);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
}
return(ret);
malloc_error:
BIOerr(BIO_F_BUFFER_CTRL,ERR_R_MALLOC_FAILURE);
return(0);
}
static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret=1;
if (b->next_bio == NULL) return(0);
switch (cmd)
{
default:
ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
break;
}
return(ret);
}
static int buffer_gets(BIO *b, char *buf, int size)
{
BIO_F_BUFFER_CTX *ctx;
int num=0,i,flag;
char *p;
ctx=(BIO_F_BUFFER_CTX *)b->ptr;
size--; /* reserve space for a '\0' */
BIO_clear_retry_flags(b);
for (;;)
{
if (ctx->ibuf_len > 0)
{
p= &(ctx->ibuf[ctx->ibuf_off]);
flag=0;
for (i=0; (i<ctx->ibuf_len) && (i<size); i++)
{
*(buf++)=p[i];
if (p[i] == '\n')
{
flag=1;
i++;
break;
}
}
num+=i;
size-=i;
ctx->ibuf_len-=i;
ctx->ibuf_off+=i;
if (flag || size == 0)
{
*buf='\0';
return(num);
}
}
else /* read another chunk */
{
i=BIO_read(b->next_bio,ctx->ibuf,ctx->ibuf_size);
if (i <= 0)
{
BIO_copy_next_retry(b);
*buf='\0';
if (i < 0) return((num > 0)?num:i);
if (i == 0) return(num);
}
ctx->ibuf_len=i;
ctx->ibuf_off=0;
}
}
}
static int buffer_puts(BIO *b, const char *str)
{
return(buffer_write(b,str,strlen(str)));
}

View File

@@ -0,0 +1,397 @@
/* crypto/bio/bf_buff.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#include "cryptlib.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
static int linebuffer_write(BIO *h, const char *buf,int num);
static int linebuffer_read(BIO *h, char *buf, int size);
static int linebuffer_puts(BIO *h, const char *str);
static int linebuffer_gets(BIO *h, char *str, int size);
static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int linebuffer_new(BIO *h);
static int linebuffer_free(BIO *data);
static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
/* A 10k maximum should be enough for most purposes */
#define DEFAULT_LINEBUFFER_SIZE 1024*10
/* #define DEBUG */
static BIO_METHOD methods_linebuffer=
{
BIO_TYPE_LINEBUFFER,
"linebuffer",
linebuffer_write,
linebuffer_read,
linebuffer_puts,
linebuffer_gets,
linebuffer_ctrl,
linebuffer_new,
linebuffer_free,
linebuffer_callback_ctrl,
};
BIO_METHOD *BIO_f_linebuffer(void)
{
return(&methods_linebuffer);
}
typedef struct bio_linebuffer_ctx_struct
{
char *obuf; /* the output char array */
int obuf_size; /* how big is the output buffer */
int obuf_len; /* how many bytes are in it */
} BIO_LINEBUFFER_CTX;
static int linebuffer_new(BIO *bi)
{
BIO_LINEBUFFER_CTX *ctx;
ctx=(BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX));
if (ctx == NULL) return(0);
ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
if (ctx->obuf == NULL) { OPENSSL_free(ctx); return(0); }
ctx->obuf_size=DEFAULT_LINEBUFFER_SIZE;
ctx->obuf_len=0;
bi->init=1;
bi->ptr=(char *)ctx;
bi->flags=0;
return(1);
}
static int linebuffer_free(BIO *a)
{
BIO_LINEBUFFER_CTX *b;
if (a == NULL) return(0);
b=(BIO_LINEBUFFER_CTX *)a->ptr;
if (b->obuf != NULL) OPENSSL_free(b->obuf);
OPENSSL_free(a->ptr);
a->ptr=NULL;
a->init=0;
a->flags=0;
return(1);
}
static int linebuffer_read(BIO *b, char *out, int outl)
{
int ret=0;
if (out == NULL) return(0);
if (b->next_bio == NULL) return(0);
ret=BIO_read(b->next_bio,out,outl);
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return(ret);
}
static int linebuffer_write(BIO *b, const char *in, int inl)
{
int i,num=0,foundnl;
BIO_LINEBUFFER_CTX *ctx;
if ((in == NULL) || (inl <= 0)) return(0);
ctx=(BIO_LINEBUFFER_CTX *)b->ptr;
if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
BIO_clear_retry_flags(b);
do
{
const char *p;
for(p = in; p < in + inl && *p != '\n'; p++)
;
if (*p == '\n')
{
p++;
foundnl = 1;
}
else
foundnl = 0;
/* If a NL was found and we already have text in the save
buffer, concatenate them and write */
while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
&& ctx->obuf_len > 0)
{
int orig_olen = ctx->obuf_len;
i = ctx->obuf_size - ctx->obuf_len;
if (p - in > 0)
{
if (i >= p - in)
{
memcpy(&(ctx->obuf[ctx->obuf_len]),
in,p - in);
ctx->obuf_len += p - in;
inl -= p - in;
num += p - in;
in = p;
}
else
{
memcpy(&(ctx->obuf[ctx->obuf_len]),
in,i);
ctx->obuf_len += i;
inl -= i;
in += i;
num += i;
}
}
#if 0
BIO_write(b->next_bio, "<*<", 3);
#endif
i=BIO_write(b->next_bio,
ctx->obuf, ctx->obuf_len);
if (i <= 0)
{
ctx->obuf_len = orig_olen;
BIO_copy_next_retry(b);
#if 0
BIO_write(b->next_bio, ">*>", 3);
#endif
if (i < 0) return((num > 0)?num:i);
if (i == 0) return(num);
}
#if 0
BIO_write(b->next_bio, ">*>", 3);
#endif
if (i < ctx->obuf_len)
memmove(ctx->obuf, ctx->obuf + i,
ctx->obuf_len - i);
ctx->obuf_len-=i;
}
/* Now that the save buffer is emptied, let's write the input
buffer if a NL was found and there is anything to write. */
if ((foundnl || p - in > ctx->obuf_size) && p - in > 0)
{
#if 0
BIO_write(b->next_bio, "<*<", 3);
#endif
i=BIO_write(b->next_bio,in,p - in);
if (i <= 0)
{
BIO_copy_next_retry(b);
#if 0
BIO_write(b->next_bio, ">*>", 3);
#endif
if (i < 0) return((num > 0)?num:i);
if (i == 0) return(num);
}
#if 0
BIO_write(b->next_bio, ">*>", 3);
#endif
num+=i;
in+=i;
inl-=i;
}
}
while(foundnl && inl > 0);
/* We've written as much as we can. The rest of the input buffer, if
any, is text that doesn't and with a NL and therefore needs to be
saved for the next trip. */
if (inl > 0)
{
memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
ctx->obuf_len += inl;
num += inl;
}
return num;
}
static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BIO *dbio;
BIO_LINEBUFFER_CTX *ctx;
long ret=1;
char *p;
int r;
int obs;
ctx=(BIO_LINEBUFFER_CTX *)b->ptr;
switch (cmd)
{
case BIO_CTRL_RESET:
ctx->obuf_len=0;
if (b->next_bio == NULL) return(0);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
case BIO_CTRL_INFO:
ret=(long)ctx->obuf_len;
break;
case BIO_CTRL_WPENDING:
ret=(long)ctx->obuf_len;
if (ret == 0)
{
if (b->next_bio == NULL) return(0);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
}
break;
case BIO_C_SET_BUFF_SIZE:
obs=(int)num;
p=ctx->obuf;
if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size))
{
p=(char *)OPENSSL_malloc((int)num);
if (p == NULL)
goto malloc_error;
}
if (ctx->obuf != p)
{
if (ctx->obuf_len > obs)
{
ctx->obuf_len = obs;
}
memcpy(p, ctx->obuf, ctx->obuf_len);
OPENSSL_free(ctx->obuf);
ctx->obuf=p;
ctx->obuf_size=obs;
}
break;
case BIO_C_DO_STATE_MACHINE:
if (b->next_bio == NULL) return(0);
BIO_clear_retry_flags(b);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_FLUSH:
if (b->next_bio == NULL) return(0);
if (ctx->obuf_len <= 0)
{
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
}
for (;;)
{
BIO_clear_retry_flags(b);
if (ctx->obuf_len > 0)
{
r=BIO_write(b->next_bio,
ctx->obuf, ctx->obuf_len);
#if 0
fprintf(stderr,"FLUSH %3d -> %3d\n",ctx->obuf_len,r);
#endif
BIO_copy_next_retry(b);
if (r <= 0) return((long)r);
if (r < ctx->obuf_len)
memmove(ctx->obuf, ctx->obuf + r,
ctx->obuf_len - r);
ctx->obuf_len-=r;
}
else
{
ctx->obuf_len=0;
ret=1;
break;
}
}
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
case BIO_CTRL_DUP:
dbio=(BIO *)ptr;
if ( !BIO_set_write_buffer_size(dbio,ctx->obuf_size))
ret=0;
break;
default:
if (b->next_bio == NULL) return(0);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
}
return(ret);
malloc_error:
BIOerr(BIO_F_LINEBUFFER_CTRL,ERR_R_MALLOC_FAILURE);
return(0);
}
static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret=1;
if (b->next_bio == NULL) return(0);
switch (cmd)
{
default:
ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
break;
}
return(ret);
}
static int linebuffer_gets(BIO *b, char *buf, int size)
{
if (b->next_bio == NULL) return(0);
return(BIO_gets(b->next_bio,buf,size));
}
static int linebuffer_puts(BIO *b, const char *str)
{
return(linebuffer_write(b,str,strlen(str)));
}

View File

@@ -0,0 +1,253 @@
/* crypto/bio/bf_nbio.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#include "cryptlib.h"
#include <openssl/rand.h>
#include <openssl/bio.h>
/* BIO_put and BIO_get both add to the digest,
* BIO_gets returns the digest */
static int nbiof_write(BIO *h,const char *buf,int num);
static int nbiof_read(BIO *h,char *buf,int size);
static int nbiof_puts(BIO *h,const char *str);
static int nbiof_gets(BIO *h,char *str,int size);
static long nbiof_ctrl(BIO *h,int cmd,long arg1,void *arg2);
static int nbiof_new(BIO *h);
static int nbiof_free(BIO *data);
static long nbiof_callback_ctrl(BIO *h,int cmd,bio_info_cb *fp);
typedef struct nbio_test_st
{
/* only set if we sent a 'should retry' error */
int lrn;
int lwn;
} NBIO_TEST;
static BIO_METHOD methods_nbiof=
{
BIO_TYPE_NBIO_TEST,
"non-blocking IO test filter",
nbiof_write,
nbiof_read,
nbiof_puts,
nbiof_gets,
nbiof_ctrl,
nbiof_new,
nbiof_free,
nbiof_callback_ctrl,
};
BIO_METHOD *BIO_f_nbio_test(void)
{
return(&methods_nbiof);
}
static int nbiof_new(BIO *bi)
{
NBIO_TEST *nt;
if (!(nt=(NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST)))) return(0);
nt->lrn= -1;
nt->lwn= -1;
bi->ptr=(char *)nt;
bi->init=1;
bi->flags=0;
return(1);
}
static int nbiof_free(BIO *a)
{
if (a == NULL) return(0);
if (a->ptr != NULL)
OPENSSL_free(a->ptr);
a->ptr=NULL;
a->init=0;
a->flags=0;
return(1);
}
static int nbiof_read(BIO *b, char *out, int outl)
{
int ret=0;
#if 1
int num;
unsigned char n;
#endif
if (out == NULL) return(0);
if (b->next_bio == NULL) return(0);
BIO_clear_retry_flags(b);
#if 1
RAND_pseudo_bytes(&n,1);
num=(n&0x07);
if (outl > num) outl=num;
if (num == 0)
{
ret= -1;
BIO_set_retry_read(b);
}
else
#endif
{
ret=BIO_read(b->next_bio,out,outl);
if (ret < 0)
BIO_copy_next_retry(b);
}
return(ret);
}
static int nbiof_write(BIO *b, const char *in, int inl)
{
NBIO_TEST *nt;
int ret=0;
int num;
unsigned char n;
if ((in == NULL) || (inl <= 0)) return(0);
if (b->next_bio == NULL) return(0);
nt=(NBIO_TEST *)b->ptr;
BIO_clear_retry_flags(b);
#if 1
if (nt->lwn > 0)
{
num=nt->lwn;
nt->lwn=0;
}
else
{
RAND_pseudo_bytes(&n,1);
num=(n&7);
}
if (inl > num) inl=num;
if (num == 0)
{
ret= -1;
BIO_set_retry_write(b);
}
else
#endif
{
ret=BIO_write(b->next_bio,in,inl);
if (ret < 0)
{
BIO_copy_next_retry(b);
nt->lwn=inl;
}
}
return(ret);
}
static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret;
if (b->next_bio == NULL) return(0);
switch (cmd)
{
case BIO_C_DO_STATE_MACHINE:
BIO_clear_retry_flags(b);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_DUP:
ret=0L;
break;
default:
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
}
return(ret);
}
static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret=1;
if (b->next_bio == NULL) return(0);
switch (cmd)
{
default:
ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
break;
}
return(ret);
}
static int nbiof_gets(BIO *bp, char *buf, int size)
{
if (bp->next_bio == NULL) return(0);
return(BIO_gets(bp->next_bio,buf,size));
}
static int nbiof_puts(BIO *bp, const char *str)
{
if (bp->next_bio == NULL) return(0);
return(BIO_puts(bp->next_bio,str));
}

View File

@@ -0,0 +1,183 @@
/* crypto/bio/bf_null.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#include "cryptlib.h"
#include <openssl/bio.h>
/* BIO_put and BIO_get both add to the digest,
* BIO_gets returns the digest */
static int nullf_write(BIO *h, const char *buf, int num);
static int nullf_read(BIO *h, char *buf, int size);
static int nullf_puts(BIO *h, const char *str);
static int nullf_gets(BIO *h, char *str, int size);
static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int nullf_new(BIO *h);
static int nullf_free(BIO *data);
static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static BIO_METHOD methods_nullf=
{
BIO_TYPE_NULL_FILTER,
"NULL filter",
nullf_write,
nullf_read,
nullf_puts,
nullf_gets,
nullf_ctrl,
nullf_new,
nullf_free,
nullf_callback_ctrl,
};
BIO_METHOD *BIO_f_null(void)
{
return(&methods_nullf);
}
static int nullf_new(BIO *bi)
{
bi->init=1;
bi->ptr=NULL;
bi->flags=0;
return(1);
}
static int nullf_free(BIO *a)
{
if (a == NULL) return(0);
/* a->ptr=NULL;
a->init=0;
a->flags=0;*/
return(1);
}
static int nullf_read(BIO *b, char *out, int outl)
{
int ret=0;
if (out == NULL) return(0);
if (b->next_bio == NULL) return(0);
ret=BIO_read(b->next_bio,out,outl);
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return(ret);
}
static int nullf_write(BIO *b, const char *in, int inl)
{
int ret=0;
if ((in == NULL) || (inl <= 0)) return(0);
if (b->next_bio == NULL) return(0);
ret=BIO_write(b->next_bio,in,inl);
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return(ret);
}
static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret;
if (b->next_bio == NULL) return(0);
switch(cmd)
{
case BIO_C_DO_STATE_MACHINE:
BIO_clear_retry_flags(b);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_DUP:
ret=0L;
break;
default:
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
}
return(ret);
}
static long nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret=1;
if (b->next_bio == NULL) return(0);
switch (cmd)
{
default:
ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
break;
}
return(ret);
}
static int nullf_gets(BIO *bp, char *buf, int size)
{
if (bp->next_bio == NULL) return(0);
return(BIO_gets(bp->next_bio,buf,size));
}
static int nullf_puts(BIO *bp, const char *str)
{
if (bp->next_bio == NULL) return(0);
return(BIO_puts(bp->next_bio,str));
}

View File

@@ -0,0 +1,850 @@
/* crypto/bio/bio.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifndef HEADER_BIO_H
#define HEADER_BIO_H
#include <openssl/e_os2.h>
#ifndef OPENSSL_NO_FP_API
# include <stdio.h>
#endif
#include <stdarg.h>
#include <openssl/crypto.h>
#ifndef OPENSSL_NO_SCTP
# ifndef OPENSSL_SYS_VMS
# include <stdint.h>
# else
# include <inttypes.h>
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* These are the 'types' of BIOs */
#define BIO_TYPE_NONE 0
#define BIO_TYPE_MEM (1|0x0400)
#define BIO_TYPE_FILE (2|0x0400)
#define BIO_TYPE_FD (4|0x0400|0x0100)
#define BIO_TYPE_SOCKET (5|0x0400|0x0100)
#define BIO_TYPE_NULL (6|0x0400)
#define BIO_TYPE_SSL (7|0x0200)
#define BIO_TYPE_MD (8|0x0200) /* passive filter */
#define BIO_TYPE_BUFFER (9|0x0200) /* filter */
#define BIO_TYPE_CIPHER (10|0x0200) /* filter */
#define BIO_TYPE_BASE64 (11|0x0200) /* filter */
#define BIO_TYPE_CONNECT (12|0x0400|0x0100) /* socket - connect */
#define BIO_TYPE_ACCEPT (13|0x0400|0x0100) /* socket for accept */
#define BIO_TYPE_PROXY_CLIENT (14|0x0200) /* client proxy BIO */
#define BIO_TYPE_PROXY_SERVER (15|0x0200) /* server proxy BIO */
#define BIO_TYPE_NBIO_TEST (16|0x0200) /* server proxy BIO */
#define BIO_TYPE_NULL_FILTER (17|0x0200)
#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)
#ifndef OPENSSL_NO_SCTP
#define BIO_TYPE_DGRAM_SCTP (24|0x0400|0x0100)
#endif
#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
#define BIO_TYPE_SOURCE_SINK 0x0400
/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
* BIO_set_fp(in,stdin,BIO_NOCLOSE); */
#define BIO_NOCLOSE 0x00
#define BIO_CLOSE 0x01
/* These are used in the following macros and are passed to
* BIO_ctrl() */
#define BIO_CTRL_RESET 1 /* opt - rewind/zero etc */
#define BIO_CTRL_EOF 2 /* opt - are we at the eof */
#define BIO_CTRL_INFO 3 /* opt - extra tit-bits */
#define BIO_CTRL_SET 4 /* man - set the 'IO' type */
#define BIO_CTRL_GET 5 /* man - get the 'IO' type */
#define BIO_CTRL_PUSH 6 /* opt - internal, used to signify change */
#define BIO_CTRL_POP 7 /* opt - internal, used to signify change */
#define BIO_CTRL_GET_CLOSE 8 /* man - set the 'close' on free */
#define BIO_CTRL_SET_CLOSE 9 /* man - set the 'close' on free */
#define BIO_CTRL_PENDING 10 /* opt - is their more data buffered */
#define BIO_CTRL_FLUSH 11 /* opt - 'flush' buffered output */
#define BIO_CTRL_DUP 12 /* man - extra stuff for 'duped' BIO */
#define BIO_CTRL_WPENDING 13 /* opt - number of bytes still to write */
/* callback is int cb(BIO *bio,state,ret); */
#define BIO_CTRL_SET_CALLBACK 14 /* opt - set callback function */
#define BIO_CTRL_GET_CALLBACK 15 /* opt - set callback function */
#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_FALLBACK_MTU 47
#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 */
#ifndef OPENSSL_NO_SCTP
/* SCTP stuff */
#define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50
#define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51
#define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52
#define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53
#define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60
#define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61
#define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62
#define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63
#define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64
#define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65
#define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70
#endif
/* modifiers */
#define BIO_FP_READ 0x02
#define BIO_FP_WRITE 0x04
#define BIO_FP_APPEND 0x08
#define BIO_FP_TEXT 0x10
#define BIO_FLAGS_READ 0x01
#define BIO_FLAGS_WRITE 0x02
#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
#define BIO_GHBN_CTRL_MISSES 2
#define BIO_GHBN_CTRL_CACHE_SIZE 3
#define BIO_GHBN_CTRL_GET_ENTRY 4
#define BIO_GHBN_CTRL_FLUSH 5
/* Mostly used in the SSL BIO */
/* Not used anymore
* #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
* #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
* #define BIO_FLAGS_PROTOCOL_STARTUP 0x40
*/
#define BIO_FLAGS_BASE64_NO_NL 0x100
/* This is used with memory BIOs: it means we shouldn't free up or change the
* data in any way.
*/
#define BIO_FLAGS_MEM_RDONLY 0x200
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) \
BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
#define BIO_set_retry_read(b) \
BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
#define BIO_set_retry_write(b) \
BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
/* These are normally used internally in BIOs */
#define BIO_clear_retry_flags(b) \
BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
#define BIO_get_retry_flags(b) \
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) 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,
* BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO
* stack and return the 'reason' for the special and the offending BIO.
* Given a BIO, BIO_get_retry_reason(bio) will return the code. */
/* Returned from the SSL bio when the certificate retrieval code had an error */
#define BIO_RR_SSL_X509_LOOKUP 0x01
/* Returned from the connect BIO when a connect would have blocked */
#define BIO_RR_CONNECT 0x02
/* Returned from the accept BIO when an accept would have blocked */
#define BIO_RR_ACCEPT 0x03
/* Returned from the SSL bio when the channel id retrieval code cannot find the
* private key. */
#define BIO_RR_SSL_CHANNEL_ID_LOOKUP 0x04
/* These are passed by the BIO callback */
#define BIO_CB_FREE 0x01
#define BIO_CB_READ 0x02
#define BIO_CB_WRITE 0x03
#define BIO_CB_PUTS 0x04
#define BIO_CB_GETS 0x05
#define BIO_CB_CTRL 0x06
/* The callback is called before and after the underling operation,
* The BIO_CB_RETURN flag indicates if it is after the call */
#define BIO_CB_RETURN 0x80
#define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
#define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN))
#define BIO_cb_post(a) ((a)&BIO_CB_RETURN)
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);
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);
typedef struct bio_method_st
{
int type;
const char *name;
int (*bwrite)(BIO *, const char *, int);
int (*bread)(BIO *, char *, int);
int (*bputs)(BIO *, const char *);
int (*bgets)(BIO *, char *, int);
long (*ctrl)(BIO *, int, long, void *);
int (*create)(BIO *);
int (*destroy)(BIO *);
long (*callback_ctrl)(BIO *, int, bio_info_cb *);
} BIO_METHOD;
struct bio_st
{
BIO_METHOD *method;
/* bio, mode, argp, argi, argl, ret */
long (*callback)(struct bio_st *,int,const char *,int, long,long);
char *cb_arg; /* first argument for the callback */
int init;
int shutdown;
int flags; /* extra storage */
int retry_reason;
int num;
void *ptr;
struct bio_st *next_bio; /* used by filter BIOs */
struct bio_st *prev_bio; /* used by filter BIOs */
int references;
unsigned long num_read;
unsigned long num_write;
CRYPTO_EX_DATA ex_data;
};
DECLARE_STACK_OF(BIO)
typedef struct bio_f_buffer_ctx_struct
{
/* Buffers are setup like this:
*
* <---------------------- size ----------------------->
* +---------------------------------------------------+
* | consumed | remaining | free space |
* +---------------------------------------------------+
* <-- off --><------- len ------->
*/
/* BIO *bio; */ /* this is now in the BIO struct */
int ibuf_size; /* how big is the input buffer */
int obuf_size; /* how big is the output buffer */
char *ibuf; /* the char array */
int ibuf_len; /* how many bytes are in it */
int ibuf_off; /* write/read offset */
char *obuf; /* the char array */
int obuf_len; /* how many bytes are in it */
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);
#ifndef OPENSSL_NO_SCTP
/* SCTP parameter structs */
struct bio_dgram_sctp_sndinfo
{
uint16_t snd_sid;
uint16_t snd_flags;
uint32_t snd_ppid;
uint32_t snd_context;
};
struct bio_dgram_sctp_rcvinfo
{
uint16_t rcv_sid;
uint16_t rcv_ssn;
uint16_t rcv_flags;
uint32_t rcv_ppid;
uint32_t rcv_tsn;
uint32_t rcv_cumtsn;
uint32_t rcv_context;
};
struct bio_dgram_sctp_prinfo
{
uint16_t pr_policy;
uint32_t pr_value;
};
#endif
/* connect BIO stuff */
#define BIO_CONN_S_BEFORE 1
#define BIO_CONN_S_GET_IP 2
#define BIO_CONN_S_GET_PORT 3
#define BIO_CONN_S_CREATE_SOCKET 4
#define BIO_CONN_S_CONNECT 5
#define BIO_CONN_S_OK 6
#define BIO_CONN_S_BLOCKED_CONNECT 7
#define BIO_CONN_S_NBIO 8
/*#define BIO_CONN_get_param_hostname BIO_ctrl */
#define BIO_C_SET_CONNECT 100
#define BIO_C_DO_STATE_MACHINE 101
#define BIO_C_SET_NBIO 102
#define BIO_C_SET_PROXY_PARAM 103
#define BIO_C_SET_FD 104
#define BIO_C_GET_FD 105
#define BIO_C_SET_FILE_PTR 106
#define BIO_C_GET_FILE_PTR 107
#define BIO_C_SET_FILENAME 108
#define BIO_C_SET_SSL 109
#define BIO_C_GET_SSL 110
#define BIO_C_SET_MD 111
#define BIO_C_GET_MD 112
#define BIO_C_GET_CIPHER_STATUS 113
#define BIO_C_SET_BUF_MEM 114
#define BIO_C_GET_BUF_MEM_PTR 115
#define BIO_C_GET_BUFF_NUM_LINES 116
#define BIO_C_SET_BUFF_SIZE 117
#define BIO_C_SET_ACCEPT 118
#define BIO_C_SSL_MODE 119
#define BIO_C_GET_MD_CTX 120
#define BIO_C_GET_PROXY_PARAM 121
#define BIO_C_SET_BUFF_READ_DATA 122 /* data to read first */
#define BIO_C_GET_CONNECT 123
#define BIO_C_GET_ACCEPT 124
#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125
#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126
#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127
#define BIO_C_FILE_SEEK 128
#define BIO_C_GET_CIPHER_CTX 129
#define BIO_C_SET_BUF_MEM_EOF_RETURN 130/*return end of input value*/
#define BIO_C_SET_BIND_MODE 131
#define BIO_C_GET_BIND_MODE 132
#define BIO_C_FILE_TELL 133
#define BIO_C_GET_SOCKS 134
#define BIO_C_SET_SOCKS 135
#define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */
#define BIO_C_GET_WRITE_BUF_SIZE 137
#define BIO_C_MAKE_BIO_PAIR 138
#define BIO_C_DESTROY_BIO_PAIR 139
#define BIO_C_GET_WRITE_GUARANTEE 140
#define BIO_C_GET_READ_REQUEST 141
#define BIO_C_SHUTDOWN_WR 142
#define BIO_C_NREAD0 143
#define BIO_C_NREAD 144
#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)
/* BIO_s_connect() and BIO_s_socks4a_connect() */
#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
#define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
#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,0)
#define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
/* BIO_s_accept_socket() */
#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)?(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
#define BIO_BIND_REUSEADDR_IF_UNUSED 1
#define BIO_BIND_REUSEADDR 2
#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
#define BIO_do_connect(b) BIO_do_handshake(b)
#define BIO_do_accept(b) BIO_do_handshake(b)
#define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
/* BIO_s_proxy_client() */
#define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
#define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
/* BIO_set_nbio(b,n) */
#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
/* BIO *BIO_get_filter_bio(BIO *bio); */
#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
#define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
#define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
#define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
#define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
#define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
#define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
#define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
#define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
/* name is cast to lose const, but might be better to route through a function
so we can do it safely */
#ifdef CONST_STRICT
/* If you are wondering why this isn't defined, its because CONST_STRICT is
* purely a compile-time kludge to allow const to be checked.
*/
int BIO_read_filename(BIO *b,const char *name);
#else
#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
BIO_CLOSE|BIO_FP_READ,(char *)name)
#endif
#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
BIO_CLOSE|BIO_FP_WRITE,name)
#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
BIO_CLOSE|BIO_FP_APPEND,name)
#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
/* WARNING WARNING, this ups the reference count on the read bio of the
* SSL structure. This is because the ssl read BIO is now pointed to by
* the next_bio field in the bio. So when you free the BIO, make sure
* you are doing a BIO_free_all() to catch the underlying BIO. */
#define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
#define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
#define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
#define BIO_set_ssl_renegotiate_bytes(b,num) \
BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
#define BIO_get_num_renegotiates(b) \
BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL);
#define BIO_set_ssl_renegotiate_timeout(b,seconds) \
BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
/* defined in evp.h */
/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
#define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
#define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
#define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
#define BIO_set_mem_eof_return(b,v) \
BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
/* For the BIO_f_buffer() type */
#define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
#define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
/* Don't use the next one unless you know what you are doing :-) */
#define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
#define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
#define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
#define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
#define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
#define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
#define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
/* ...pending macros have inappropriate return type */
size_t BIO_ctrl_pending(BIO *b);
size_t BIO_ctrl_wpending(BIO *b);
#define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
cbp)
#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
/* For the BIO_f_buffer() type */
#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
/* For BIO_s_bio() */
#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
#define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
#define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
#define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
/* macros with inappropriate type -- but ...pending macros use int too: */
#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
#define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
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)()); */
int BIO_set_ex_data(BIO *bio,int idx,void *data);
void *BIO_get_ex_data(BIO *bio,int idx);
int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_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
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
# endif
BIO * BIO_new(BIO_METHOD *type);
int BIO_set(BIO *a,BIO_METHOD *type);
int BIO_free(BIO *a);
void BIO_vfree(BIO *a);
int BIO_read(BIO *b, void *data, int len);
int BIO_gets(BIO *bp,char *buf, int size);
int BIO_write(BIO *b, const void *data, int len);
int BIO_puts(BIO *bp,const char *buf);
int BIO_indent(BIO *b,int indent,int max);
long BIO_ctrl(BIO *bp,int cmd,long larg,void *parg);
long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long));
char * BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
long BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
BIO * BIO_push(BIO *b,BIO *append);
BIO * BIO_pop(BIO *b);
void BIO_free_all(BIO *a);
BIO * BIO_find_type(BIO *b,int bio_type);
BIO * BIO_next(BIO *b);
BIO * BIO_get_retry_BIO(BIO *bio, int *reason);
int BIO_get_retry_reason(BIO *bio);
BIO * BIO_dup_chain(BIO *in);
int BIO_nread0(BIO *bio, char **buf);
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);
long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
long argl,long ret);
BIO_METHOD *BIO_s_mem(void);
BIO *BIO_new_mem_buf(void *buf, int len);
BIO_METHOD *BIO_s_socket(void);
BIO_METHOD *BIO_s_connect(void);
BIO_METHOD *BIO_s_accept(void);
BIO_METHOD *BIO_s_fd(void);
#ifndef OPENSSL_SYS_OS2
BIO_METHOD *BIO_s_log(void);
#endif
BIO_METHOD *BIO_s_bio(void);
BIO_METHOD *BIO_s_null(void);
BIO_METHOD *BIO_f_null(void);
BIO_METHOD *BIO_f_buffer(void);
#ifdef OPENSSL_SYS_VMS
BIO_METHOD *BIO_f_linebuffer(void);
#endif
BIO_METHOD *BIO_f_nbio_test(void);
#ifndef OPENSSL_NO_DGRAM
BIO_METHOD *BIO_s_datagram(void);
#ifndef OPENSSL_NO_SCTP
BIO_METHOD *BIO_s_datagram_sctp(void);
#endif
#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),
void *u, const char *s, int len);
int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
void *u, const char *s, int len, int indent);
int BIO_dump(BIO *b,const char *bytes,int len);
int BIO_dump_indent(BIO *b,const char *bytes,int len,int indent);
#ifndef OPENSSL_NO_FP_API
int BIO_dump_fp(FILE *fp, const char *s, int len);
int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
#endif
struct hostent *BIO_gethostbyname(const char *name);
/* We might want a thread-safe interface too:
* struct hostent *BIO_gethostbyname_r(const char *name,
* struct hostent *result, void *buffer, size_t buflen);
* or something similar (caller allocates a struct hostent,
* pointed to by "result", and additional buffer space for the various
* substructures; if the buffer does not suffice, NULL is returned
* and an appropriate error code is set).
*/
int BIO_sock_error(int sock);
int BIO_socket_ioctl(int fd, long type, void *arg);
int BIO_socket_nbio(int fd,int mode);
int BIO_get_port(const char *str, unsigned short *port_ptr);
int BIO_get_host_ip(const char *str, unsigned char *ip);
int BIO_get_accept_socket(char *host_port,int mode);
int BIO_accept(int sock,char **ip_port);
int BIO_sock_init(void );
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);
#ifndef OPENSSL_NO_SCTP
BIO *BIO_new_dgram_sctp(int fd, int close_flag);
int BIO_dgram_is_sctp(BIO *bio);
int BIO_dgram_sctp_notification_cb(BIO *b,
void (*handle_notifications)(BIO *bio, void *context, void *buf),
void *context);
int BIO_dgram_sctp_wait_for_dry(BIO *b);
int BIO_dgram_sctp_msg_waiting(BIO *b);
#endif
BIO *BIO_new_fd(int fd, int close_flag);
BIO *BIO_new_connect(char *host_port);
BIO *BIO_new_accept(char *host_port);
int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
BIO **bio2, size_t writebuf2);
/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
* Otherwise returns 0 and sets *bio1 and *bio2 to NULL.
* Size 0 uses default value.
*/
void BIO_copy_next_retry(BIO *b);
/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/
#ifdef __GNUC__
# define __bio_h__attr__ __attribute__
#else
# define __bio_h__attr__(x)
#endif
int BIO_printf(BIO *bio, const char *format, ...)
__bio_h__attr__((__format__(__printf__,2,3)));
int BIO_vprintf(BIO *bio, const char *format, va_list args)
__bio_h__attr__((__format__(__printf__,2,0)));
int BIO_snprintf(char *buf, size_t n, const char *format, ...)
__bio_h__attr__((__format__(__printf__,3,4)));
int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
__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
* made after this point may be overwritten when the script is next run.
*/
void ERR_load_BIO_strings(void);
/* Error codes for the BIO functions. */
/* Function codes. */
#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
#define BIO_F_BIO_GET_ACCEPT_SOCKET 105
#define BIO_F_BIO_GET_HOST_IP 106
#define BIO_F_BIO_GET_PORT 107
#define BIO_F_BIO_MAKE_PAIR 121
#define BIO_F_BIO_NEW 108
#define BIO_F_BIO_NEW_FILE 109
#define BIO_F_BIO_NEW_MEM_BUF 126
#define BIO_F_BIO_NREAD 123
#define BIO_F_BIO_NREAD0 124
#define BIO_F_BIO_NWRITE 125
#define BIO_F_BIO_NWRITE0 122
#define BIO_F_BIO_PUTS 110
#define BIO_F_BIO_READ 111
#define BIO_F_BIO_SOCK_INIT 112
#define BIO_F_BIO_WRITE 113
#define BIO_F_BUFFER_CTRL 114
#define BIO_F_CONN_CTRL 127
#define BIO_F_CONN_STATE 115
#define BIO_F_DGRAM_SCTP_READ 132
#define BIO_F_FILE_CTRL 116
#define BIO_F_FILE_READ 130
#define BIO_F_LINEBUFFER_CTRL 129
#define BIO_F_MEM_READ 128
#define BIO_F_MEM_WRITE 117
#define BIO_F_SSL_NEW 118
#define BIO_F_WSASTARTUP 119
/* Reason codes. */
#define BIO_R_ACCEPT_ERROR 100
#define BIO_R_BAD_FOPEN_MODE 101
#define BIO_R_BAD_HOSTNAME_LOOKUP 102
#define BIO_R_BROKEN_PIPE 124
#define BIO_R_CONNECT_ERROR 103
#define BIO_R_EOF_ON_MEMORY_BIO 127
#define BIO_R_ERROR_SETTING_NBIO 104
#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105
#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106
#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107
#define BIO_R_INVALID_ARGUMENT 125
#define BIO_R_INVALID_IP_ADDRESS 108
#define BIO_R_IN_USE 123
#define BIO_R_KEEPALIVE 109
#define BIO_R_NBIO_CONNECT_ERROR 110
#define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111
#define BIO_R_NO_HOSTNAME_SPECIFIED 112
#define BIO_R_NO_PORT_DEFINED 113
#define BIO_R_NO_PORT_SPECIFIED 114
#define BIO_R_NO_SUCH_FILE 128
#define BIO_R_NULL_PARAMETER 115
#define BIO_R_TAG_MISMATCH 116
#define BIO_R_UNABLE_TO_BIND_SOCKET 117
#define BIO_R_UNABLE_TO_CREATE_SOCKET 118
#define BIO_R_UNABLE_TO_LISTEN_SOCKET 119
#define BIO_R_UNINITIALIZED 120
#define BIO_R_UNSUPPORTED_METHOD 121
#define BIO_R_WRITE_TO_READ_ONLY_BIO 126
#define BIO_R_WSASTARTUP 122
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,143 @@
/* crypto/bio/bio_cb.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cryptlib.h"
#include <openssl/bio.h>
#include <openssl/err.h>
long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp,
int argi, long argl, long ret)
{
BIO *b;
MS_STATIC char buf[256];
char *p;
long r=1;
size_t p_maxlen;
if (BIO_CB_RETURN & cmd)
r=ret;
BIO_snprintf(buf,sizeof buf,"BIO[%08lX]:",(unsigned long)bio);
p= &(buf[14]);
p_maxlen = sizeof buf - 14;
switch (cmd)
{
case BIO_CB_FREE:
BIO_snprintf(p,p_maxlen,"Free - %s\n",bio->method->name);
break;
case BIO_CB_READ:
if (bio->method->type & BIO_TYPE_DESCRIPTOR)
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,%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,%lu) - %s fd=%d\n",
bio->num,(unsigned long)argi,
bio->method->name,bio->num);
else
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(%lu) - %s\n",(unsigned long)argi,bio->method->name);
break;
case BIO_CB_CTRL:
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);
break;
case BIO_CB_RETURN|BIO_CB_WRITE:
BIO_snprintf(p,p_maxlen,"write return %ld\n",ret);
break;
case BIO_CB_RETURN|BIO_CB_GETS:
BIO_snprintf(p,p_maxlen,"gets return %ld\n",ret);
break;
case BIO_CB_RETURN|BIO_CB_PUTS:
BIO_snprintf(p,p_maxlen,"puts return %ld\n",ret);
break;
case BIO_CB_RETURN|BIO_CB_CTRL:
BIO_snprintf(p,p_maxlen,"ctrl return %ld\n",ret);
break;
default:
BIO_snprintf(p,p_maxlen,"bio callback - unknown type (%d)\n",cmd);
break;
}
b=(BIO *)bio->cb_arg;
if (b != NULL)
BIO_write(b,buf,strlen(buf));
#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
else
fputs(buf,stderr);
#endif
return(r);
}

View File

@@ -0,0 +1,155 @@
/* crypto/bio/bio_err.c */
/* ====================================================================
* Copyright (c) 1999-2011 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).
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/bio.h>
/* 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_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_DGRAM_SCTP_READ), "DGRAM_SCTP_READ"},
{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[]=
{
{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}
};
#endif
void ERR_load_BIO_strings(void)
{
#ifndef OPENSSL_NO_ERR
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
}

View File

@@ -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

View File

@@ -0,0 +1,602 @@
/* crypto/bio/bio_lib.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#include <openssl/crypto.h>
#include "cryptlib.h"
#include <openssl/bio.h>
#include <openssl/stack.h>
BIO *BIO_new(BIO_METHOD *method)
{
BIO *ret=NULL;
ret=(BIO *)OPENSSL_malloc(sizeof(BIO));
if (ret == NULL)
{
BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
}
if (!BIO_set(ret,method))
{
OPENSSL_free(ret);
ret=NULL;
}
return(ret);
}
int BIO_set(BIO *bio, BIO_METHOD *method)
{
bio->method=method;
bio->callback=NULL;
bio->cb_arg=NULL;
bio->init=0;
bio->shutdown=1;
bio->flags=0;
bio->retry_reason=0;
bio->num=0;
bio->ptr=NULL;
bio->prev_bio=NULL;
bio->next_bio=NULL;
bio->references=1;
bio->num_read=0L;
bio->num_write=0L;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
if (method->create != NULL)
if (!method->create(bio))
{
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
&bio->ex_data);
return(0);
}
return(1);
}
int BIO_free(BIO *a)
{
int i;
if (a == NULL) return(0);
i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
#ifdef REF_PRINT
REF_PRINT("BIO",a);
#endif
if (i > 0) return(1);
#ifdef REF_CHECK
if (i < 0)
{
fprintf(stderr,"BIO_free, bad reference count\n");
abort();
}
#endif
if ((a->callback != NULL) &&
((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0))
return(i);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
a->method->destroy(a);
OPENSSL_free(a);
return(1);
}
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;
long (*cb)(BIO *,int,const char *,int,long,long);
if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL))
{
BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD);
return(-2);
}
cb=b->callback;
if ((cb != NULL) &&
((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
return(i);
if (!b->init)
{
BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED);
return(-2);
}
i=b->method->bread(b,out,outl);
if (i > 0) b->num_read+=(unsigned long)i;
if (cb != NULL)
i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
0L,(long)i);
return(i);
}
int BIO_write(BIO *b, const void *in, int inl)
{
int i;
long (*cb)(BIO *,int,const char *,int,long,long);
if (b == NULL)
return(0);
cb=b->callback;
if ((b->method == NULL) || (b->method->bwrite == NULL))
{
BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD);
return(-2);
}
if ((cb != NULL) &&
((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
return(i);
if (!b->init)
{
BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED);
return(-2);
}
i=b->method->bwrite(b,in,inl);
if (i > 0) b->num_write+=(unsigned long)i;
if (cb != NULL)
i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
0L,(long)i);
return(i);
}
int BIO_puts(BIO *b, const char *in)
{
int i;
long (*cb)(BIO *,int,const char *,int,long,long);
if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
{
BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD);
return(-2);
}
cb=b->callback;
if ((cb != NULL) &&
((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
return(i);
if (!b->init)
{
BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED);
return(-2);
}
i=b->method->bputs(b,in);
if (i > 0) b->num_write+=(unsigned long)i;
if (cb != NULL)
i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
0L,(long)i);
return(i);
}
int BIO_gets(BIO *b, char *in, int inl)
{
int i;
long (*cb)(BIO *,int,const char *,int,long,long);
if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
{
BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);
return(-2);
}
cb=b->callback;
if ((cb != NULL) &&
((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
return(i);
if (!b->init)
{
BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);
return(-2);
}
i=b->method->bgets(b,in,inl);
if (cb != NULL)
i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
0L,(long)i);
return(i);
}
int BIO_indent(BIO *b,int indent,int max)
{
if(indent < 0)
indent=0;
if(indent > max)
indent=max;
while(indent--)
if(BIO_puts(b," ") != 1)
return 0;
return 1;
}
long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
{
int i;
i=iarg;
return(BIO_ctrl(b,cmd,larg,(char *)&i));
}
char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
{
char *p=NULL;
if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
return(NULL);
else
return(p);
}
long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
{
long ret;
long (*cb)(BIO *,int,const char *,int,long,long);
if (b == NULL) return(0);
if ((b->method == NULL) || (b->method->ctrl == NULL))
{
BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
return(-2);
}
cb=b->callback;
if ((cb != NULL) &&
((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
return(ret);
ret=b->method->ctrl(b,cmd,larg,parg);
if (cb != NULL)
ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
larg,ret);
return(ret);
}
long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long))
{
long ret;
long (*cb)(BIO *,int,const char *,int,long,long);
if (b == NULL) return(0);
if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
{
BIOerr(BIO_F_BIO_CALLBACK_CTRL,BIO_R_UNSUPPORTED_METHOD);
return(-2);
}
cb=b->callback;
if ((cb != NULL) &&
((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
return(ret);
ret=b->method->callback_ctrl(b,cmd,fp);
if (cb != NULL)
ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
0,ret);
return(ret);
}
/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
* do; but those macros have inappropriate return type, and for interfacing
* from other programming languages, C macros aren't much of a help anyway. */
size_t BIO_ctrl_pending(BIO *bio)
{
return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
}
size_t BIO_ctrl_wpending(BIO *bio)
{
return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
}
/* put the 'bio' on the end of b's list of operators */
BIO *BIO_push(BIO *b, BIO *bio)
{
BIO *lb;
if (b == NULL) return(bio);
lb=b;
while (lb->next_bio != NULL)
lb=lb->next_bio;
lb->next_bio=bio;
if (bio != NULL)
bio->prev_bio=lb;
/* called to do internal processing */
BIO_ctrl(b,BIO_CTRL_PUSH,0,lb);
return(b);
}
/* Remove the first and return the rest */
BIO *BIO_pop(BIO *b)
{
BIO *ret;
if (b == NULL) return(NULL);
ret=b->next_bio;
BIO_ctrl(b,BIO_CTRL_POP,0,b);
if (b->prev_bio != NULL)
b->prev_bio->next_bio=b->next_bio;
if (b->next_bio != NULL)
b->next_bio->prev_bio=b->prev_bio;
b->next_bio=NULL;
b->prev_bio=NULL;
return(ret);
}
BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
{
BIO *b,*last;
b=last=bio;
for (;;)
{
if (!BIO_should_retry(b)) break;
last=b;
b=b->next_bio;
if (b == NULL) break;
}
if (reason != NULL) *reason=last->retry_reason;
return(last);
}
int BIO_get_retry_reason(BIO *bio)
{
return(bio->retry_reason);
}
BIO *BIO_find_type(BIO *bio, int type)
{
int mt,mask;
if(!bio) return NULL;
mask=type&0xff;
do {
if (bio->method != NULL)
{
mt=bio->method->type;
if (!mask)
{
if (mt & type) return(bio);
}
else if (mt == type)
return(bio);
}
bio=bio->next_bio;
} while (bio != NULL);
return(NULL);
}
BIO *BIO_next(BIO *b)
{
if(!b) return NULL;
return b->next_bio;
}
void BIO_free_all(BIO *bio)
{
BIO *b;
int ref;
while (bio != NULL)
{
b=bio;
ref=b->references;
bio=bio->next_bio;
BIO_free(b);
/* Since ref count > 1, don't free anyone else. */
if (ref > 1) break;
}
}
BIO *BIO_dup_chain(BIO *in)
{
BIO *ret=NULL,*eoc=NULL,*bio,*new_bio;
for (bio=in; bio != NULL; bio=bio->next_bio)
{
if ((new_bio=BIO_new(bio->method)) == NULL) goto err;
new_bio->callback=bio->callback;
new_bio->cb_arg=bio->cb_arg;
new_bio->init=bio->init;
new_bio->shutdown=bio->shutdown;
new_bio->flags=bio->flags;
/* This will let SSL_s_sock() work with stdin/stdout */
new_bio->num=bio->num;
if (!BIO_dup_state(bio,(char *)new_bio))
{
BIO_free(new_bio);
goto err;
}
/* copy app data */
if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
&bio->ex_data))
goto err;
if (ret == NULL)
{
eoc=new_bio;
ret=eoc;
}
else
{
BIO_push(eoc,new_bio);
eoc=new_bio;
}
}
return(ret);
err:
if (ret != NULL)
BIO_free(ret);
return(NULL);
}
void BIO_copy_next_retry(BIO *b)
{
BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
b->retry_reason=b->next_bio->retry_reason;
}
int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
new_func, dup_func, free_func);
}
int BIO_set_ex_data(BIO *bio, int idx, void *data)
{
return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
}
void *BIO_get_ex_data(BIO *bio, int idx)
{
return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
}
unsigned long BIO_number_read(BIO *bio)
{
if(bio) return bio->num_read;
return 0;
}
unsigned long BIO_number_written(BIO *bio)
{
if(bio) return bio->num_write;
return 0;
}
IMPLEMENT_STACK_OF(BIO)

View File

@@ -0,0 +1,478 @@
/* crypto/bio/bss_acpt.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#define USE_SOCKETS
#include "cryptlib.h"
#include <openssl/bio.h>
#ifndef OPENSSL_NO_SOCK
#ifdef OPENSSL_SYS_WIN16
#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
#else
#define SOCKET_PROTOCOL IPPROTO_TCP
#endif
#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
#undef FIONBIO
#endif
typedef struct bio_accept_st
{
int state;
char *param_addr;
int accept_sock;
int accept_nbio;
char *addr;
int nbio;
/* If 0, it means normal, if 1, do a connect on bind failure,
* and if there is no-one listening, bind with SO_REUSEADDR.
* If 2, always use SO_REUSEADDR. */
int bind_mode;
BIO *bio_chain;
} BIO_ACCEPT;
static int acpt_write(BIO *h, const char *buf, int num);
static int acpt_read(BIO *h, char *buf, int size);
static int acpt_puts(BIO *h, const char *str);
static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
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);
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
#define ACPT_S_OK 3
static BIO_METHOD methods_acceptp=
{
BIO_TYPE_ACCEPT,
"socket accept",
acpt_write,
acpt_read,
acpt_puts,
NULL, /* connect_gets, */
acpt_ctrl,
acpt_new,
acpt_free,
NULL,
};
BIO_METHOD *BIO_s_accept(void)
{
return(&methods_acceptp);
}
static int acpt_new(BIO *bi)
{
BIO_ACCEPT *ba;
bi->init=0;
bi->num=INVALID_SOCKET;
bi->flags=0;
if ((ba=BIO_ACCEPT_new()) == NULL)
return(0);
bi->ptr=(char *)ba;
ba->state=ACPT_S_BEFORE;
bi->shutdown=1;
return(1);
}
static BIO_ACCEPT *BIO_ACCEPT_new(void)
{
BIO_ACCEPT *ret;
if ((ret=(BIO_ACCEPT *)OPENSSL_malloc(sizeof(BIO_ACCEPT))) == NULL)
return(NULL);
memset(ret,0,sizeof(BIO_ACCEPT));
ret->accept_sock=INVALID_SOCKET;
ret->bind_mode=BIO_BIND_NORMAL;
return(ret);
}
static void BIO_ACCEPT_free(BIO_ACCEPT *a)
{
if(a == NULL)
return;
if (a->param_addr != NULL) OPENSSL_free(a->param_addr);
if (a->addr != NULL) OPENSSL_free(a->addr);
if (a->bio_chain != NULL) BIO_free(a->bio_chain);
OPENSSL_free(a);
}
static void acpt_close_socket(BIO *bio)
{
BIO_ACCEPT *c;
c=(BIO_ACCEPT *)bio->ptr;
if (c->accept_sock != INVALID_SOCKET)
{
shutdown(c->accept_sock,2);
closesocket(c->accept_sock);
c->accept_sock=INVALID_SOCKET;
bio->num=INVALID_SOCKET;
}
}
static int acpt_free(BIO *a)
{
BIO_ACCEPT *data;
if (a == NULL) return(0);
data=(BIO_ACCEPT *)a->ptr;
if (a->shutdown)
{
acpt_close_socket(a);
BIO_ACCEPT_free(data);
a->ptr=NULL;
a->flags=0;
a->init=0;
}
return(1);
}
static int acpt_state(BIO *b, BIO_ACCEPT *c)
{
BIO *bio=NULL,*dbio;
int s= -1;
int i;
again:
switch (c->state)
{
case ACPT_S_BEFORE:
if (c->param_addr == NULL)
{
BIOerr(BIO_F_ACPT_STATE,BIO_R_NO_ACCEPT_PORT_SPECIFIED);
return(-1);
}
s=BIO_get_accept_socket(c->param_addr,c->bind_mode);
if (s == INVALID_SOCKET)
return(-1);
if (c->accept_nbio)
{
if (!BIO_socket_nbio(s,1))
{
closesocket(s);
BIOerr(BIO_F_ACPT_STATE,BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET);
return(-1);
}
}
c->accept_sock=s;
b->num=s;
c->state=ACPT_S_GET_ACCEPT_SOCKET;
return(1);
/* break; */
case ACPT_S_GET_ACCEPT_SOCKET:
if (b->next_bio != NULL)
{
c->state=ACPT_S_OK;
goto again;
}
BIO_clear_retry_flags(b);
b->retry_reason=0;
i=BIO_accept(c->accept_sock,&(c->addr));
/* -2 return means we should retry */
if(i == -2)
{
BIO_set_retry_special(b);
b->retry_reason=BIO_RR_ACCEPT;
return -1;
}
if (i < 0) return(i);
bio=BIO_new_socket(i,BIO_CLOSE);
if (bio == NULL) goto err;
BIO_set_callback(bio,BIO_get_callback(b));
BIO_set_callback_arg(bio,BIO_get_callback_arg(b));
if (c->nbio)
{
if (!BIO_socket_nbio(i,1))
{
BIOerr(BIO_F_ACPT_STATE,BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET);
goto err;
}
}
/* If the accept BIO has an bio_chain, we dup it and
* put the new socket at the end. */
if (c->bio_chain != NULL)
{
if ((dbio=BIO_dup_chain(c->bio_chain)) == NULL)
goto err;
if (!BIO_push(dbio,bio)) goto err;
bio=dbio;
}
if (BIO_push(b,bio) == NULL) goto err;
c->state=ACPT_S_OK;
return(1);
err:
if (bio != NULL)
BIO_free(bio);
else if (s >= 0)
closesocket(s);
return(0);
/* break; */
case ACPT_S_OK:
if (b->next_bio == NULL)
{
c->state=ACPT_S_GET_ACCEPT_SOCKET;
goto again;
}
return(1);
/* break; */
default:
return(0);
/* break; */
}
}
static int acpt_read(BIO *b, char *out, int outl)
{
int ret=0;
BIO_ACCEPT *data;
BIO_clear_retry_flags(b);
data=(BIO_ACCEPT *)b->ptr;
while (b->next_bio == NULL)
{
ret=acpt_state(b,data);
if (ret <= 0) return(ret);
}
ret=BIO_read(b->next_bio,out,outl);
BIO_copy_next_retry(b);
return(ret);
}
static int acpt_write(BIO *b, const char *in, int inl)
{
int ret;
BIO_ACCEPT *data;
BIO_clear_retry_flags(b);
data=(BIO_ACCEPT *)b->ptr;
while (b->next_bio == NULL)
{
ret=acpt_state(b,data);
if (ret <= 0) return(ret);
}
ret=BIO_write(b->next_bio,in,inl);
BIO_copy_next_retry(b);
return(ret);
}
static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
{
int *ip;
long ret=1;
BIO_ACCEPT *data;
char **pp;
data=(BIO_ACCEPT *)b->ptr;
switch (cmd)
{
case BIO_CTRL_RESET:
ret=0;
data->state=ACPT_S_BEFORE;
acpt_close_socket(b);
b->flags=0;
break;
case BIO_C_DO_STATE_MACHINE:
/* use this one to start the connection */
ret=(long)acpt_state(b,data);
break;
case BIO_C_SET_ACCEPT:
if (ptr != NULL)
{
if (num == 0)
{
b->init=1;
if (data->param_addr != NULL)
OPENSSL_free(data->param_addr);
data->param_addr=BUF_strdup(ptr);
}
else if (num == 1)
{
data->accept_nbio=(ptr != NULL);
}
else if (num == 2)
{
if (data->bio_chain != NULL)
BIO_free(data->bio_chain);
data->bio_chain=(BIO *)ptr;
}
}
break;
case BIO_C_SET_NBIO:
data->nbio=(int)num;
break;
case BIO_C_SET_FD:
b->init=1;
b->num= *((int *)ptr);
data->accept_sock=b->num;
data->state=ACPT_S_GET_ACCEPT_SOCKET;
b->shutdown=(int)num;
b->init=1;
break;
case BIO_C_GET_FD:
if (b->init)
{
ip=(int *)ptr;
if (ip != NULL)
*ip=data->accept_sock;
ret=data->accept_sock;
}
else
ret= -1;
break;
case BIO_C_GET_ACCEPT:
if (b->init)
{
if (ptr != NULL)
{
pp=(char **)ptr;
*pp=data->param_addr;
}
else
ret= -1;
}
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_FLUSH:
break;
case BIO_C_SET_BIND_MODE:
data->bind_mode=(int)num;
break;
case BIO_C_GET_BIND_MODE:
ret=(long)data->bind_mode;
break;
case BIO_CTRL_DUP:
/* dbio=(BIO *)ptr;
if (data->param_port) EAY EAY
BIO_set_port(dbio,data->param_port);
if (data->param_hostname)
BIO_set_hostname(dbio,data->param_hostname);
BIO_set_nbio(dbio,data->nbio); */
break;
default:
ret=0;
break;
}
return(ret);
}
static int acpt_puts(BIO *bp, const char *str)
{
int n,ret;
n=strlen(str);
ret=acpt_write(bp,str,n);
return(ret);
}
BIO *BIO_new_accept(char *str)
{
BIO *ret;
ret=BIO_new(BIO_s_accept());
if (ret == NULL) return(NULL);
if (BIO_set_accept_port(ret,str))
return(ret);
else
{
BIO_free(ret);
return(NULL);
}
}
#endif

View File

@@ -0,0 +1,924 @@
/* crypto/bio/bss_bio.c -*- Mode: C; c-file-style: "eay" -*- */
/* ====================================================================
* Copyright (c) 1998-2003 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).
*
*/
/* Special method for a BIO where the other endpoint is also a BIO
* of this kind, handled by the same thread (i.e. the "peer" is actually
* ourselves, wearing a different hat).
* Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
* for which no specific BIO method is available.
* See ssl/ssltest.c for some hints on how this can be used. */
/* BIO_DEBUG implies BIO_PAIR_DEBUG */
#ifdef BIO_DEBUG
# ifndef BIO_PAIR_DEBUG
# define BIO_PAIR_DEBUG
# endif
#endif
/* disable assert() unless BIO_PAIR_DEBUG has been defined */
#ifndef BIO_PAIR_DEBUG
# ifndef NDEBUG
# define NDEBUG
# endif
#endif
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
#include "e_os.h"
/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */
#if defined(OPENSSL_SYS_VXWORKS)
# undef SSIZE_MAX
#endif
#ifndef SSIZE_MAX
# define SSIZE_MAX INT_MAX
#endif
static int bio_new(BIO *bio);
static int bio_free(BIO *bio);
static int bio_read(BIO *bio, char *buf, int size);
static int bio_write(BIO *bio, const char *buf, int num);
static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
static int bio_puts(BIO *bio, const char *str);
static int bio_make_pair(BIO *bio1, BIO *bio2);
static void bio_destroy_pair(BIO *bio);
static BIO_METHOD methods_biop =
{
BIO_TYPE_BIO,
"BIO pair",
bio_write,
bio_read,
bio_puts,
NULL /* no bio_gets */,
bio_ctrl,
bio_new,
bio_free,
NULL /* no bio_callback_ctrl */
};
BIO_METHOD *BIO_s_bio(void)
{
return &methods_biop;
}
struct bio_bio_st
{
BIO *peer; /* NULL if buf == NULL.
* If peer != NULL, then peer->ptr is also a bio_bio_st,
* and its "peer" member points back to us.
* peer != NULL iff init != 0 in the BIO. */
/* This is for what we write (i.e. reading uses peer's struct): */
int closed; /* valid iff peer != NULL */
size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
size_t size;
char *buf; /* "size" elements (if != NULL) */
size_t request; /* valid iff peer != NULL; 0 if len != 0,
* otherwise set by peer to number of bytes
* it (unsuccessfully) tried to read,
* never more than buffer space (size-len) warrants. */
};
static int bio_new(BIO *bio)
{
struct bio_bio_st *b;
b = OPENSSL_malloc(sizeof *b);
if (b == NULL)
return 0;
b->peer = NULL;
b->size = 17*1024; /* enough for one TLS record (just a default) */
b->buf = NULL;
bio->ptr = b;
return 1;
}
static int bio_free(BIO *bio)
{
struct bio_bio_st *b;
if (bio == NULL)
return 0;
b = bio->ptr;
assert(b != NULL);
if (b->peer)
bio_destroy_pair(bio);
if (b->buf != NULL)
{
OPENSSL_free(b->buf);
}
OPENSSL_free(b);
return 1;
}
static int bio_read(BIO *bio, char *buf, int size_)
{
size_t size = size_;
size_t rest;
struct bio_bio_st *b, *peer_b;
BIO_clear_retry_flags(bio);
if (!bio->init)
return 0;
b = bio->ptr;
assert(b != NULL);
assert(b->peer != NULL);
peer_b = b->peer->ptr;
assert(peer_b != NULL);
assert(peer_b->buf != NULL);
peer_b->request = 0; /* will be set in "retry_read" situation */
if (buf == NULL || size == 0)
return 0;
if (peer_b->len == 0)
{
if (peer_b->closed)
return 0; /* writer has closed, and no data is left */
else
{
BIO_set_retry_read(bio); /* buffer is empty */
if (size <= peer_b->size)
peer_b->request = size;
else
/* don't ask for more than the peer can
* deliver in one write */
peer_b->request = peer_b->size;
return -1;
}
}
/* we can read */
if (peer_b->len < size)
size = peer_b->len;
/* now read "size" bytes */
rest = size;
assert(rest > 0);
do /* one or two iterations */
{
size_t chunk;
assert(rest <= peer_b->len);
if (peer_b->offset + rest <= peer_b->size)
chunk = rest;
else
/* wrap around ring buffer */
chunk = peer_b->size - peer_b->offset;
assert(peer_b->offset + chunk <= peer_b->size);
memcpy(buf, peer_b->buf + peer_b->offset, chunk);
peer_b->len -= chunk;
if (peer_b->len)
{
peer_b->offset += chunk;
assert(peer_b->offset <= peer_b->size);
if (peer_b->offset == peer_b->size)
peer_b->offset = 0;
buf += chunk;
}
else
{
/* buffer now empty, no need to advance "buf" */
assert(chunk == rest);
peer_b->offset = 0;
}
rest -= chunk;
}
while (rest);
return size;
}
/* non-copying interface: provide pointer to available data in buffer
* bio_nread0: return number of available bytes
* bio_nread: also advance index
* (example usage: bio_nread0(), read from buffer, bio_nread()
* or just bio_nread(), read from buffer)
*/
/* WARNING: The non-copying interface is largely untested as of yet
* and may contain bugs. */
static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
{
struct bio_bio_st *b, *peer_b;
ossl_ssize_t num;
BIO_clear_retry_flags(bio);
if (!bio->init)
return 0;
b = bio->ptr;
assert(b != NULL);
assert(b->peer != NULL);
peer_b = b->peer->ptr;
assert(peer_b != NULL);
assert(peer_b->buf != NULL);
peer_b->request = 0;
if (peer_b->len == 0)
{
char dummy;
/* avoid code duplication -- nothing available for reading */
return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
}
num = peer_b->len;
if (peer_b->size < peer_b->offset + num)
/* no ring buffer wrap-around for non-copying interface */
num = peer_b->size - peer_b->offset;
assert(num > 0);
if (buf != NULL)
*buf = peer_b->buf + peer_b->offset;
return num;
}
static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
{
struct bio_bio_st *b, *peer_b;
ossl_ssize_t num, available;
if (num_ > SSIZE_MAX)
num = SSIZE_MAX;
else
num = (ossl_ssize_t)num_;
available = bio_nread0(bio, buf);
if (num > available)
num = available;
if (num <= 0)
return num;
b = bio->ptr;
peer_b = b->peer->ptr;
peer_b->len -= num;
if (peer_b->len)
{
peer_b->offset += num;
assert(peer_b->offset <= peer_b->size);
if (peer_b->offset == peer_b->size)
peer_b->offset = 0;
}
else
peer_b->offset = 0;
return num;
}
static int bio_write(BIO *bio, const char *buf, int num_)
{
size_t num = num_;
size_t rest;
struct bio_bio_st *b;
BIO_clear_retry_flags(bio);
if (!bio->init || buf == NULL || num == 0)
return 0;
b = bio->ptr;
assert(b != NULL);
assert(b->peer != NULL);
assert(b->buf != NULL);
b->request = 0;
if (b->closed)
{
/* we already closed */
BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
return -1;
}
assert(b->len <= b->size);
if (b->len == b->size)
{
BIO_set_retry_write(bio); /* buffer is full */
return -1;
}
/* we can write */
if (num > b->size - b->len)
num = b->size - b->len;
/* now write "num" bytes */
rest = num;
assert(rest > 0);
do /* one or two iterations */
{
size_t write_offset;
size_t chunk;
assert(b->len + rest <= b->size);
write_offset = b->offset + b->len;
if (write_offset >= b->size)
write_offset -= b->size;
/* b->buf[write_offset] is the first byte we can write to. */
if (write_offset + rest <= b->size)
chunk = rest;
else
/* wrap around ring buffer */
chunk = b->size - write_offset;
memcpy(b->buf + write_offset, buf, chunk);
b->len += chunk;
assert(b->len <= b->size);
rest -= chunk;
buf += chunk;
}
while (rest);
return num;
}
/* non-copying interface: provide pointer to region to write to
* bio_nwrite0: check how much space is available
* bio_nwrite: also increase length
* (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
* or just bio_nwrite(), write to buffer)
*/
static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
{
struct bio_bio_st *b;
size_t num;
size_t write_offset;
BIO_clear_retry_flags(bio);
if (!bio->init)
return 0;
b = bio->ptr;
assert(b != NULL);
assert(b->peer != NULL);
assert(b->buf != NULL);
b->request = 0;
if (b->closed)
{
BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
return -1;
}
assert(b->len <= b->size);
if (b->len == b->size)
{
BIO_set_retry_write(bio);
return -1;
}
num = b->size - b->len;
write_offset = b->offset + b->len;
if (write_offset >= b->size)
write_offset -= b->size;
if (write_offset + num > b->size)
/* no ring buffer wrap-around for non-copying interface
* (to fulfil the promise by BIO_ctrl_get_write_guarantee,
* BIO_nwrite may have to be called twice) */
num = b->size - write_offset;
if (buf != NULL)
*buf = b->buf + write_offset;
assert(write_offset + num <= b->size);
return num;
}
static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
{
struct bio_bio_st *b;
ossl_ssize_t num, space;
if (num_ > SSIZE_MAX)
num = SSIZE_MAX;
else
num = (ossl_ssize_t)num_;
space = bio_nwrite0(bio, buf);
if (num > space)
num = space;
if (num <= 0)
return num;
b = bio->ptr;
assert(b != NULL);
b->len += num;
assert(b->len <= b->size);
return num;
}
static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
{
long ret;
struct bio_bio_st *b = bio->ptr;
assert(b != NULL);
switch (cmd)
{
/* specific CTRL codes */
case BIO_C_SET_WRITE_BUF_SIZE:
if (b->peer)
{
BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
ret = 0;
}
else if (num == 0)
{
BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
ret = 0;
}
else
{
size_t new_size = num;
if (b->size != new_size)
{
if (b->buf)
{
OPENSSL_free(b->buf);
b->buf = NULL;
}
b->size = new_size;
}
ret = 1;
}
break;
case BIO_C_GET_WRITE_BUF_SIZE:
ret = (long) b->size;
break;
case BIO_C_MAKE_BIO_PAIR:
{
BIO *other_bio = ptr;
if (bio_make_pair(bio, other_bio))
ret = 1;
else
ret = 0;
}
break;
case BIO_C_DESTROY_BIO_PAIR:
/* Affects both BIOs in the pair -- call just once!
* Or let BIO_free(bio1); BIO_free(bio2); do the job. */
bio_destroy_pair(bio);
ret = 1;
break;
case BIO_C_GET_WRITE_GUARANTEE:
/* How many bytes can the caller feed to the next write
* without having to keep any? */
if (b->peer == NULL || b->closed)
ret = 0;
else
ret = (long) b->size - b->len;
break;
case BIO_C_GET_READ_REQUEST:
/* If the peer unsuccessfully tried to read, how many bytes
* were requested? (As with BIO_CTRL_PENDING, that number
* can usually be treated as boolean.) */
ret = (long) b->request;
break;
case BIO_C_RESET_READ_REQUEST:
/* Reset request. (Can be useful after read attempts
* at the other side that are meant to be non-blocking,
* e.g. when probing SSL_read to see if any data is
* available.) */
b->request = 0;
ret = 1;
break;
case BIO_C_SHUTDOWN_WR:
/* similar to shutdown(..., SHUT_WR) */
b->closed = 1;
ret = 1;
break;
case BIO_C_NREAD0:
/* prepare for non-copying read */
ret = (long) bio_nread0(bio, ptr);
break;
case BIO_C_NREAD:
/* non-copying read */
ret = (long) bio_nread(bio, ptr, (size_t) num);
break;
case BIO_C_NWRITE0:
/* prepare for non-copying write */
ret = (long) bio_nwrite0(bio, ptr);
break;
case BIO_C_NWRITE:
/* non-copying write */
ret = (long) bio_nwrite(bio, ptr, (size_t) num);
break;
/* standard CTRL codes follow */
case BIO_CTRL_RESET:
if (b->buf != NULL)
{
b->len = 0;
b->offset = 0;
}
ret = 0;
break;
case BIO_CTRL_GET_CLOSE:
ret = bio->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
bio->shutdown = (int) num;
ret = 1;
break;
case BIO_CTRL_PENDING:
if (b->peer != NULL)
{
struct bio_bio_st *peer_b = b->peer->ptr;
ret = (long) peer_b->len;
}
else
ret = 0;
break;
case BIO_CTRL_WPENDING:
if (b->buf != NULL)
ret = (long) b->len;
else
ret = 0;
break;
case BIO_CTRL_DUP:
/* See BIO_dup_chain for circumstances we have to expect. */
{
BIO *other_bio = ptr;
struct bio_bio_st *other_b;
assert(other_bio != NULL);
other_b = other_bio->ptr;
assert(other_b != NULL);
assert(other_b->buf == NULL); /* other_bio is always fresh */
other_b->size = b->size;
}
ret = 1;
break;
case BIO_CTRL_FLUSH:
ret = 1;
break;
case BIO_CTRL_EOF:
{
BIO *other_bio = ptr;
if (other_bio)
{
struct bio_bio_st *other_b = other_bio->ptr;
assert(other_b != NULL);
ret = other_b->len == 0 && other_b->closed;
}
else
ret = 1;
}
break;
default:
ret = 0;
}
return ret;
}
static int bio_puts(BIO *bio, const char *str)
{
return bio_write(bio, str, strlen(str));
}
static int bio_make_pair(BIO *bio1, BIO *bio2)
{
struct bio_bio_st *b1, *b2;
assert(bio1 != NULL);
assert(bio2 != NULL);
b1 = bio1->ptr;
b2 = bio2->ptr;
if (b1->peer != NULL || b2->peer != NULL)
{
BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
return 0;
}
if (b1->buf == NULL)
{
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL)
{
BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
return 0;
}
b1->len = 0;
b1->offset = 0;
}
if (b2->buf == NULL)
{
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL)
{
BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
return 0;
}
b2->len = 0;
b2->offset = 0;
}
b1->peer = bio2;
b1->closed = 0;
b1->request = 0;
b2->peer = bio1;
b2->closed = 0;
b2->request = 0;
bio1->init = 1;
bio2->init = 1;
return 1;
}
static void bio_destroy_pair(BIO *bio)
{
struct bio_bio_st *b = bio->ptr;
if (b != NULL)
{
BIO *peer_bio = b->peer;
if (peer_bio != NULL)
{
struct bio_bio_st *peer_b = peer_bio->ptr;
assert(peer_b != NULL);
assert(peer_b->peer == bio);
peer_b->peer = NULL;
peer_bio->init = 0;
assert(peer_b->buf != NULL);
peer_b->len = 0;
peer_b->offset = 0;
b->peer = NULL;
bio->init = 0;
assert(b->buf != NULL);
b->len = 0;
b->offset = 0;
}
}
}
/* Exported convenience functions */
int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
BIO **bio2_p, size_t writebuf2)
{
BIO *bio1 = NULL, *bio2 = NULL;
long r;
int ret = 0;
bio1 = BIO_new(BIO_s_bio());
if (bio1 == NULL)
goto err;
bio2 = BIO_new(BIO_s_bio());
if (bio2 == NULL)
goto err;
if (writebuf1)
{
r = BIO_set_write_buf_size(bio1, writebuf1);
if (!r)
goto err;
}
if (writebuf2)
{
r = BIO_set_write_buf_size(bio2, writebuf2);
if (!r)
goto err;
}
r = BIO_make_bio_pair(bio1, bio2);
if (!r)
goto err;
ret = 1;
err:
if (ret == 0)
{
if (bio1)
{
BIO_free(bio1);
bio1 = NULL;
}
if (bio2)
{
BIO_free(bio2);
bio2 = NULL;
}
}
*bio1_p = bio1;
*bio2_p = bio2;
return ret;
}
size_t BIO_ctrl_get_write_guarantee(BIO *bio)
{
return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
}
size_t BIO_ctrl_get_read_request(BIO *bio)
{
return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
}
int BIO_ctrl_reset_read_request(BIO *bio)
{
return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
}
/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
* (conceivably some other BIOs could allow non-copying reads and writes too.)
*/
int BIO_nread0(BIO *bio, char **buf)
{
long ret;
if (!bio->init)
{
BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
return -2;
}
ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
if (ret > INT_MAX)
return INT_MAX;
else
return (int) ret;
}
int BIO_nread(BIO *bio, char **buf, int num)
{
int ret;
if (!bio->init)
{
BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
return -2;
}
ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
if (ret > 0)
bio->num_read += ret;
return ret;
}
int BIO_nwrite0(BIO *bio, char **buf)
{
long ret;
if (!bio->init)
{
BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
return -2;
}
ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
if (ret > INT_MAX)
return INT_MAX;
else
return (int) ret;
}
int BIO_nwrite(BIO *bio, char **buf, int num)
{
int ret;
if (!bio->init)
{
BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
return -2;
}
ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
if (ret > 0)
bio->num_write += ret;
return ret;
}

View File

@@ -0,0 +1,652 @@
/* crypto/bio/bss_conn.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#define USE_SOCKETS
#include "cryptlib.h"
#include <openssl/bio.h>
#ifndef OPENSSL_NO_SOCK
#ifdef OPENSSL_SYS_WIN16
#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
#else
#define SOCKET_PROTOCOL IPPROTO_TCP
#endif
#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
#undef FIONBIO
#endif
typedef struct bio_connect_st
{
int state;
char *param_hostname;
char *param_port;
int nbio;
unsigned char ip[4];
unsigned short port;
struct sockaddr_in them;
/* int socket; this will be kept in bio->num so that it is
* compatible with the bss_sock bio */
/* called when the connection is initially made
* callback(BIO,state,ret); The callback should return
* 'ret'. state is for compatibility with the ssl info_callback */
int (*info_callback)(const BIO *bio,int state,int ret);
} BIO_CONNECT;
static int conn_write(BIO *h, const char *buf, int num);
static int conn_read(BIO *h, char *buf, int size);
static int conn_puts(BIO *h, const char *str);
static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int conn_new(BIO *h);
static int conn_free(BIO *data);
static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
static int conn_state(BIO *b, BIO_CONNECT *c);
static void conn_close_socket(BIO *data);
BIO_CONNECT *BIO_CONNECT_new(void );
void BIO_CONNECT_free(BIO_CONNECT *a);
static BIO_METHOD methods_connectp=
{
BIO_TYPE_CONNECT,
"socket connect",
conn_write,
conn_read,
conn_puts,
NULL, /* connect_gets, */
conn_ctrl,
conn_new,
conn_free,
conn_callback_ctrl,
};
static int conn_state(BIO *b, BIO_CONNECT *c)
{
int ret= -1,i;
unsigned long l;
char *p,*q;
int (*cb)(const BIO *,int,int)=NULL;
if (c->info_callback != NULL)
cb=c->info_callback;
for (;;)
{
switch (c->state)
{
case BIO_CONN_S_BEFORE:
p=c->param_hostname;
if (p == NULL)
{
BIOerr(BIO_F_CONN_STATE,BIO_R_NO_HOSTNAME_SPECIFIED);
goto exit_loop;
}
for ( ; *p != '\0'; p++)
{
if ((*p == ':') || (*p == '/')) break;
}
i= *p;
if ((i == ':') || (i == '/'))
{
*(p++)='\0';
if (i == ':')
{
for (q=p; *q; q++)
if (*q == '/')
{
*q='\0';
break;
}
if (c->param_port != NULL)
OPENSSL_free(c->param_port);
c->param_port=BUF_strdup(p);
}
}
if (c->param_port == NULL)
{
BIOerr(BIO_F_CONN_STATE,BIO_R_NO_PORT_SPECIFIED);
ERR_add_error_data(2,"host=",c->param_hostname);
goto exit_loop;
}
c->state=BIO_CONN_S_GET_IP;
break;
case BIO_CONN_S_GET_IP:
if (BIO_get_host_ip(c->param_hostname,&(c->ip[0])) <= 0)
goto exit_loop;
c->state=BIO_CONN_S_GET_PORT;
break;
case BIO_CONN_S_GET_PORT:
if (c->param_port == NULL)
{
/* abort(); */
goto exit_loop;
}
else if (BIO_get_port(c->param_port,&c->port) <= 0)
goto exit_loop;
c->state=BIO_CONN_S_CREATE_SOCKET;
break;
case BIO_CONN_S_CREATE_SOCKET:
/* now setup address */
memset((char *)&c->them,0,sizeof(c->them));
c->them.sin_family=AF_INET;
c->them.sin_port=htons((unsigned short)c->port);
l=(unsigned long)
((unsigned long)c->ip[0]<<24L)|
((unsigned long)c->ip[1]<<16L)|
((unsigned long)c->ip[2]<< 8L)|
((unsigned long)c->ip[3]);
c->them.sin_addr.s_addr=htonl(l);
c->state=BIO_CONN_S_CREATE_SOCKET;
ret=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
if (ret == INVALID_SOCKET)
{
SYSerr(SYS_F_SOCKET,get_last_socket_error());
ERR_add_error_data(4,"host=",c->param_hostname,
":",c->param_port);
BIOerr(BIO_F_CONN_STATE,BIO_R_UNABLE_TO_CREATE_SOCKET);
goto exit_loop;
}
b->num=ret;
c->state=BIO_CONN_S_NBIO;
break;
case BIO_CONN_S_NBIO:
if (c->nbio)
{
if (!BIO_socket_nbio(b->num,1))
{
BIOerr(BIO_F_CONN_STATE,BIO_R_ERROR_SETTING_NBIO);
ERR_add_error_data(4,"host=",
c->param_hostname,
":",c->param_port);
goto exit_loop;
}
}
c->state=BIO_CONN_S_CONNECT;
#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
i=1;
i=setsockopt(b->num,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
if (i < 0)
{
SYSerr(SYS_F_SOCKET,get_last_socket_error());
ERR_add_error_data(4,"host=",c->param_hostname,
":",c->param_port);
BIOerr(BIO_F_CONN_STATE,BIO_R_KEEPALIVE);
goto exit_loop;
}
#endif
break;
case BIO_CONN_S_CONNECT:
BIO_clear_retry_flags(b);
ret=connect(b->num,
(struct sockaddr *)&c->them,
sizeof(c->them));
b->retry_reason=0;
if (ret < 0)
{
if (BIO_sock_should_retry(ret))
{
BIO_set_retry_special(b);
c->state=BIO_CONN_S_BLOCKED_CONNECT;
b->retry_reason=BIO_RR_CONNECT;
}
else
{
SYSerr(SYS_F_CONNECT,get_last_socket_error());
ERR_add_error_data(4,"host=",
c->param_hostname,
":",c->param_port);
BIOerr(BIO_F_CONN_STATE,BIO_R_CONNECT_ERROR);
}
goto exit_loop;
}
else
c->state=BIO_CONN_S_OK;
break;
case BIO_CONN_S_BLOCKED_CONNECT:
i=BIO_sock_error(b->num);
if (i)
{
BIO_clear_retry_flags(b);
SYSerr(SYS_F_CONNECT,i);
ERR_add_error_data(4,"host=",
c->param_hostname,
":",c->param_port);
BIOerr(BIO_F_CONN_STATE,BIO_R_NBIO_CONNECT_ERROR);
ret=0;
goto exit_loop;
}
else
c->state=BIO_CONN_S_OK;
break;
case BIO_CONN_S_OK:
ret=1;
goto exit_loop;
default:
/* abort(); */
goto exit_loop;
}
if (cb != NULL)
{
if (!(ret=cb((BIO *)b,c->state,ret)))
goto end;
}
}
/* Loop does not exit */
exit_loop:
if (cb != NULL)
ret=cb((BIO *)b,c->state,ret);
end:
return(ret);
}
BIO_CONNECT *BIO_CONNECT_new(void)
{
BIO_CONNECT *ret;
if ((ret=(BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL)
return(NULL);
ret->state=BIO_CONN_S_BEFORE;
ret->param_hostname=NULL;
ret->param_port=NULL;
ret->info_callback=NULL;
ret->nbio=0;
ret->ip[0]=0;
ret->ip[1]=0;
ret->ip[2]=0;
ret->ip[3]=0;
ret->port=0;
memset((char *)&ret->them,0,sizeof(ret->them));
return(ret);
}
void BIO_CONNECT_free(BIO_CONNECT *a)
{
if(a == NULL)
return;
if (a->param_hostname != NULL)
OPENSSL_free(a->param_hostname);
if (a->param_port != NULL)
OPENSSL_free(a->param_port);
OPENSSL_free(a);
}
BIO_METHOD *BIO_s_connect(void)
{
return(&methods_connectp);
}
static int conn_new(BIO *bi)
{
bi->init=0;
bi->num=INVALID_SOCKET;
bi->flags=0;
if ((bi->ptr=(char *)BIO_CONNECT_new()) == NULL)
return(0);
else
return(1);
}
static void conn_close_socket(BIO *bio)
{
BIO_CONNECT *c;
c=(BIO_CONNECT *)bio->ptr;
if (bio->num != INVALID_SOCKET)
{
/* Only do a shutdown if things were established */
if (c->state == BIO_CONN_S_OK)
shutdown(bio->num,2);
closesocket(bio->num);
bio->num=INVALID_SOCKET;
}
}
static int conn_free(BIO *a)
{
BIO_CONNECT *data;
if (a == NULL) return(0);
data=(BIO_CONNECT *)a->ptr;
if (a->shutdown)
{
conn_close_socket(a);
BIO_CONNECT_free(data);
a->ptr=NULL;
a->flags=0;
a->init=0;
}
return(1);
}
static int conn_read(BIO *b, char *out, int outl)
{
int ret=0;
BIO_CONNECT *data;
data=(BIO_CONNECT *)b->ptr;
if (data->state != BIO_CONN_S_OK)
{
ret=conn_state(b,data);
if (ret <= 0)
return(ret);
}
if (out != NULL)
{
clear_socket_error();
ret=readsocket(b->num,out,outl);
BIO_clear_retry_flags(b);
if (ret <= 0)
{
if (BIO_sock_should_retry(ret))
BIO_set_retry_read(b);
}
}
return(ret);
}
static int conn_write(BIO *b, const char *in, int inl)
{
int ret;
BIO_CONNECT *data;
data=(BIO_CONNECT *)b->ptr;
if (data->state != BIO_CONN_S_OK)
{
ret=conn_state(b,data);
if (ret <= 0) return(ret);
}
clear_socket_error();
ret=writesocket(b->num,in,inl);
BIO_clear_retry_flags(b);
if (ret <= 0)
{
if (BIO_sock_should_retry(ret))
BIO_set_retry_write(b);
}
return(ret);
}
static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BIO *dbio;
int *ip;
const char **pptr;
long ret=1;
BIO_CONNECT *data;
data=(BIO_CONNECT *)b->ptr;
switch (cmd)
{
case BIO_CTRL_RESET:
ret=0;
data->state=BIO_CONN_S_BEFORE;
conn_close_socket(b);
b->flags=0;
break;
case BIO_C_DO_STATE_MACHINE:
/* use this one to start the connection */
if (data->state != BIO_CONN_S_OK)
ret=(long)conn_state(b,data);
else
ret=1;
break;
case BIO_C_GET_CONNECT:
if (ptr != NULL)
{
pptr=(const char **)ptr;
if (num == 0)
{
*pptr=data->param_hostname;
}
else if (num == 1)
{
*pptr=data->param_port;
}
else if (num == 2)
{
*pptr= (char *)&(data->ip[0]);
}
else if (num == 3)
{
*((int *)ptr)=data->port;
}
if ((!b->init) || (ptr == NULL))
*pptr="not initialized";
ret=1;
}
break;
case BIO_C_SET_CONNECT:
if (ptr != NULL)
{
b->init=1;
if (num == 0)
{
if (data->param_hostname != NULL)
OPENSSL_free(data->param_hostname);
data->param_hostname=BUF_strdup(ptr);
}
else if (num == 1)
{
if (data->param_port != NULL)
OPENSSL_free(data->param_port);
data->param_port=BUF_strdup(ptr);
}
else if (num == 2)
{
char buf[16];
unsigned char *p = ptr;
BIO_snprintf(buf,sizeof buf,"%d.%d.%d.%d",
p[0],p[1],p[2],p[3]);
if (data->param_hostname != NULL)
OPENSSL_free(data->param_hostname);
data->param_hostname=BUF_strdup(buf);
memcpy(&(data->ip[0]),ptr,4);
}
else if (num == 3)
{
char buf[DECIMAL_SIZE(int)+1];
BIO_snprintf(buf,sizeof buf,"%d",*(int *)ptr);
if (data->param_port != NULL)
OPENSSL_free(data->param_port);
data->param_port=BUF_strdup(buf);
data->port= *(int *)ptr;
}
}
break;
case BIO_C_SET_NBIO:
data->nbio=(int)num;
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_FLUSH:
break;
case BIO_CTRL_DUP:
{
dbio=(BIO *)ptr;
if (data->param_port)
BIO_set_conn_port(dbio,data->param_port);
if (data->param_hostname)
BIO_set_conn_hostname(dbio,data->param_hostname);
BIO_set_nbio(dbio,data->nbio);
/* FIXME: the cast of the function seems unlikely to be a good idea */
(void)BIO_set_info_callback(dbio,(bio_info_cb *)data->info_callback);
}
break;
case BIO_CTRL_SET_CALLBACK:
{
#if 0 /* FIXME: Should this be used? -- Richard Levitte */
BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
ret = -1;
#else
ret=0;
#endif
}
break;
case BIO_CTRL_GET_CALLBACK:
{
int (**fptr)(const BIO *bio,int state,int xret);
fptr=(int (**)(const BIO *bio,int state,int xret))ptr;
*fptr=data->info_callback;
}
break;
default:
ret=0;
break;
}
return(ret);
}
static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret=1;
BIO_CONNECT *data;
data=(BIO_CONNECT *)b->ptr;
switch (cmd)
{
case BIO_CTRL_SET_CALLBACK:
{
data->info_callback=(int (*)(const struct bio_st *, int, int))fp;
}
break;
default:
ret=0;
break;
}
return(ret);
}
static int conn_puts(BIO *bp, const char *str)
{
int n,ret;
n=strlen(str);
ret=conn_write(bp,str,n);
return(ret);
}
BIO *BIO_new_connect(char *str)
{
BIO *ret;
ret=BIO_new(BIO_s_connect());
if (ret == NULL) return(NULL);
if (BIO_set_conn_hostname(ret,str))
return(ret);
else
{
BIO_free(ret);
return(NULL);
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,319 @@
/* crypto/bio/bss_fd.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#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
* 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);
int BIO_fd_should_retry(int s);
static BIO_METHOD methods_fdp=
{
BIO_TYPE_FD,"file descriptor",
fd_write,
fd_read,
fd_puts,
fd_gets,
fd_ctrl,
fd_new,
fd_free,
NULL,
};
BIO_METHOD *BIO_s_fd(void)
{
return(&methods_fdp);
}
BIO *BIO_new_fd(int fd,int close_flag)
{
BIO *ret;
ret=BIO_new(BIO_s_fd());
if (ret == NULL) return(NULL);
BIO_set_fd(ret,fd,close_flag);
return(ret);
}
static int fd_new(BIO *bi)
{
bi->init=0;
bi->num=-1;
bi->ptr=NULL;
bi->flags=BIO_FLAGS_UPLINK; /* essentially redundant */
return(1);
}
static int fd_free(BIO *a)
{
if (a == NULL) return(0);
if (a->shutdown)
{
if (a->init)
{
UP_close(a->num);
}
a->init=0;
a->flags=BIO_FLAGS_UPLINK;
}
return(1);
}
static int fd_read(BIO *b, char *out,int outl)
{
int ret=0;
if (out != NULL)
{
clear_sys_error();
ret=UP_read(b->num,out,outl);
BIO_clear_retry_flags(b);
if (ret <= 0)
{
if (BIO_fd_should_retry(ret))
BIO_set_retry_read(b);
}
}
return(ret);
}
static int fd_write(BIO *b, const char *in, int inl)
{
int ret;
clear_sys_error();
ret=UP_write(b->num,in,inl);
BIO_clear_retry_flags(b);
if (ret <= 0)
{
if (BIO_fd_should_retry(ret))
BIO_set_retry_write(b);
}
return(ret);
}
static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret=1;
int *ip;
switch (cmd)
{
case BIO_CTRL_RESET:
num=0;
case BIO_C_FILE_SEEK:
ret=(long)UP_lseek(b->num,num,0);
break;
case BIO_C_FILE_TELL:
case BIO_CTRL_INFO:
ret=(long)UP_lseek(b->num,0,1);
break;
case BIO_C_SET_FD:
fd_free(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;
default:
ret=0;
break;
}
return(ret);
}
static int fd_puts(BIO *bp, const char *str)
{
int n,ret;
n=strlen(str);
ret=fd_write(bp,str,n);
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;
if ((i == 0) || (i == -1))
{
err=get_last_sys_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_fd_non_fatal_error(err));
}
return(0);
}
int BIO_fd_non_fatal_error(int err)
{
switch (err)
{
#ifdef EWOULDBLOCK
# ifdef WSAEWOULDBLOCK
# if WSAEWOULDBLOCK != EWOULDBLOCK
case EWOULDBLOCK:
# endif
# else
case EWOULDBLOCK:
# endif
#endif
#if defined(ENOTCONN)
case ENOTCONN:
#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

View File

@@ -0,0 +1,477 @@
/* crypto/bio/bss_file.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/*
* 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout
* with binary data (e.g. asn1parse -inform DER < xxx) under
* Windows
*/
#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 "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);
static int MS_CALLBACK file_read(BIO *h, char *buf, int size);
static int MS_CALLBACK file_puts(BIO *h, const char *str);
static int MS_CALLBACK file_gets(BIO *h, char *str, int size);
static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int MS_CALLBACK file_new(BIO *h);
static int MS_CALLBACK file_free(BIO *data);
static BIO_METHOD methods_filep=
{
BIO_TYPE_FILE,
"FILE pointer",
file_write,
file_read,
file_puts,
file_gets,
file_ctrl,
file_new,
file_free,
NULL,
};
BIO *BIO_new_file(const char *filename, const char *mode)
{
BIO *ret;
FILE *file=NULL;
#if defined(_WIN32) && defined(CP_UTF8)
int sz, len_0 = (int)strlen(filename)+1;
DWORD flags;
/*
* 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,(flags=MB_ERR_INVALID_CHARS),
filename,len_0,NULL,0))>0 ||
(GetLastError()==ERROR_INVALID_FLAGS &&
(sz=MultiByteToWideChar(CP_UTF8,(flags=0),
filename,len_0,NULL,0))>0)
)
{
WCHAR wmode[8];
WCHAR *wfilename = _alloca(sz*sizeof(WCHAR));
if (MultiByteToWideChar(CP_UTF8,flags,
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 || errno==EBADF)
) /* 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,"')");
if (errno == ENOENT)
BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
else
BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
return(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);
}
BIO *BIO_new_fp(FILE *stream, int close_flag)
{
BIO *ret;
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);
}
BIO_METHOD *BIO_s_file(void)
{
return(&methods_filep);
}
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);
}
static int MS_CALLBACK file_free(BIO *a)
{
if (a == NULL) return(0);
if (a->shutdown)
{
if ((a->init) && (a->ptr != NULL))
{
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;
}
return(1);
}
static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
{
int ret=0;
if (b->init && (out != NULL))
{
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);
ret=-1;
}
}
return(ret);
}
static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
{
int ret=0;
if (b->init && (in != NULL))
{
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
* out version above can cause 'inl' write calls under
* some stupid stdio implementations (VMS) */
}
return(ret);
}
static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret=1;
FILE *fp=(FILE *)b->ptr;
FILE **fpp;
char p[4];
switch (cmd)
{
case BIO_C_FILE_SEEK:
case BIO_CTRL_RESET:
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:
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:
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=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_fsetmod
if (b->flags&BIO_FLAGS_UPLINK)
UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b'));
else
#endif
{
#if defined(OPENSSL_SYS_WINDOWS)
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 */
if (num & BIO_FP_TEXT)
setmode(fd,O_TEXT);
else
setmode(fd,O_BINARY);
#elif defined(OPENSSL_SYS_MSDOS)
int fd = fileno((FILE*)ptr);
/* Set correct text/binary mode */
if (num & BIO_FP_TEXT)
_setmode(fd,_O_TEXT);
/* Dangerous to set stdin/stdout to raw (unless redirected) */
else
{
if (fd == STDIN_FILENO || fd == STDOUT_FILENO)
{
if (isatty(fd) <= 0)
_setmode(fd,_O_BINARY);
}
else
_setmode(fd,_O_BINARY);
}
#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
int fd = fileno((FILE*)ptr);
if (num & BIO_FP_TEXT)
setmode(fd, O_TEXT);
else
setmode(fd, O_BINARY);
#endif
}
break;
case BIO_C_SET_FILENAME:
file_free(b);
b->shutdown=(int)num&BIO_CLOSE;
if (num & BIO_FP_APPEND)
{
if (num & BIO_FP_READ)
BUF_strlcpy(p,"a+",sizeof p);
else BUF_strlcpy(p,"a",sizeof p);
}
else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
BUF_strlcpy(p,"r+",sizeof p);
else if (num & BIO_FP_WRITE)
BUF_strlcpy(p,"w",sizeof p);
else if (num & BIO_FP_READ)
BUF_strlcpy(p,"r",sizeof p);
else
{
BIOerr(BIO_F_FILE_CTRL,BIO_R_BAD_FOPEN_MODE);
ret=0;
break;
}
#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
if (!(num & BIO_FP_TEXT))
strcat(p,"b");
else
strcat(p,"t");
#endif
#if defined(OPENSSL_SYS_NETWARE)
if (!(num & BIO_FP_TEXT))
strcat(p,"b");
else
strcat(p,"t");
#endif
fp=fopen(ptr,p);
if (fp == NULL)
{
SYSerr(SYS_F_FOPEN,get_last_sys_error());
ERR_add_error_data(5,"fopen('",ptr,"','",p,"')");
BIOerr(BIO_F_FILE_CTRL,ERR_R_SYS_LIB);
ret=0;
break;
}
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. */
if (ptr != NULL)
{
fpp=(FILE **)ptr;
*fpp=(FILE *)b->ptr;
}
break;
case BIO_CTRL_GET_CLOSE:
ret=(long)b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown=(int)num;
break;
case BIO_CTRL_FLUSH:
if (b->flags&BIO_FLAGS_UPLINK)
UP_fflush(b->ptr);
else
fflush((FILE *)b->ptr);
break;
case BIO_CTRL_DUP:
ret=1;
break;
case BIO_CTRL_WPENDING:
case BIO_CTRL_PENDING:
case BIO_CTRL_PUSH:
case BIO_CTRL_POP:
default:
ret=0;
break;
}
return(ret);
}
static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
{
int ret=0;
buf[0]='\0';
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);
}
static int MS_CALLBACK file_puts(BIO *bp, const char *str)
{
int n,ret;
n=strlen(str);
ret=file_write(bp,str,n);
return(ret);
}
#endif /* OPENSSL_NO_STDIO */
#endif /* HEADER_BSS_FILE_C */

View File

@@ -0,0 +1,399 @@
/* crypto/bio/bss_log.c */
/* ====================================================================
* Copyright (c) 1999 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
* licensing@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).
*
*/
/*
Why BIO_s_log?
BIO_s_log is useful for system daemons (or services under NT).
It is one-way BIO, it sends all stuff to syslogd (on system that
commonly use that), or event log (on NT), or OPCOM (on OpenVMS).
*/
#include <stdio.h>
#include <errno.h>
#include "cryptlib.h"
#if defined(OPENSSL_SYS_WINCE)
#elif defined(OPENSSL_SYS_WIN32)
#elif defined(OPENSSL_SYS_VMS)
# include <opcdef.h>
# include <descrip.h>
# include <lib$routines.h>
# include <starlet.h>
/* Some compiler options may mask the declaration of "_malloc32". */
# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
# if __INITIAL_POINTER_SIZE == 64
# pragma pointer_size save
# pragma pointer_size 32
void * _malloc32 (__size_t);
# pragma pointer_size restore
# endif /* __INITIAL_POINTER_SIZE == 64 */
# endif /* __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE */
#elif defined(__ultrix)
# include <sys/syslog.h>
#elif defined(OPENSSL_SYS_NETWARE)
# define NO_SYSLOG
#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
# include <syslog.h>
#endif
#include <openssl/buffer.h>
#include <openssl/err.h>
#ifndef NO_SYSLOG
#if defined(OPENSSL_SYS_WIN32)
#define LOG_EMERG 0
#define LOG_ALERT 1
#define LOG_CRIT 2
#define LOG_ERR 3
#define LOG_WARNING 4
#define LOG_NOTICE 5
#define LOG_INFO 6
#define LOG_DEBUG 7
#define LOG_DAEMON (3<<3)
#elif defined(OPENSSL_SYS_VMS)
/* On VMS, we don't really care about these, but we need them to compile */
#define LOG_EMERG 0
#define LOG_ALERT 1
#define LOG_CRIT 2
#define LOG_ERR 3
#define LOG_WARNING 4
#define LOG_NOTICE 5
#define LOG_INFO 6
#define LOG_DEBUG 7
#define LOG_DAEMON OPC$M_NM_NTWORK
#endif
static int MS_CALLBACK slg_write(BIO *h, const char *buf, int num);
static int MS_CALLBACK slg_puts(BIO *h, const char *str);
static long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int MS_CALLBACK slg_new(BIO *h);
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);
static BIO_METHOD methods_slg=
{
BIO_TYPE_MEM,"syslog",
slg_write,
NULL,
slg_puts,
NULL,
slg_ctrl,
slg_new,
slg_free,
NULL,
};
BIO_METHOD *BIO_s_log(void)
{
return(&methods_slg);
}
static int MS_CALLBACK slg_new(BIO *bi)
{
bi->init=1;
bi->num=0;
bi->ptr=NULL;
xopenlog(bi, "application", LOG_DAEMON);
return(1);
}
static int MS_CALLBACK slg_free(BIO *a)
{
if (a == NULL) return(0);
xcloselog(a);
return(1);
}
static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl)
{
int ret= inl;
char* buf;
char* pp;
int priority, i;
static const struct
{
int strl;
char str[10];
int log_level;
}
mapping[] =
{
{ 6, "PANIC ", LOG_EMERG },
{ 6, "EMERG ", LOG_EMERG },
{ 4, "EMR ", LOG_EMERG },
{ 6, "ALERT ", LOG_ALERT },
{ 4, "ALR ", LOG_ALERT },
{ 5, "CRIT ", LOG_CRIT },
{ 4, "CRI ", LOG_CRIT },
{ 6, "ERROR ", LOG_ERR },
{ 4, "ERR ", LOG_ERR },
{ 8, "WARNING ", LOG_WARNING },
{ 5, "WARN ", LOG_WARNING },
{ 4, "WAR ", LOG_WARNING },
{ 7, "NOTICE ", LOG_NOTICE },
{ 5, "NOTE ", LOG_NOTICE },
{ 4, "NOT ", LOG_NOTICE },
{ 5, "INFO ", LOG_INFO },
{ 4, "INF ", LOG_INFO },
{ 6, "DEBUG ", LOG_DEBUG },
{ 4, "DBG ", LOG_DEBUG },
{ 0, "", LOG_ERR } /* The default */
};
if((buf= (char *)OPENSSL_malloc(inl+ 1)) == NULL){
return(0);
}
strncpy(buf, in, inl);
buf[inl]= '\0';
i = 0;
while(strncmp(buf, mapping[i].str, mapping[i].strl) != 0) i++;
priority = mapping[i].log_level;
pp = buf + mapping[i].strl;
xsyslog(b, priority, pp);
OPENSSL_free(buf);
return(ret);
}
static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr)
{
switch (cmd)
{
case BIO_CTRL_SET:
xcloselog(b);
xopenlog(b, ptr, num);
break;
default:
break;
}
return(0);
}
static int MS_CALLBACK slg_puts(BIO *bp, const char *str)
{
int n,ret;
n=strlen(str);
ret=slg_write(bp,str,n);
return(ret);
}
#if defined(OPENSSL_SYS_WIN32)
static void xopenlog(BIO* bp, char* name, int level)
{
if (check_winnt())
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;
char pidbuf[DECIMAL_SIZE(DWORD)+4];
if (bp->ptr == NULL)
return;
switch (priority)
{
case LOG_EMERG:
case LOG_ALERT:
case LOG_CRIT:
case LOG_ERR:
evtype = EVENTLOG_ERROR_TYPE;
break;
case LOG_WARNING:
evtype = EVENTLOG_WARNING_TYPE;
break;
case LOG_NOTICE:
case LOG_INFO:
case LOG_DEBUG:
evtype = EVENTLOG_INFORMATION_TYPE;
break;
default: /* Should never happen, but set it
as error anyway. */
evtype = EVENTLOG_ERROR_TYPE;
break;
}
sprintf(pidbuf, "[%u] ", GetCurrentProcessId());
lpszStrings[0] = pidbuf;
lpszStrings[1] = string;
ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0,
lpszStrings, NULL);
}
static void xcloselog(BIO* bp)
{
if(bp->ptr)
DeregisterEventSource((HANDLE)(bp->ptr));
bp->ptr= NULL;
}
#elif defined(OPENSSL_SYS_VMS)
static int VMS_OPC_target = LOG_DAEMON;
static void xopenlog(BIO* bp, char* name, int level)
{
VMS_OPC_target = level;
}
static void xsyslog(BIO *bp, int priority, const char *string)
{
struct dsc$descriptor_s opc_dsc;
/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
#if __INITIAL_POINTER_SIZE == 64
# pragma pointer_size save
# pragma pointer_size 32
# define OPCDEF_TYPE __char_ptr32
# define OPCDEF_MALLOC _malloc32
#else /* __INITIAL_POINTER_SIZE == 64 */
# define OPCDEF_TYPE char *
# define OPCDEF_MALLOC OPENSSL_malloc
#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
struct opcdef *opcdef_p;
#if __INITIAL_POINTER_SIZE == 64
# pragma pointer_size restore
#endif /* __INITIAL_POINTER_SIZE == 64 */
char buf[10240];
unsigned int len;
struct dsc$descriptor_s buf_dsc;
$DESCRIPTOR(fao_cmd, "!AZ: !AZ");
char *priority_tag;
switch (priority)
{
case LOG_EMERG: priority_tag = "Emergency"; break;
case LOG_ALERT: priority_tag = "Alert"; break;
case LOG_CRIT: priority_tag = "Critical"; break;
case LOG_ERR: priority_tag = "Error"; break;
case LOG_WARNING: priority_tag = "Warning"; break;
case LOG_NOTICE: priority_tag = "Notice"; break;
case LOG_INFO: priority_tag = "Info"; break;
case LOG_DEBUG: priority_tag = "DEBUG"; break;
}
buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
buf_dsc.dsc$b_class = DSC$K_CLASS_S;
buf_dsc.dsc$a_pointer = buf;
buf_dsc.dsc$w_length = sizeof(buf) - 1;
lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
/* We know there's an 8-byte header. That's documented. */
opcdef_p = OPCDEF_MALLOC( 8+ len);
opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
opcdef_p->opc$l_ms_rqstid = 0;
memcpy(&opcdef_p->opc$l_ms_text, buf, len);
opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
opc_dsc.dsc$b_class = DSC$K_CLASS_S;
opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
opc_dsc.dsc$w_length = len + 8;
sys$sndopr(opc_dsc, 0);
OPENSSL_free(opcdef_p);
}
static void xcloselog(BIO* bp)
{
}
#else /* Unix/Watt32 */
static void xopenlog(BIO* bp, char* name, int level)
{
#ifdef WATT32 /* djgpp/DOS */
openlog(name, LOG_PID|LOG_CONS|LOG_NDELAY, level);
#else
openlog(name, LOG_PID|LOG_CONS, level);
#endif
}
static void xsyslog(BIO *bp, int priority, const char *string)
{
syslog(priority, "%s", string);
}
static void xcloselog(BIO* bp)
{
closelog();
}
#endif /* Unix */
#endif /* NO_SYSLOG */

View File

@@ -0,0 +1,319 @@
/* crypto/bio/bss_mem.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#include "cryptlib.h"
#include <openssl/bio.h>
static int mem_write(BIO *h, const char *buf, int num);
static int mem_read(BIO *h, char *buf, int size);
static int mem_puts(BIO *h, const char *str);
static int mem_gets(BIO *h, char *str, int size);
static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int mem_new(BIO *h);
static int mem_free(BIO *data);
static BIO_METHOD mem_method=
{
BIO_TYPE_MEM,
"memory buffer",
mem_write,
mem_read,
mem_puts,
mem_gets,
mem_ctrl,
mem_new,
mem_free,
NULL,
};
/* bio->num is used to hold the value to return on 'empty', if it is
* 0, should_retry is not set */
BIO_METHOD *BIO_s_mem(void)
{
return(&mem_method);
}
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;
}
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 = sz;
b->max = sz;
ret->flags |= BIO_FLAGS_MEM_RDONLY;
/* Since this is static data retrying wont help */
ret->num = 0;
return ret;
}
static int mem_new(BIO *bi)
{
BUF_MEM *b;
if ((b=BUF_MEM_new()) == NULL)
return(0);
bi->shutdown=1;
bi->init=1;
bi->num= -1;
bi->ptr=(char *)b;
return(1);
}
static int mem_free(BIO *a)
{
if (a == NULL) return(0);
if (a->shutdown)
{
if ((a->init) && (a->ptr != NULL))
{
BUF_MEM *b;
b = (BUF_MEM *)a->ptr;
if(a->flags & BIO_FLAGS_MEM_RDONLY) b->data = NULL;
BUF_MEM_free(b);
a->ptr=NULL;
}
}
return(1);
}
static int mem_read(BIO *b, char *out, int outl)
{
int ret= -1;
BUF_MEM *bm;
bm=(BUF_MEM *)b->ptr;
BIO_clear_retry_flags(b);
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;
if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret;
else {
memmove(&(bm->data[0]),&(bm->data[ret]),bm->length);
}
} else if (bm->length == 0)
{
ret = b->num;
if (ret != 0)
BIO_set_retry_read(b);
}
return(ret);
}
static int mem_write(BIO *b, const char *in, int inl)
{
int ret= -1;
int blen;
BUF_MEM *bm;
bm=(BUF_MEM *)b->ptr;
if (in == NULL)
{
BIOerr(BIO_F_MEM_WRITE,BIO_R_NULL_PARAMETER);
goto end;
}
if(b->flags & BIO_FLAGS_MEM_RDONLY) {
BIOerr(BIO_F_MEM_WRITE,BIO_R_WRITE_TO_READ_ONLY_BIO);
goto end;
}
BIO_clear_retry_flags(b);
blen=bm->length;
if (BUF_MEM_grow_clean(bm,blen+inl) != (blen+inl))
goto end;
memcpy(&(bm->data[blen]),in,inl);
ret=inl;
end:
return(ret);
}
static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret=1;
char **pptr;
BUF_MEM *bm=(BUF_MEM *)b->ptr;
switch (cmd)
{
case BIO_CTRL_RESET:
if (bm->data != NULL)
{
/* For read only case reset to the start again */
if(b->flags & BIO_FLAGS_MEM_RDONLY)
{
bm->data -= bm->max - bm->length;
bm->length = bm->max;
}
else
{
memset(bm->data,0,bm->max);
bm->length=0;
}
}
break;
case BIO_CTRL_EOF:
ret=(long)(bm->length == 0);
break;
case BIO_C_SET_BUF_MEM_EOF_RETURN:
b->num=(int)num;
break;
case BIO_CTRL_INFO:
ret=(long)bm->length;
if (ptr != NULL)
{
pptr=(char **)ptr;
*pptr=(char *)&(bm->data[0]);
}
break;
case BIO_C_SET_BUF_MEM:
mem_free(b);
b->shutdown=(int)num;
b->ptr=ptr;
break;
case BIO_C_GET_BUF_MEM_PTR:
if (ptr != NULL)
{
pptr=(char **)ptr;
*pptr=(char *)bm;
}
break;
case BIO_CTRL_GET_CLOSE:
ret=(long)b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown=(int)num;
break;
case BIO_CTRL_WPENDING:
ret=0L;
break;
case BIO_CTRL_PENDING:
ret=(long)bm->length;
break;
case BIO_CTRL_DUP:
case BIO_CTRL_FLUSH:
ret=1;
break;
case BIO_CTRL_PUSH:
case BIO_CTRL_POP:
default:
ret=0;
break;
}
return(ret);
}
static int mem_gets(BIO *bp, char *buf, int size)
{
int i,j;
int ret= -1;
char *p;
BUF_MEM *bm=(BUF_MEM *)bp->ptr;
BIO_clear_retry_flags(bp);
j=bm->length;
if ((size-1) < j) j=size-1;
if (j <= 0)
{
*buf='\0';
return 0;
}
p=bm->data;
for (i=0; i<j; i++)
{
if (p[i] == '\n')
{
i++;
break;
}
}
/*
* 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;
return(ret);
}
static int mem_puts(BIO *bp, const char *str)
{
int n,ret;
n=strlen(str);
ret=mem_write(bp,str,n);
/* memory semantics is that it will always work */
return(ret);
}

View File

@@ -0,0 +1,150 @@
/* crypto/bio/bss_null.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#include "cryptlib.h"
#include <openssl/bio.h>
static int null_write(BIO *h, const char *buf, int num);
static int null_read(BIO *h, char *buf, int size);
static int null_puts(BIO *h, const char *str);
static int null_gets(BIO *h, char *str, int size);
static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int null_new(BIO *h);
static int null_free(BIO *data);
static BIO_METHOD null_method=
{
BIO_TYPE_NULL,
"NULL",
null_write,
null_read,
null_puts,
null_gets,
null_ctrl,
null_new,
null_free,
NULL,
};
BIO_METHOD *BIO_s_null(void)
{
return(&null_method);
}
static int null_new(BIO *bi)
{
bi->init=1;
bi->num=0;
bi->ptr=(NULL);
return(1);
}
static int null_free(BIO *a)
{
if (a == NULL) return(0);
return(1);
}
static int null_read(BIO *b, char *out, int outl)
{
return(0);
}
static int null_write(BIO *b, const char *in, int inl)
{
return(inl);
}
static long null_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret=1;
switch (cmd)
{
case BIO_CTRL_RESET:
case BIO_CTRL_EOF:
case BIO_CTRL_SET:
case BIO_CTRL_SET_CLOSE:
case BIO_CTRL_FLUSH:
case BIO_CTRL_DUP:
ret=1;
break;
case BIO_CTRL_GET_CLOSE:
case BIO_CTRL_INFO:
case BIO_CTRL_GET:
case BIO_CTRL_PENDING:
case BIO_CTRL_WPENDING:
default:
ret=0;
break;
}
return(ret);
}
static int null_gets(BIO *bp, char *buf, int size)
{
return(0);
}
static int null_puts(BIO *bp, const char *str)
{
if (str == NULL) return(0);
return(strlen(str));
}

View File

@@ -0,0 +1,294 @@
/* crypto/bio/bss_sock.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#define USE_SOCKETS
#include "cryptlib.h"
#ifndef OPENSSL_NO_SOCK
#include <openssl/bio.h>
#ifdef WATT32
#define sock_write SockWrite /* Watt-32 uses same names */
#define sock_read SockRead
#define sock_puts SockPuts
#endif
static int sock_write(BIO *h, const char *buf, int num);
static int sock_read(BIO *h, char *buf, int size);
static int sock_puts(BIO *h, const char *str);
static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int sock_new(BIO *h);
static int sock_free(BIO *data);
int BIO_sock_should_retry(int s);
static BIO_METHOD methods_sockp=
{
BIO_TYPE_SOCKET,
"socket",
sock_write,
sock_read,
sock_puts,
NULL, /* sock_gets, */
sock_ctrl,
sock_new,
sock_free,
NULL,
};
BIO_METHOD *BIO_s_socket(void)
{
return(&methods_sockp);
}
BIO *BIO_new_socket(int fd, int close_flag)
{
BIO *ret;
ret=BIO_new(BIO_s_socket());
if (ret == NULL) return(NULL);
BIO_set_fd(ret,fd,close_flag);
return(ret);
}
static int sock_new(BIO *bi)
{
bi->init=0;
bi->num=0;
bi->ptr=NULL;
bi->flags=0;
return(1);
}
static int sock_free(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 int sock_read(BIO *b, char *out, int outl)
{
int ret=0;
if (out != NULL)
{
clear_socket_error();
ret=readsocket(b->num,out,outl);
BIO_clear_retry_flags(b);
if (ret <= 0)
{
if (BIO_sock_should_retry(ret))
BIO_set_retry_read(b);
}
}
return(ret);
}
static int sock_write(BIO *b, const char *in, int inl)
{
int ret;
clear_socket_error();
ret=writesocket(b->num,in,inl);
BIO_clear_retry_flags(b);
if (ret <= 0)
{
if (BIO_sock_should_retry(ret))
BIO_set_retry_write(b);
}
return(ret);
}
static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret=1;
int *ip;
switch (cmd)
{
case BIO_C_SET_FD:
sock_free(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_DUP:
case BIO_CTRL_FLUSH:
ret=1;
break;
default:
ret=0;
break;
}
return(ret);
}
static int sock_puts(BIO *bp, const char *str)
{
int n,ret;
n=strlen(str);
ret=sock_write(bp,str,n);
return(ret);
}
int BIO_sock_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_sock_non_fatal_error(err));
}
return(0);
}
int BIO_sock_non_fatal_error(int err)
{
switch (err)
{
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE)
# 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
#if defined(ENOTCONN)
case ENOTCONN:
#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 /* #ifndef OPENSSL_NO_SOCK */