Esempio n. 1
0
int MaOpenSslSocket::initConnection()
{
	BIO		*bioSSL, *bioSock;

	if (bio) {
		return 0;
	}
	bio = BIO_new(BIO_f_buffer());
	if (bio == 0) {
		return MPR_ERR_CANT_INITIALIZE;
	}

	BIO_set_write_buffer_size(bio, 128);
	ssl = (SSL*) SSL_new(context);
	mprAssert(ssl);
	if (ssl == 0) {
		return MPR_ERR_CANT_INITIALIZE;
	}
    SSL_set_app_data(ssl, (void*) this);

	SSL_set_session(ssl, 0);
	bioSSL = BIO_new(BIO_f_ssl());
	mprAssert(bioSSL);

	bioSock = BIO_new_socket(sock, BIO_NOCLOSE);
	mprAssert(bioSock);

	SSL_set_bio(ssl, bioSock, bioSock);
	SSL_set_accept_state(ssl);

	BIO_set_ssl(bioSSL, ssl, BIO_CLOSE);
	BIO_push(bio, bioSSL);
	return 0;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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 = malloc(num);
			if (p1 == NULL)
				goto malloc_error;
			free(ctx->ibuf);
			ctx->ibuf = p1;
		}
		ctx->ibuf_off = 0;
		ctx->ibuf_len = (int)num;
		memcpy(ctx->ibuf, ptr, 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 = malloc(num);
			if (p1 == NULL)
				goto malloc_error;
		}
		if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
			p2 = malloc(num);
			if (p2 == NULL) {
				if (p1 != ctx->ibuf)
					free(p1);
				goto malloc_error;
			}
		}
		if (ctx->ibuf != p1) {
			free(ctx->ibuf);
			ctx->ibuf = p1;
			ctx->ibuf_off = 0;
			ctx->ibuf_len = 0;
			ctx->ibuf_size = ibs;
		}
		if (ctx->obuf != p2) {
			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);
				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;
				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:
	BIOerror(ERR_R_MALLOC_FAILURE);
	return (0);
}