Esempio n. 1
0
void    tls_prng_exch_update(TLS_PRNG_SRC *eh)
{
    const char *myname = "tls_prng_exch_update";
    unsigned char buffer[TLS_PRNG_EXCH_SIZE];
    ssize_t count;

    /*
     * Update the PRNG exchange file. Since other processes may have added
     * entropy, we use a read-stir-write cycle.
     */
    if (acl_myflock(eh->fd.file, ACL_INTERNAL_LOCK, ACL_MYFLOCK_OP_EXCLUSIVE) != 0)
	acl_msg_fatal("%s: cannot lock PRNG exchange file %s: %s",
		myname, eh->name, acl_last_serror());
    if (acl_lseek(eh->fd.file, 0, SEEK_SET) < 0)
	acl_msg_fatal("%s: cannot seek PRNG exchange file %s: %s",
		myname, eh->name, acl_last_serror());
    if ((count = acl_file_read(eh->fd.file, buffer, sizeof(buffer), 0, NULL)) < 0)
	acl_msg_fatal("%s: cannot read PRNG exchange file %s: %s",
		myname, eh->name, acl_last_serror());

    if (count > 0)
	RAND_seed(buffer, count);
    RAND_bytes(buffer, sizeof(buffer));

    if (acl_lseek(eh->fd.file, 0, SEEK_SET) < 0)
	acl_msg_fatal("%s: cannot seek PRNG exchange file %s: %s",
		myname, eh->name, acl_last_serror());
    if (acl_file_write(eh->fd.file, buffer, sizeof(buffer), 0, NULL) != sizeof(buffer))
	acl_msg_fatal("%s: cannot write PRNG exchange file %s: %s",
		myname, eh->name, acl_last_serror());
    if (acl_myflock(eh->fd.file, ACL_INTERNAL_LOCK, ACL_MYFLOCK_OP_NONE) != 0)
	acl_msg_fatal("%s: cannot unlock PRNG exchange file %s: %s",
		myname, eh->name, acl_last_serror());
}
Esempio n. 2
0
ssize_t tls_prng_file_read(TLS_PRNG_SRC *fh, size_t len)
{
    const char *myname = "tls_prng_file_read";
    char    buffer[8192];
    ssize_t to_read;
    ssize_t count;

    if (acl_msg_verbose)
	acl_msg_info("%s: seed internal pool from file %s", myname, fh->name);

    if (acl_lseek(fh->fd.file, 0, SEEK_SET) < 0) {
	if (acl_msg_verbose)
	    acl_msg_info("%s: cannot seek entropy file %s: %s",
		myname, fh->name, acl_last_serror());
	return (-1);
    }
    errno = 0;
    for (to_read = (ssize_t) len; to_read > 0; to_read -= count) {
#ifdef ACL_UNIX
		count = acl_timed_read(fh->fd.file, buffer,
				to_read > (ssize_t) sizeof(buffer) ?
				(ssize_t) sizeof(buffer) : to_read,
				fh->timeout, NULL);
#elif defined(WIN32)
		count = acl_file_read(fh->fd.file, buffer,
				to_read > (ssize_t) sizeof(buffer) ?
				(ssize_t) sizeof(buffer) : to_read,
				fh->timeout, NULL);
#endif
		if (count < 0) {
			if (acl_msg_verbose)
				acl_msg_info("%s: cannot read entropy file %s: %s",
					myname, fh->name, acl_last_serror());
			return (-1);
		}
		if (count == 0)
			break;
		RAND_seed(buffer, count);
    }
    if (acl_msg_verbose)
		acl_msg_info("%s: read %ld bytes from entropy file %s: %s",
			myname, (long) (len - to_read), fh->name, acl_last_serror());
    return ((ssize_t) (len - to_read));
}
Esempio n. 3
0
static int vstring_extend(ACL_VBUF *bp, ssize_t incr)
{
	const char *myname = "vstring_extend";
	ssize_t used = (ssize_t) (bp->ptr - bp->data), new_len;
	ACL_VSTRING *vp = (ACL_VSTRING *) bp;

	if (vp->maxlen > 0 && (ssize_t) ACL_VSTRING_LEN(vp) >= vp->maxlen) {
		ACL_VSTRING_AT_OFFSET(vp, vp->maxlen - 1);
		ACL_VSTRING_TERMINATE(vp);
		acl_msg_warn("%s(%d), %s: overflow maxlen: %ld, %ld",
			__FILE__, __LINE__, myname, (long) vp->maxlen,
			(long) ACL_VSTRING_LEN(vp));
		bp->flags |= ACL_VBUF_FLAG_EOF;
		return ACL_VBUF_EOF;
	}

#ifdef ACL_WINDOWS
	if (bp->fd == ACL_FILE_INVALID && (bp->flags & ACL_VBUF_FLAG_FIXED))
#else
	if (bp->fd < 0 && (bp->flags & ACL_VBUF_FLAG_FIXED))
#endif
	{
		acl_msg_warn("%s(%d), %s: can't extend fixed buffer",
			__FILE__, __LINE__, myname);
		return ACL_VBUF_EOF;
	}

	/*
	 * Note: vp->vbuf.len is the current buffer size (both on entry and on
	 * exit of this routine). We round up the increment size to the buffer
	 * size to avoid silly little buffer increments. With really large
	 * strings we might want to abandon the length doubling strategy, and
	 * go to fixed increments.
	 */
#ifdef INCR_NO_DOUBLE
	/* below come from redis-server/sds.c/sdsMakeRoomFor, which can
	 * avoid memory double growing too large --- 2015.2.2, zsx
	 */
	new_len = bp->len + incr;
	if (new_len < MAX_PREALLOC)
		new_len *= 2;
	else
		new_len += MAX_PREALLOC;
#else
	new_len = bp->len + (bp->len > incr ? bp->len : incr);
#endif

	if (vp->maxlen > 0 && new_len > vp->maxlen)
		new_len = vp->maxlen;

	if (vp->slice)
		bp->data = (unsigned char *) acl_slice_pool_realloc(
			__FILE__, __LINE__, vp->slice, bp->data, new_len);
	else if (vp->dbuf) {
		const unsigned char *data = bp->data;
		bp->data = (unsigned char *) acl_dbuf_pool_alloc(
			vp->dbuf, new_len);
		memcpy(bp->data, data, used);
		acl_dbuf_pool_free(vp->dbuf, data);
	} else if (bp->fd != ACL_FILE_INVALID) {
#ifdef ACL_UNIX
		acl_off_t off = new_len - 1;
		if (acl_lseek(bp->fd, off, SEEK_SET) != (acl_off_t) off)
			acl_msg_fatal("lseek failed: %s, off: %lld",
				acl_last_serror(), off);
		if (acl_file_write(bp->fd, "\0", 1, 0, NULL, NULL)
			== ACL_VSTREAM_EOF)
		{
			acl_msg_fatal("write error: %s", acl_last_serror());
		}
#endif
	} else
		bp->data = (unsigned char *) acl_myrealloc(bp->data, new_len);

	bp->len = new_len;
	bp->ptr = bp->data + used;
	bp->cnt = bp->len - used;

	return 0;
}
Esempio n. 4
0
static int __vstream_sys_write(ACL_VSTREAM *stream, const void *vptr, int dlen)
{
	int   n, neintr = 0;

	acl_assert(stream && vptr && dlen > 0);

	if (stream->type == ACL_VSTREAM_TYPE_FILE) {
		if (ACL_VSTREAM_FILE(stream) == ACL_FILE_INVALID)
			return (ACL_VSTREAM_EOF);
	} else if (ACL_VSTREAM_SOCK(stream) == ACL_SOCKET_INVALID)
		return (ACL_VSTREAM_EOF);

TAG_AGAIN:

	if (stream->type == ACL_VSTREAM_TYPE_FILE) {
		if ((stream->oflags & O_APPEND)) {
#ifdef ACL_WINDOWS
			stream->sys_offset = acl_lseek(
				ACL_VSTREAM_FILE(stream), 0, SEEK_END);
			if (stream->sys_offset < 0)
				return (ACL_VSTREAM_EOF);
#endif
		} else if ((stream->flag & ACL_VSTREAM_FLAG_CACHE_SEEK)
			&& stream->offset != stream->sys_offset)
		{
			stream->sys_offset = acl_lseek(ACL_VSTREAM_FILE(stream),
				stream->offset, SEEK_SET);
			if (stream->sys_offset == -1)
				return (ACL_VSTREAM_EOF);
			stream->offset = stream->sys_offset;
		}

		n = stream->fwrite_fn(ACL_VSTREAM_FILE(stream), vptr, dlen,
			stream->rw_timeout, stream, stream->context);
		if (n > 0) {
			stream->sys_offset += n;
			stream->offset = stream->sys_offset;
			/* 防止缓冲区内的数据与实际不一致, 仅对文件IO有效 */
			stream->read_cnt = 0;
		}
	} else
		n = stream->write_fn(ACL_VSTREAM_SOCK(stream), vptr, dlen,
			stream->rw_timeout, stream, stream->context);
	if (n < 0) {
		if (acl_last_error() == ACL_EINTR) {
			if (++neintr >= 5)
				return (ACL_VSTREAM_EOF);

			goto TAG_AGAIN;
		}

		if (acl_last_error() == ACL_EAGAIN
			|| acl_last_error() == ACL_EWOULDBLOCK)
		{
			acl_set_error(ACL_EAGAIN);
		}

		return (ACL_VSTREAM_EOF);
	}

	stream->total_write_cnt += n;
	return (n);
}