Exemplo n.º 1
0
int encode_out(Gzb64* gzb64, unsigned char* buf, const size_t length)
{
	int gzout_size, ret;

	if( gzb64->encoded_last_chunk ) {
		gzout_size = evbuffer_get_length(gzb64->encode_gzout_buffer); /* dump everything in */		
	} else {
		int contiguous = evbuffer_get_contiguous_space(gzb64->encode_gzout_buffer);	
		gzout_size = contiguous - (contiguous % 3); /* must be mutliple of 3 */	 
	}

	if(gzout_size > 0) {
		unsigned char* gzout_buf = evbuffer_pullup(gzb64->encode_gzout_buffer, gzout_size);	
		int bytes_written = BIO_write(gzb64->b64_encoder, gzout_buf, gzout_size);
		evbuffer_drain(gzb64->encode_gzout_buffer, bytes_written);

		if(gzb64->encoded_last_chunk) ret = BIO_flush(gzb64->b64_encoder);	/* flush if last */
	}
		
	ret = BIO_read(gzb64->encode_output_buffer, buf, length);

	/* reset for next stream */
	if(gzb64->encoded_last_chunk && 0 == ret) {
		resetEncoder(gzb64);
	}

	return ret;
}
Exemplo n.º 2
0
static void ss_relay_readcb(struct bufferevent *buffev, void *_arg)
{
    redsocks_client *client = _arg;
    struct bufferevent * from = buffev;
    struct bufferevent * to   = client->client;
    size_t input_size = evbuffer_get_contiguous_space(bufferevent_get_input(from));
    size_t output_size = evbuffer_get_length(bufferevent_get_output(to));

    assert(buffev == client->relay);
    redsocks_touch_client(client);

    if (client->state == ss_connected)
    {
        /* decrypt and forward data to client side */
        if (output_size < to->wm_write.high)
        {
            if (input_size)
                decrypt_buffer(client, from, to);
            if (bufferevent_enable(from, EV_READ) == -1)
                redsocks_log_errno(client, LOG_ERR, "bufferevent_enable");
        }
        else
        {
            if (bufferevent_disable(from, EV_READ) == -1)
                redsocks_log_errno(client, LOG_ERR, "bufferevent_disable");
        }
    }
    else
    {
        redsocks_drop_client(client);
    }
}
Exemplo n.º 3
0
int decode_out(Gzb64* gzb64, unsigned char* buf, const size_t length)
{
	int zret, ret;

	/* should be guaranteed at least length after inflate */
	int gz_in_bytes = evbuffer_get_contiguous_space(gzb64->decode_output_buffer);
	unsigned char* gzin_buf = evbuffer_pullup(gzb64->decode_output_buffer, gz_in_bytes );

	if(DEBUG) hex_debug(gzin_buf, gz_in_bytes);
	
	gzb64->gz_decode_strm.next_in = gzin_buf;
	gzb64->gz_decode_strm.avail_in = gz_in_bytes;
	gzb64->gz_decode_strm.next_out = buf;
    gzb64->gz_decode_strm.avail_out = length;
	zret = inflate (& gzb64->gz_decode_strm, Z_NO_FLUSH);
	if(zret < 0) zerr(zret);

	evbuffer_drain(gzb64->decode_output_buffer, gz_in_bytes - gzb64->gz_decode_strm.avail_in);

	ret = length - gzb64->gz_decode_strm.avail_out;
	
	if(gzb64->decoded_last_chunk && 0 == ret) {
		resetDecoder(gzb64);
	}

	return ret;
}
Exemplo n.º 4
0
static void ss_relay_writecb(struct bufferevent *buffev, void *_arg)
{
    redsocks_client *client = _arg;
    struct bufferevent * from = client->client;
    struct bufferevent * to   = buffev;
    size_t input_size = evbuffer_get_contiguous_space(bufferevent_get_input(from));
    size_t output_size = evbuffer_get_length(bufferevent_get_output(to));

    assert(buffev == client->relay);
    redsocks_touch_client(client);

    if (process_shutdown_on_write_(client, from, to))
        return;

    if (client->state == ss_connected) 
    {
        /* encrypt and forward data received from client side */
        if (output_size < to->wm_write.high)
        {
            if (input_size)
                encrypt_buffer(client, from, to);
            if (!(client->client_evshut & EV_READ) && bufferevent_enable(from, EV_READ) == -1)
                redsocks_log_errno(client, LOG_ERR, "bufferevent_enable");
        }
    }
    else
    {
        redsocks_drop_client(client);
    }
}
Exemplo n.º 5
0
static void decrypt_buffer(redsocks_client * client,
                           struct bufferevent * from,
                           struct bufferevent * to)
{
    // To reduce memory copy, just decrypt one block a time
    struct evbuffer * buf_in = bufferevent_get_input(from);
    size_t input_size = evbuffer_get_contiguous_space(buf_in);
    char * input;

    if (!input_size)
        return;

    input = (char *)evbuffer_pullup(buf_in, input_size);
    encrypt_mem(client, input, input_size, to, 1);
    evbuffer_drain(buf_in, input_size);
}
Exemplo n.º 6
0
int decode_in_ev(Gzb64* gzb64, struct evbuffer* input)
{
	int contiguous;

	while(evbuffer_get_length(input) > 0 ) 
	{
		contiguous = evbuffer_get_contiguous_space(input);	

		if( contiguous < evbuffer_get_length(input) ) 
		{
			evbuffer_remove_buffer(input, gzb64->decode_input_buffer, contiguous);
			decode(gzb64, false);			
		} else 
		{
			/* last (only) block */
			evbuffer_remove_buffer(input, gzb64->decode_input_buffer, contiguous);
		}
	}

	return decode(gzb64, true);
}
Exemplo n.º 7
0
int encode_in_ev(Gzb64* gzb64, struct evbuffer* input)
{
	int contiguous;
	unsigned char* input_block;

	while(evbuffer_get_length(input) > 0) 
	{
		contiguous = evbuffer_get_contiguous_space(input);	
		input_block = evbuffer_pullup(input, contiguous);

		if( contiguous < evbuffer_get_length(input) ) 
		{
			encode_in(gzb64, &input_block[0], contiguous, false);
			evbuffer_drain(input, contiguous);			
		} else 
		{
			/* last (only) block */
			encode_in(gzb64, &input_block[0], contiguous, true);
			evbuffer_drain(input, contiguous);
		}
	}
	
	return 0;
}
Exemplo n.º 8
0
static int decode(Gzb64* gzb64, bool last)
{
	int b64in_size;
	struct evbuffer_iovec v[2];
	int n, i;
	size_t n_to_add = BUFF_SIZE;

	if( last ) {
		b64in_size = evbuffer_get_length(gzb64->decode_input_buffer); /* dump everything in */		
		gzb64->decoded_last_chunk = true;	
	} else {
		int contiguous = evbuffer_get_contiguous_space(gzb64->decode_input_buffer);	
		b64in_size = contiguous - (contiguous % 4); /* must be mutliple of 4 */	 
	}

	if(DEBUG) printf("Decode In:%zu\n", evbuffer_get_length(gzb64->decode_input_buffer));

	unsigned char* b64in_buf = evbuffer_pullup(gzb64->decode_input_buffer, b64in_size);
	BIO *b64_src_temp = BIO_new_mem_buf(b64in_buf, b64in_size);
	gzb64->b64_decoder = BIO_push(gzb64->b64_decoder, b64_src_temp);

	int b64_output_len = BUFF_SIZE;

	while(b64_output_len == BUFF_SIZE) {

		/* Reserve BUFF_SIZE bytes.*/
		n = evbuffer_reserve_space(gzb64->decode_output_buffer, n_to_add, v, 2);
		if (n<=0)
		   return -1; /* Unable to reserve the space for some reason. */

		for (i=0; i<n && n_to_add > 0; ++i) {
		   size_t len = v[i].iov_len;
		   if (len > n_to_add) /* Don't write more than n_to_add bytes. */
			  len = n_to_add;

		   b64_output_len = BIO_read(gzb64->b64_decoder, v[i].iov_base, len);

		   if ( b64_output_len < 0) {
			  /* If there was a problem during data generation, we can just stop
				 here; no data will be committed to the buffer. */
			  return -1;
		   }
		   /* Set iov_len to the number of bytes we actually wrote, so we
			  don't commit too much. */
		   v[i].iov_len = b64_output_len;
			if(DEBUG) printf("Decode B64 Out:%d\n", b64_output_len);
		}

		/* We commit the space here.  Note that we give it 'i' (the number of
		   vectors we actually used) rather than 'n' (the number of vectors we
		   had available. */
		if (evbuffer_commit_space(gzb64->decode_output_buffer, v, i) < 0)
		   return -1; /* Error committing */
	}

	if(DEBUG) printf("Inflate In:%zu\n", evbuffer_get_length(gzb64->decode_output_buffer));

	BIO_pop(gzb64->b64_decoder);
	BIO_free(b64_src_temp);
	BIO_reset(gzb64->b64_decoder);

	evbuffer_drain(gzb64->decode_input_buffer, b64in_size);
	
	return 0;
}