Пример #1
0
int rts_recv_pdu(rdpRpc* rpc, RTS_PDU* rts_pdu)
{
	STREAM* s;
	int status;
	int length;
	BYTE header_buffer[20];
	rdpTls* tls_out = rpc->tls_out;

	/* read first 20 bytes to get RTS PDU Header */
	status = tls_read(tls_out, (BYTE*) &header_buffer, 20);

	if (status <= 0)
	{
		printf("rts_recv error\n");
		return status;
	}

	s = stream_new(0);
	stream_attach(s, header_buffer, 20);

	rts_pdu_header_read(s, &(rts_pdu->header));

	stream_detach(s);
	stream_free(s);

	length = rts_pdu->header.frag_length - 20;
	rts_pdu->content = (BYTE*) malloc(length);

	status = tls_read(tls_out, rts_pdu->content, length);

	if (status < 0)
	{
		printf("rts_recv error\n");
		return status;
	}

	if (rts_pdu->header.ptype != PTYPE_RTS)
	{
		printf("rts_recv error: unexpected ptype:%d\n", rts_pdu->header.ptype);
		return -1;
	}

#ifdef WITH_DEBUG_RTS
	printf("rts_recv(): length: %d\n", length);
	freerdp_hexdump(rts_pdu->content, length);
	printf("\n");
#endif

	rts_recv_pdu_commands(rpc, rts_pdu);

	return rts_pdu->header.frag_length;
}
Пример #2
0
static ssize_t
tls_readv(struct wrap_io *wio, iovec_t *iov, int iovcnt)
{
    struct gnutella_socket *s = wio->ctx;
    ssize_t ret, done;
    int i;

    g_assert(socket_uses_tls(s));
    g_assert(iovcnt > 0);

    done = 0;
    ret = 0;
    for (i = 0; i < iovcnt; i++) {
        const size_t size = iovec_len(&iov[i]);

        ret = tls_read(wio, iovec_base(&iov[i]), size);
        if ((ssize_t) -1 == ret)
            break;
        done += (size_t) ret;
        if (size != (size_t) ret)
            break;
    }

    return done > 0 ? done : ret;
}
Пример #3
0
int transport_read(rdpTransport* transport, STREAM* s)
{
	int status = -1;

	while (True)
	{
		if (transport->layer == TRANSPORT_LAYER_TLS)
			status = tls_read(transport->tls, s->data, s->size);
		else if (transport->layer == TRANSPORT_LAYER_TCP)
			status = tcp_read(transport->tcp, s->data, s->size);

		if (status == 0 && transport->blocking)
		{
			nanosleep(&transport->ts, NULL);
			continue;
		}

		break;
	}

#ifdef WITH_DEBUG_TRANSPORT
	if (status > 0)
	{
		printf("Server > Client\n");
		freerdp_hexdump(s->data, status);
	}
#endif

	return status;
}
Пример #4
0
int force_read(rdpTls* tls, uint8* data, int bytes)
{
	int total_read;
	int read;

	LLOGLN(10, ("force_read:"));
	total_read = 0;
	while (total_read < bytes)
	{
		LLOGLN(10, ("force_read: reading %d bytes", bytes - total_read));
		read = tls_read(tls, data + total_read, bytes - total_read);
		if (read < 0)
		{
			/* disconnect or other error */
			return -1;
		}
		if (read == 0)
		{
			LLOGLN(0, ("force_read: read == 0, sleeping and reading again"));
			tcp_can_recv(tls->sockfd, 100);
			continue;
		}
		total_read += read;
	}
	return total_read;
}
Пример #5
0
static void
connection_poll_callback(uv_poll_t *handle, int status, int events)
{
    Client *client = handle->data;
    uv_buf_t buffer = { 0 };
    size_t len;
    int ret;

    if(status != 0)
    {
        client_free(client);
        return;
    }

    connection_allocate_buffer_callback((uv_handle_t *)handle,
                                        DEFAULT_READ_SIZE, &buffer);

    while((ret = tls_read(client->TlsContext, buffer.base, buffer.len, &len)) != 0)
    {
        if(ret == -1)
        {
            client_free(client);
            return;
        }
    }

    connection_on_read_callback((uv_stream_t *)handle, len, &buffer);
}
Пример #6
0
int transport_read(rdpTransport* transport, STREAM* s)
{
	int status = -1;

	while (True)
	{
		if (transport->layer == TRANSPORT_LAYER_TLS)
			status = tls_read(transport->tls, stream_get_tail(s), stream_get_left(s));
		else if (transport->layer == TRANSPORT_LAYER_TCP)
			status = tcp_read(transport->tcp, stream_get_tail(s), stream_get_left(s));

		if (status == 0 && transport->blocking)
		{
			freerdp_usleep(transport->usleep_interval);
			continue;
		}

		break;
	}

#ifdef WITH_DEBUG_TRANSPORT
	if (status > 0)
	{
		printf("Local < Remote\n");
		freerdp_hexdump(s->data, status);
	}
#endif

	return status;
}
Пример #7
0
static int copy_from_tls_to_stdout(struct tls *ctx)
{
	static size_t buf[BUFSIZE];
	ssize_t n,r;
	int i = 0;

	dbg("DEBUG: data from TLS\n");
	do {
		n = tls_read(ctx, buf, sizeof(buf));
	} while (n == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT);
	if (n < 0)
		err(1, "tls read: %s", tls_error(ctx));

	if (n == 0)
		return 1;

	while (n) {
		r = write(STDOUT_FILENO, &buf[i], n);
		if (r < 0)
			err(1, "write");
		i += r;
		n -= r;
	}
	return 0;
}
Пример #8
0
int rpc_out_read(rdpRpc* rpc, BYTE* data, int length)
{
	int status;

	status = tls_read(rpc->TlsOut, data, length);

	return status;
}
Пример #9
0
json_t* recvOverTLS(struct tls*ctx) {
    json_error_t error;
    size_t getSize, size;
    size_t len = sizeof(getSize);

    // read length
    while (len > 0) {
        int ret = tls_read(ctx, &getSize, len, &size); 
 
        if (ret == TLS_READ_AGAIN || ret == TLS_WRITE_AGAIN) { 
            /* retry.  May use select to wait for nonblocking */ 
        } else if (ret < 0) { 
            syslog(LOG_ERR, "%s\n", tls_error(ctx));
            break;
        } else { 
            len -= size; 
        } 
    }

    // create buffer
    char* buffer = (char*)malloc((getSize +1) *sizeof(char));
    char* buf = buffer;

    while (getSize > 0) {
        int ret = tls_read(ctx, buf, getSize, &size); 
 
        if (ret == TLS_READ_AGAIN || ret == TLS_WRITE_AGAIN) { 
            /* retry.  May use select to wait for nonblocking */ 
        } else if (ret < 0) { 
            syslog(LOG_ERR, "%s\n", tls_error(ctx));
            break;
        } else { 
            buf += size; 
            getSize -= size; 
        } 
    }

    // Process buffer to json
    json_t *json = json_loads(buffer, JSON_DISABLE_EOF_CHECK, &error);
    if (verbose_flag) {
        syslog(LOG_DEBUG, "%s\n", buffer);
    }
    return json;
}
Пример #10
0
int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
{
	int read = 0;
	int status = -1;

	while (read < bytes)
	{
		if (transport->layer == TRANSPORT_LAYER_TLS)
			status = tls_read(transport->TlsIn, data + read, bytes - read);
		else if (transport->layer == TRANSPORT_LAYER_TCP)
			status = tcp_read(transport->TcpIn, data + read, bytes - read);
		else if (transport->layer == TRANSPORT_LAYER_TSG)
			status = tsg_read(transport->tsg, data + read, bytes - read);
		else if (transport->layer == TRANSPORT_LAYER_TSG_TLS) {
			status = tls_read(transport->TsgTls, data + read, bytes - read);
		}

		/* blocking means that we can't continue until this is read */

		if (!transport->blocking)
			return status;

		if (status < 0)
		{
			/* A read error indicates that the peer has dropped the connection */
			transport->layer = TRANSPORT_LAYER_CLOSED;
			return status;
		}

		read += status;

		if (status == 0)
		{
			/*
			 * instead of sleeping, we should wait timeout on the
			 * socket but this only happens on initial connection
			 */
			USleep(transport->SleepInterval);
		}
	}

	return read;
}
Пример #11
0
static void worker_cb(int fd, short flags, void *arg)
{
	struct Worker *w = arg;
	const char *err;
	char buf[128];
	int res;
	size_t outlen;

	w->pending = 0;

	if (w->wstate == HANDSHAKE) {
		err = do_handshake(w, fd);
		add_error(w, err);
	} else if (w->wstate == CONNECTED) {
		if (flags & EV_READ) {
			res = tls_read(w->ctx, buf, sizeof buf, &outlen);
			if (res == TLS_READ_AGAIN) {
				wait_for_event(w, EV_READ);
			} else if (res == TLS_WRITE_AGAIN) {
				wait_for_event(w, EV_WRITE);
			} else if (res == 0) {
				if (outlen > 0 && w->is_server) {
					tls_write(w->ctx, "END", 3, &outlen);
					w->wstate = CLOSED;
				} else if (outlen == 0) {
					w->wstate = CLOSED;
				} else {
					wait_for_event(w, EV_READ);
				}
			} else {
				add_error(w, "bad pkt");
			}
		} else {
			add_error(w, "EV_WRITE?");
		}
	}
	if (w->wstate == CLOSED && w->ctx) {
		res = tls_close(w->ctx);
		if (res == 0) {
			tls_free(w->ctx);
			w->ctx = NULL;
		} else if (res == TLS_READ_AGAIN) {
			wait_for_event(w, EV_READ);
		} else if (res == TLS_WRITE_AGAIN) {
			wait_for_event(w, EV_WRITE);
		} else {
			tls_free(w->ctx);
			w->ctx = NULL;
		}
	}
	if (!w->pending && w->ctx) {
		errx(1, "missed event setup: %s flags=%d state=%d", w->is_server ? "S":"C", flags, w->wstate);
	}
	return;
}
Пример #12
0
int transport_read(rdpTransport* transport, STREAM* s)
{
    int status = -1;

    if (transport->layer == TRANSPORT_LAYER_TLS)
        status = tls_read(transport->tls, s->data, s->size);
    else if (transport->layer == TRANSPORT_LAYER_TCP)
        status = tcp_read(transport->tcp, s->data, s->size);

    return status;
}
Пример #13
0
int tls_read_all(rdpTls* tls, uint8* data, int length)
{
	int status;

	do
	{
		status = tls_read(tls, data, length);
	}
	while (status == 0);

	return status;
}
Пример #14
0
int credssp_recv(rdpCredssp* credssp)
{
	STREAM* s;
	int length;
	int status;
	uint32 version;

	s = stream_new(2048);
	status = tls_read(credssp->tls, s->data, stream_get_left(s));

	if (status < 0)
		return -1;

	/* TSRequest */
	ber_read_sequence_tag(s, &length);
	ber_read_contextual_tag(s, 0, &length, true);
	ber_read_integer(s, &version);

	/* [1] negoTokens (NegoData) */
	if (ber_read_contextual_tag(s, 1, &length, true) != false)
	{
		ber_read_sequence_tag(s, &length); /* SEQUENCE OF NegoDataItem */
		ber_read_sequence_tag(s, &length); /* NegoDataItem */
		ber_read_contextual_tag(s, 0, &length, true); /* [0] negoToken */
		ber_read_octet_string(s, &length); /* OCTET STRING */
		sspi_SecBufferAlloc(&credssp->negoToken, length);
		stream_read(s, credssp->negoToken.pvBuffer, length);
		credssp->negoToken.cbBuffer = length;
	}

	/* [2] authInfo (OCTET STRING) */
	if (ber_read_contextual_tag(s, 2, &length, true) != false)
	{
		ber_read_octet_string(s, &length); /* OCTET STRING */
		sspi_SecBufferAlloc(&credssp->authInfo, length);
		stream_read(s, credssp->authInfo.pvBuffer, length);
		credssp->authInfo.cbBuffer = length;
	}

	/* [3] pubKeyAuth (OCTET STRING) */
	if (ber_read_contextual_tag(s, 3, &length, true) != false)
	{
		ber_read_octet_string(s, &length); /* OCTET STRING */
		sspi_SecBufferAlloc(&credssp->pubKeyAuth, length);
		stream_read(s, credssp->pubKeyAuth.pvBuffer, length);
		credssp->pubKeyAuth.cbBuffer = length;
	}

	stream_free(s);

	return 0;
}
Пример #15
0
static void
https_retr_file(const char *fn, off_t file_sz, off_t offset)
{
	size_t		 wlen;
	ssize_t		 i, r;
	char		*cp;
	static char	*buf;
	int		 fd, flags;

	if (buf == NULL) {
		buf = malloc(TMPBUF_LEN); /* allocate once */
		if (buf == NULL)
			err(1, "%s: malloc", __func__);
	}

	flags = O_CREAT | O_WRONLY;
	if (offset)
		flags |= O_APPEND;

	if (strcmp(fn, "-") == 0)
		fd = STDOUT_FILENO;
	else if ((fd = open(fn, flags, 0666)) == -1)
		err(1, "%s: open %s", __func__, fn);

	start_progress_meter(file_sz, &offset);
	while (1) {
		r = tls_read(ctx, buf, TMPBUF_LEN);
		if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
			continue;
		else if (r < 0) {
			errx(1, "%s: tls_read: %s", __func__, tls_error(ctx));
		}

		if (r == 0)
			break;

		offset += r;
		for (cp = buf, wlen = r; wlen > 0; wlen -= i, cp += i) {
			if ((i = write(fd, cp, wlen)) == -1) {
				if (errno != EINTR)
					err(1, "%s: write", __func__);
			} else if (i == 0)
				break;
		}
	}

	if (strcmp(fn, "-") != 0)
		close(fd);

	stop_progress_meter();
}
Пример #16
0
int tls_read_all(rdpTls* tls, BYTE* data, int length)
{
	int status;

	do
	{
		status = tls_read(tls, data, length);
		if (status == 0)
			tls_wait_read(tls);
	}
	while (status == 0);

	return status;
}
Пример #17
0
/** Check if data is available in TCP connection.
 *
 *
 *
 * @retval -1 upon an error
 * @retval 0 end-of-stream
 * @retval 1 nothing to read
 * @retval 2 there is data to read
 */
int tls_want_read(tls_t *tls, int events)
{
  if (tls && (events & tls->read_events)) {
    int ret = tls_read(tls);
    if (ret > 0)
      return 2;
    else if (ret == 0)
      return 0;
    else if (errno == EAGAIN)
      return 3;			/* ??? */
    else
      return -1;
  }

  return 1;
}
Пример #18
0
int
evtls_read(struct evbuffer *buf, int fd, int howmuch, struct tls *ctx)
{
	u_char *p;
	size_t oldoff = buf->off;
	int n = EVBUFFER_MAX_READ;

	if (ioctl(fd, FIONREAD, &n) == -1 || n <= 0) {
		n = EVBUFFER_MAX_READ;
	} else if (n > EVBUFFER_MAX_READ && n > howmuch) {
		/*
		 * It's possible that a lot of data is available for
		 * reading.  We do not want to exhaust resources
		 * before the reader has a chance to do something
		 * about it.  If the reader does not tell us how much
		 * data we should read, we artifically limit it.
		 */
		if ((size_t)n > buf->totallen << 2)
			n = buf->totallen << 2;
		if (n < EVBUFFER_MAX_READ)
			n = EVBUFFER_MAX_READ;
	}
	if (howmuch < 0 || howmuch > n)
		howmuch = n;

	/* If we don't have FIONREAD, we might waste some space here */
	if (evbuffer_expand(buf, howmuch) == -1)
		return (-1);

	/* We can append new data at this point */
	p = buf->buffer + buf->off;

	n = tls_read(ctx, p, howmuch);
	if (n <= 0)
		return (n);

	buf->off += n;

	/* Tell someone about changes in this buffer */
	if (buf->off != oldoff && buf->cb != NULL)
		(*buf->cb)(buf, oldoff, buf->off, buf->cbarg);

	return (n);
}
Пример #19
0
static char *
https_parseln(size_t *lenp)
{
	size_t	 i, len;
	char	*buf, *q, c;
	ssize_t	 nr;

	len = 128;
	if ((buf = calloc(1, len)) == NULL)
		errx(1, "Can't allocate memory for transfer buffer");

	for (i = 0; ; i++) {
		if (i >= len - 1) {
			if ((q = reallocarray(buf, len, 2)) == NULL)
				errx(1, "Can't expand transfer buffer");

			buf = q;
			len *= 2;
		}
again:
		nr = tls_read(ctx, &c, 1);
		if (nr == TLS_WANT_POLLIN || nr == TLS_WANT_POLLOUT)
			goto again;

		if (nr < 0)
			errx(1, "TLS read error: %ld", nr);

		buf[i] = c;
		if (c == '\n')
			break;
	}

	buf[i] = '\0';
	if (i && buf[i - 1] == '\r')
		buf[--i] = '\0';

	if (lenp)
		*lenp = i;

	return buf;
}
Пример #20
0
VMINT vm_tls_read(VMINT res_id, void* buf, VMINT32 len)
{
    kal_int32 ret;
    vm_tls_context_t * ctx_p = NULL;
    
    MMI_TRACE(TRACE_GROUP_8, TRC_MRE_SSL_S, 7, __LINE__);
    ctx_p = vm_tls_get_ctx_by_res(res_id);
    if (NULL == ctx_p)
    {
        MMI_TRACE(TRACE_GROUP_8, TRC_MRE_SSL_E1, 7, __LINE__);
        return VM_TLS_RET_BASE -2;
    }
    
    ret = tls_read((kal_int8)(ctx_p->soc_id), (void *)buf, (kal_int32)len);
    if (TLS_ERR_NONE != ret)
    {
        MMI_TRACE(TRACE_GROUP_8, TRC_MRE_SSL_E2, 7, ret);
        return ret;
    }
    MMI_TRACE(TRACE_GROUP_8, TRC_MRE_SSL_E, 7, __LINE__);
    return 0;
}
Пример #21
0
int transport_read_layer(rdpTransport* transport, uint8* data, int bytes)
{
    int read = 0;
    int status = -1;

    while (read < bytes)
    {
        if (transport->layer == TRANSPORT_LAYER_TLS)
            status = tls_read(transport->tls, data + read, bytes - read);
        else if (transport->layer == TRANSPORT_LAYER_TCP)
            status = tcp_read(transport->tcp, data + read, bytes - read);
        //else if (transport->layer == TRANSPORT_LAYER_TSG)
        //	status = tsg_read(transport->tsg, data + read, bytes - read);

        /* blocking means that we can't continue until this is read */

        if (!transport->blocking)
            return status;

        if (status < 0)
            return status;

        read += status;

        if (status == 0)
        {
            /*
             * instead of sleeping, we should wait timeout on the
             * socket but this only happens on initial connection
             */
            freerdp_usleep(transport->usleep_interval);
        }
    }

    return read;
}
Пример #22
0
static int sock_read(SocketRef const socket, size_t const size, uv_buf_t *const out) {
	if(!socket->secure) return async_read((uv_stream_t *)socket->stream, size, out);

	out->base = malloc(size);
	if(!out->base) return UV_ENOMEM;
	size_t total = 0;
	for(;;) {
		size_t partial = 0;
		int event = tls_read(socket->secure, out->base+total, size-total, &partial);
		total += partial;
		if(0 == event) break;
		int rc = tls_poll((uv_stream_t *)socket->stream, event);
		if(rc < 0) {
			FREE(&out->base);
			return rc;
		}
	}
	if(0 == total) {
		FREE(&out->base);
		return UV_EOF;
	}
	out->len = total;
	return 0;
}
Пример #23
0
int tls_read(tls_t *tls, void * const buff, const size_t len)
{
    int bytes;

    /* first, if we've got some ready data, put that in the buffer */
    if (tls->readybufferpos < tls->readybufferlen)
    {
	if (len < tls->readybufferlen - tls->readybufferpos) {
	    bytes = len;
	} else {
	    bytes = tls->readybufferlen - tls->readybufferpos;
	}

	memcpy(buff, tls->readybuffer + tls->readybufferpos, bytes);

	if (len < tls->readybufferlen - tls->readybufferpos) {
	    tls->readybufferpos += bytes;
	    return bytes;
	} else {
	    unsigned char *newbuff = buff;
	    int read;
	    tls->readybufferpos += bytes;
	    newbuff += bytes;
	    read = tls_read(tls, newbuff, len - bytes);

	    if (read == -1) {
	        if (tls_is_recoverable(tls->lasterror)) {
		    return bytes;
		}

		return -1;
	    }

	    return bytes + read;
	}
    }

    /* next, top up our recv buffer */
    bytes = sock_read(tls->sock, tls->recvbuffer + tls->recvbufferpos,
		      tls->recvbuffermaxlen - tls->recvbufferpos);

    if (bytes == 0) {
        tls->lasterror = WSAECONNRESET;
        return -1;
    }

    if (bytes == -1) {
	if (!tls_is_recoverable(sock_error())) {
	    tls->lasterror = sock_error();
	    return -1;
	}
    }

    if (bytes > 0) {
	tls->recvbufferpos += bytes;
    }

    /* next, try to decrypt the recv buffer */
    if (tls->recvbufferpos > 0) {
	SecBufferDesc sbddec;
	SecBuffer sbdec[4];
	int ret;

	memset(&sbddec, 0, sizeof(sbddec));
	sbddec.ulVersion = SECBUFFER_VERSION;
	sbddec.cBuffers = 4;
	sbddec.pBuffers = sbdec;

	memset(&(sbdec[0]), 0, sizeof(sbdec[0]));
	sbdec[0].BufferType = SECBUFFER_DATA;
	sbdec[0].pvBuffer = tls->recvbuffer;
	sbdec[0].cbBuffer = tls->recvbufferpos;

	memset(&(sbdec[1]), 0, sizeof(sbdec[1]));
	sbdec[1].BufferType = SECBUFFER_EMPTY;

	memset(&(sbdec[2]), 0, sizeof(sbdec[2]));
	sbdec[2].BufferType = SECBUFFER_EMPTY;

	memset(&(sbdec[3]), 0, sizeof(sbdec[3]));
	sbdec[3].BufferType = SECBUFFER_EMPTY;

	ret = tls->sft->DecryptMessage(&(tls->hctxt), &sbddec, 0, NULL);

	if (ret == SEC_E_OK) {
	    memcpy(tls->readybuffer, sbdec[1].pvBuffer, sbdec[1].cbBuffer);
	    tls->readybufferpos = 0;
	    tls->readybufferlen = sbdec[1].cbBuffer;
	    /* have we got some data left over?  If so, copy it to the start
	     * of the recv buffer */
	    if (sbdec[3].BufferType == SECBUFFER_EXTRA) {
		memcpy(tls->recvbuffer, sbdec[3].pvBuffer, sbdec[3].cbBuffer);
		tls->recvbufferpos = sbdec[3].cbBuffer;
	    } else {
		tls->recvbufferpos = 0;
	    }

	    return tls_read(tls, buff, len);
	} else if (ret == SEC_E_INCOMPLETE_MESSAGE) {
	    tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
	    return -1;
	} else if (ret == SEC_I_RENEGOTIATE) {
	    ret = tls_start(tls);
	    if (!ret)
	    {
		return -1;
	    }

	    /* fake an incomplete message so we're called again */
	    tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
	    return -1;
	}

	/* something bad happened, so we bail */
	tls->lasterror = ret;

	return -1;
    }

    tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;

    return -1;
}
Пример #24
0
HttpResponse* http_response_recv(rdpTls* tls)
{
	uint8* p;
	int nbytes;
	int length;
	int status;
	uint8* buffer;
	char* content;
	char* header_end;
	HttpResponse* http_response;

	nbytes = 0;
	length = 0xFFFF;
	buffer = xmalloc(length);
	http_response = http_response_new();

	p = buffer;

	while (true)
	{
		status = tls_read(tls, p, length - nbytes);

		if (status > 0)
		{
			nbytes += status;
			p = (uint8*) &buffer[nbytes];
		}
		else if (status == 0)
		{
			continue;
		}
		else
		{
			return NULL;
			break;
		}

		header_end = strstr((char*) buffer, "\r\n\r\n") + 2;

		if (header_end != NULL)
		{
			int count;
			char* line;

			header_end[0] = '\0';
			header_end[1] = '\0';
			content = &header_end[2];

			count = 0;
			line = (char*) buffer;

			while ((line = strstr(line, "\r\n")) != NULL)
			{
				line++;
				count++;
			}

			http_response->count = count;
			http_response->lines = (char**) xmalloc(sizeof(char*) * http_response->count);

			count = 0;
			line = strtok((char*) buffer, "\r\n");

			while (line != NULL)
			{
				http_response->lines[count] = xstrdup(line);
				line = strtok(NULL, "\r\n");
				count++;
			}

			http_response_parse_header(http_response);

			if (http_response->ContentLength > 0)
			{
				http_response->Content = xstrdup(content);
			}

			break;
		}

		if ((length - nbytes) <= 0)
		{
			length *= 2;
			buffer = xrealloc(buffer, length);
			p = (uint8*) &buffer[nbytes];
		}
	}

	return http_response;
}
Пример #25
0
int
main(int argc, char *argv[], char *envp[])
{
	struct tls *tls = NULL;
	int ch;
	environ = envp;

	/* pipes to communicate with the front end */
	int in = -1;
	int out = -1;

	bool no_name_verification = false;
	bool no_cert_verification = false;
	bool no_time_verification = false;
	char *host = getenv("TCPREMOTEHOST");
	struct tls_config *tls_config;

	if (getenv("TLSC_NO_VERIFICATION") != NULL) {
		no_name_verification = true;
		no_cert_verification = true;
		no_time_verification = true;
	}

	if (getenv("TLSC_NO_HOST_VERIFICATION") != NULL)
		no_name_verification = true;

	if (getenv("TLSC_NO_CERT_VERIFICATION") != NULL)
		no_cert_verification = true;

	if (getenv("TLSC_NO_TIME_VERIFICATION") != NULL)
		no_time_verification = true;

	if ((tls_config = tls_config_new()) == NULL)
		err(EXIT_FAILURE, "tls_config_new");

	char *str = NULL;
	if ((str = getenv("TLSC_CERT_FILE")) != NULL)
		if (tls_config_set_cert_file(tls_config, str) == -1)
			err(EXIT_FAILURE, "tls_config_set_cert_file");

	if ((str = getenv("TLSC_KEY_FILE")) != NULL)
		if (tls_config_set_key_file(tls_config, str) == -1)
			err(EXIT_FAILURE, "tls_config_set_key_file");

	if ((str = getenv("TLSC_CA_FILE")) != NULL)
		if (tls_config_set_ca_file(tls_config, str) == -1)
			err(EXIT_FAILURE, "tls_config_set_ca_file");

	if ((str = getenv("TLSC_CA_PATH")) != NULL)
		if (tls_config_set_ca_path(tls_config, str) == -1)
			err(EXIT_FAILURE, "tls_config_set_ca_path");

	while ((ch = getopt(argc, argv, "c:k:f:p:n:HCTVh")) != -1) {
		switch (ch) {
		case 'c':
			if (tls_config_set_cert_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_cert_file");
			break;
		case 'k':
			if (tls_config_set_key_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_key_file");
			break;
		case 'f':
			if (tls_config_set_ca_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_ca_file");
			break;
		case 'p':
			if (tls_config_set_ca_path(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_ca_path");
			break;
		case 'n':
			if ((host = strdup(optarg)) == NULL) goto err;
			break;
		case 'H':
			no_name_verification = true;
			break;
		case 'C':
			no_cert_verification = true;
			break;
		case 'T':
			no_time_verification = true;
			break;
		case 'V':
			no_name_verification = true;
			no_cert_verification = true;
			no_time_verification = true;
			break;
		case 'h':
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();

	/* verification settings */
	if (no_cert_verification)
		tls_config_insecure_noverifycert(tls_config);

	if (no_name_verification)
		tls_config_insecure_noverifyname(tls_config);

	if (no_time_verification)
		tls_config_insecure_noverifytime(tls_config);

	/* libtls setup */
	if (tls_init() != 0)
		err(EXIT_FAILURE, "tls_init");

	if ((tls = tls_client()) == NULL)
		err(EXIT_FAILURE, "tls_client");

	if (tls_configure(tls, tls_config) != 0)
		err(EXIT_FAILURE, "tls_configure");

	if (tls_connect_fds(tls, READ_FD, WRITE_FD, host) == -1)
		goto err;

	if (tls_handshake(tls) == -1)
		goto err;

	/* overide PROTO to signal the application layer that the communication
	 * channel is save. */
	if (setenv("PROTO", "SSL", 1) == -1)
		err(EXIT_FAILURE, "setenv");

	/* fork front end program */
	char *prog = argv[0];
#	define PIPE_READ 0
#	define PIPE_WRITE 1
	int pi[2];	/* input pipe */
	int po[2];	/* output pipe */
	if (pipe(pi) == -1) err(EXIT_FAILURE, "pipe");
	if (pipe(po) == -1) err(EXIT_FAILURE, "pipe");

	switch (fork()) {
	case -1:
		err(EXIT_FAILURE, "fork");
	case 0: /* client program */

		/* close non-using ends of pipes */
		if (close(pi[PIPE_READ]) == -1) err(EXIT_FAILURE, "close");
		if (close(po[PIPE_WRITE]) == -1) err(EXIT_FAILURE, "close");

		/*
		 * We have to move one descriptor cause po[] may
		 * overlaps with descriptor 6 and 7.
		 */
		int po_read = 0;
		if ((po_read = dup(po[PIPE_READ])) == -1)
			err(EXIT_FAILURE, "dup");
		if (close(po[PIPE_READ]) < 0) err(EXIT_FAILURE, "close");

		if (dup2(pi[PIPE_WRITE], WRITE_FD) < 0)
			err(EXIT_FAILURE, "dup2");
		if (dup2(po_read, READ_FD) < 0) err(EXIT_FAILURE, "dup2");

		if (close(pi[PIPE_WRITE]) < 0) err(EXIT_FAILURE, "close");
		if (close(po_read) < 0) err(EXIT_FAILURE, "close");
		execvpe(prog, argv, environ);
		err(EXIT_FAILURE, "execvpe");
	default: break;	/* parent */
	}

	/* close non-using ends of pipes */
	if (close(pi[PIPE_WRITE]) == -1) err(EXIT_FAILURE, "close");
	if (close(po[PIPE_READ]) == -1) err(EXIT_FAILURE, "close");

	in = pi[PIPE_READ];
	out = po[PIPE_WRITE];

	/* communication loop */
	for (;;) {
		int ret;
		char buf[BUFSIZ];
		ssize_t sn = 0;
		fd_set readfds;
		FD_ZERO(&readfds);
		FD_SET(in, &readfds);
		FD_SET(READ_FD, &readfds);
		int max_fd = MAX(in, READ_FD);

		ret = select(max_fd+1, &readfds, NULL, NULL, NULL);
		if (ret == -1)
			err(EXIT_FAILURE, "select");

		if (FD_ISSET(READ_FD, &readfds)) {
			do {
 again:
				sn = tls_read(tls, buf, sizeof buf);
				if (sn == TLS_WANT_POLLIN ||
				    sn == TLS_WANT_POLLOUT)
					goto again;
				if (sn == -1)
					goto err;
				if (sn == 0)
					return EXIT_SUCCESS;

				if (write(out, buf, sn) == -1)
					err(EXIT_FAILURE, "write()");
			} while (sn == sizeof buf);
		} else if (FD_ISSET(in, &readfds)) {
			if ((sn = read(in, buf, sizeof buf)) == -1)
				err(EXIT_FAILURE, "read()");
			if (sn == 0)
				goto out;
			if ((sn = tls_write(tls, buf, sn)) == -1)
				goto out;
		}
	}
 out:
	tls_close(tls);
	return EXIT_SUCCESS;
 err:
	errx(EXIT_FAILURE, "tls_error: %s", tls_error(tls));
}
Пример #26
0
int rpc_out_read(rdpRpc* rpc, uint8* data, int length)
{
	STREAM* s;
	int status;
	uint8* pdu;
	int content_length;
	RPC_PDU_HEADER header;

	if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */
		rts_send_flow_control_ack_pdu(rpc);  /* Send FlowControlAck every time AvailableWindow reaches the half */

	pdu = xmalloc(0xFFFF);
	if (pdu == NULL)
	{
		printf("rpc_out_read error: memory allocation failed") ;
		return -1 ;
	}

	status = tls_read(rpc->tls_out, pdu, 16); /* read first 16 bytes to get RPC PDU Header */

	if (status <= 0)
	{
		xfree(pdu);
		return status;
	}

	s = stream_new(0);
	stream_attach(s, pdu, 16);

	rpc_pdu_header_read(s, &header);

	stream_detach(s);
	stream_free(s);

	content_length = header.frag_length - 16;
	status = tls_read(rpc->tls_out, pdu + 16, content_length);

	if (status < 0)
	{
		xfree(pdu);
		return status;
	}

	if (header.ptype == PTYPE_RTS) /* RTS PDU */
	{
		printf("rpc_out_read error: Unexpected RTS PDU\n");
		xfree(pdu);
		return -1;
	}
	else
	{
		/* RTS PDUs are not subject to flow control */
		rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header.frag_length;
		rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header.frag_length;
	}

	if (length < header.frag_length)
	{
		printf("rpc_out_read error! receive buffer is not large enough\n");
		xfree(pdu);
		return -1;
	}

	memcpy(data, pdu, header.frag_length);

#ifdef WITH_DEBUG_RPC
	printf("rpc_out_read(): length: %d\n", header.frag_length);
	freerdp_hexdump(data, header.frag_length);
	printf("\n");
#endif

	xfree(pdu);
	return header.frag_length;
}
Пример #27
0
HttpResponse* http_response_recv(rdpTls* tls)
{
	BYTE* p;
	int nbytes;
	int length;
	int status;
	BYTE* buffer;
	char* content;
	char* header_end;
	HttpResponse* http_response;

	nbytes = 0;
	length = 10000;
	content = NULL;
	buffer = malloc(length);
	if (!buffer)
		return NULL;

	http_response = http_response_new();
	if (!http_response)
		goto out_free;

	p = buffer;
	http_response->ContentLength = 0;

	while (TRUE)
	{
		while (nbytes < 5)
		{
			status = tls_read(tls, p, length - nbytes);
            
			if (status < 0)
				goto out_error;

			if (!status)
				continue;

			nbytes += status;
			p = (BYTE*) &buffer[nbytes];
		}

		header_end = strstr((char*) buffer, "\r\n\r\n");
        
		if (!header_end)
		{
			fprintf(stderr, "http_response_recv: invalid response:\n");
			winpr_HexDump(buffer, status);
			goto out_error;
		}

		header_end += 2;

		if (header_end != NULL)
		{
			int count;
			char* line;

			header_end[0] = '\0';
			header_end[1] = '\0';
			content = &header_end[2];

			count = 0;
			line = (char*) buffer;

			while ((line = strstr(line, "\r\n")) != NULL)
			{
				line++;
				count++;
			}

			http_response->count = count;
			if (count)
			{
				http_response->lines = (char **)calloc(http_response->count, sizeof(char *));
				if (!http_response->lines)
					goto out_error;
			}

			count = 0;
			line = strtok((char*) buffer, "\r\n");

			while (line != NULL)
			{
				http_response->lines[count] = _strdup(line);
				if (!http_response->lines[count])
					goto out_error;

				line = strtok(NULL, "\r\n");
				count++;
			}

			if (!http_response_parse_header(http_response))
				goto out_error;

			if (http_response->ContentLength > 0)
			{
				http_response->Content = _strdup(content);
				if (!http_response->Content)
					goto out_error;
			}

			break;
		}

		if ((length - nbytes) <= 0)
		{
			length *= 2;
			buffer = realloc(buffer, length);
			p = (BYTE*) &buffer[nbytes];
		}
	}

	free(buffer);

	return http_response;

out_error:
	http_response_free(http_response);
out_free:
	free(buffer);
	return NULL;
}
Пример #28
0
Файл: ip.c Проект: fanf2/exim
int
ip_recv(int sock, uschar *buffer, int buffsize, int timeout)
{
fd_set select_inset;
struct timeval tv;
int start_recv = time(NULL);
int rc;

/* Wait until the socket is ready */

for (;;)
  {
  FD_ZERO (&select_inset);
  FD_SET (sock, &select_inset);
  tv.tv_sec = timeout;
  tv.tv_usec = 0;

  DEBUG(D_transport) debug_printf("waiting for data on socket\n");
  rc = select(sock + 1, (SELECT_ARG2_TYPE *)&select_inset, NULL, NULL, &tv);

  /* If some interrupt arrived, just retry. We presume this to be rare,
  but it can happen (e.g. the SIGUSR1 signal sent by exiwhat causes
  select() to exit).

  Aug 2004: Somebody set up a cron job that ran exiwhat every 2 minutes, making
  the interrupt not at all rare. Since the timeout is typically more than 2
  minutes, the effect was to block the timeout completely. To prevent this
  happening again, we do an explicit time test. */

  if (rc < 0 && errno == EINTR)
    {
    DEBUG(D_transport) debug_printf("EINTR while waiting for socket data\n");
    if (time(NULL) - start_recv < timeout) continue;
    DEBUG(D_transport) debug_printf("total wait time exceeds timeout\n");
    }

  /* Handle a timeout, and treat any other select error as a timeout, including
  an EINTR when we have been in this loop for longer than timeout. */

  if (rc <= 0)
    {
    errno = ETIMEDOUT;
    return -1;
    }

  /* If the socket is ready, break out of the loop. */

  if (FD_ISSET(sock, &select_inset)) break;
  }

/* The socket is ready, read from it (via TLS if it's active). On EOF (i.e.
close down of the connection), set errno to zero; otherwise leave it alone. */

#ifdef SUPPORT_TLS
if (tls_active == sock)
  rc = tls_read(buffer, buffsize);
else
#endif
  rc = recv(sock, buffer, buffsize, 0);

if (rc > 0) return rc;
if (rc == 0) errno = 0;
return -1;
}
Пример #29
0
/** Run the event loop once.
 *  This function will run send any data that has been queued by
 *  xmpp_send and related functions and run through the Strophe even
 *  loop a single time, and will not wait more than timeout
 *  milliseconds for events.  This is provided to support integration
 *  with event loops outside the library, and if used, should be
 *  called regularly to achieve low latency event handling.
 *
 *  @param ctx a Strophe context object
 *  @param timeout time to wait for events in milliseconds
 *
 *  @ingroup EventLoop
 */
void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
{
    xmpp_connlist_t *connitem;
    xmpp_conn_t *conn;
    fd_set rfds, wfds;
    sock_t max = 0;
    int ret;
    struct timeval tv;
    xmpp_send_queue_t *sq, *tsq;
    int towrite;
    char buf[4096];
    uint64_t next;
    long usec;
    int tls_read_bytes = 0;

    if (ctx->loop_status == XMPP_LOOP_QUIT) return;
    ctx->loop_status = XMPP_LOOP_RUNNING;

    /* send queued data */
    connitem = ctx->connlist;
    while (connitem) {
	conn = connitem->conn;
	if (conn->state != XMPP_STATE_CONNECTED) {
	    connitem = connitem->next;
	    continue;
	}

	/* if we're running tls, there may be some remaining data waiting to
	 * be sent, so push that out */
	if (conn->tls) {
	    ret = tls_clear_pending_write(conn->tls);

	    if (ret < 0 && !tls_is_recoverable(tls_error(conn->tls))) {
		/* an error occured */
		xmpp_debug(ctx, "xmpp", "Send error occured, disconnecting.");
		conn->error = ECONNABORTED;
		conn_disconnect(conn);
	    }
	}

	/* write all data from the send queue to the socket */
	sq = conn->send_queue_head;
	while (sq) {
	    towrite = sq->len - sq->written;

	    if (conn->tls) {
		ret = tls_write(conn->tls, &sq->data[sq->written], towrite);

		if (ret < 0 && !tls_is_recoverable(tls_error(conn->tls))) {
		    /* an error occured */
		    conn->error = tls_error(conn->tls);
		    break;
		} else if (ret < towrite) {
		    /* not all data could be sent now */
		    if (ret >= 0) sq->written += ret;
		    break;
		}

	    } else {
		ret = sock_write(conn->sock, &sq->data[sq->written], towrite);

		if (ret < 0 && !sock_is_recoverable(sock_error())) {
		    /* an error occured */
		    conn->error = sock_error();
		    break;
		} else if (ret < towrite) {
		    /* not all data could be sent now */
		    if (ret >= 0) sq->written += ret;
		    break;
		}
	    }

	    /* all data for this queue item written, delete and move on */
	    xmpp_free(ctx, sq->data);
	    tsq = sq;
	    sq = sq->next;
	    xmpp_free(ctx, tsq);

	    /* pop the top item */
	    conn->send_queue_head = sq;
	    /* if we've sent everything update the tail */
	    if (!sq) conn->send_queue_tail = NULL;
	}

	/* tear down connection on error */
	if (conn->error) {
	    /* FIXME: need to tear down send queues and random other things
	     * maybe this should be abstracted */
	    xmpp_debug(ctx, "xmpp", "Send error occured, disconnecting.");
	    conn->error = ECONNABORTED;
	    conn_disconnect(conn);
	}

	connitem = connitem->next;
    }

    /* reset parsers if needed */
    for (connitem = ctx->connlist; connitem; connitem = connitem->next) {
	if (connitem->conn->reset_parser)
	    conn_parser_reset(connitem->conn);
    }


    /* fire any ready timed handlers, then
       make sure we don't wait past the time when timed handlers need
       to be called */
    next = handler_fire_timed(ctx);

    usec = ((next < timeout) ? next : timeout) * 1000;
    tv.tv_sec = usec / 1000000;
    tv.tv_usec = usec % 1000000;

    FD_ZERO(&rfds);
    FD_ZERO(&wfds);

    /* find events to watch */
    connitem = ctx->connlist;
    while (connitem) {
	conn = connitem->conn;

	switch (conn->state) {
	case XMPP_STATE_CONNECTING:
	    /* connect has been called and we're waiting for it to complete */
	    /* connection will give us write or error events */

	    /* make sure the timeout hasn't expired */
	    if (time_elapsed(conn->timeout_stamp, time_stamp()) <=
		conn->connect_timeout)
		FD_SET(conn->sock, &wfds);
	    else {
		conn->error = ETIMEDOUT;
		xmpp_info(ctx, "xmpp", "Connection attempt timed out.");
		conn_disconnect(conn);
	    }
	    break;
	case XMPP_STATE_CONNECTED:
	    FD_SET(conn->sock, &rfds);
	    break;
	case XMPP_STATE_DISCONNECTED:
	    /* do nothing */
	default:
	    break;
	}

	/* Check if there is something in the SSL buffer. */
	if (conn->tls) {
	    tls_read_bytes += tls_pending(conn->tls);
	}

	if (conn->state != XMPP_STATE_DISCONNECTED && conn->sock > max)
	    max = conn->sock;

	connitem = connitem->next;
    }

    /* check for events */
    if (max > 0)
        ret = select(max + 1, &rfds,  &wfds, NULL, &tv);
    else {
        if (timeout > 0)
            _sleep(timeout);
        return;
    }

    /* select errored */
    if (ret < 0) {
	if (!sock_is_recoverable(sock_error()))
	    xmpp_error(ctx, "xmpp", "event watcher internal error %d",
		       sock_error());
	return;
    }

    /* no events happened */
    if (ret == 0 && tls_read_bytes == 0) return;

    /* process events */
    connitem = ctx->connlist;
    while (connitem) {
	conn = connitem->conn;

	switch (conn->state) {
	case XMPP_STATE_CONNECTING:
	    if (FD_ISSET(conn->sock, &wfds)) {
		/* connection complete */

		/* check for error */
                ret = sock_connect_error(conn->sock);
		if (ret != 0) {
		    /* connection failed */
		    xmpp_debug(ctx, "xmpp", "connection failed, error %d", ret);
		    conn_disconnect(conn);
		    break;
		}

		conn->state = XMPP_STATE_CONNECTED;
		xmpp_debug(ctx, "xmpp", "connection successful");

        if (conn->tls_legacy_ssl) {
            xmpp_debug(ctx, "xmpp", "using legacy SSL connection");
            ret = conn_tls_start(conn);
            if (ret != 0) {
                conn_disconnect(conn);
                break;
            }
        }

		/* send stream init */
		conn_open_stream(conn);
	    }

	    break;
	case XMPP_STATE_CONNECTED:
	    if (FD_ISSET(conn->sock, &rfds) || (conn->tls && tls_pending(conn->tls))) {
		if (conn->tls) {
		    ret = tls_read(conn->tls, buf, 4096);
		} else {
		    ret = sock_read(conn->sock, buf, 4096);
		}

		if (ret > 0) {
		    ret = parser_feed(conn->parser, buf, ret);
		    if (!ret) {
			/* parse error, we need to shut down */
			/* FIXME */
			xmpp_debug(ctx, "xmpp", "parse error, disconnecting");
			conn_disconnect(conn);
		    }
		} else {
		    if (conn->tls) {
			if (!tls_is_recoverable(tls_error(conn->tls)))
			{
			    xmpp_debug(ctx, "xmpp", "Unrecoverable TLS error, %d.", tls_error(conn->tls));
			    conn->error = tls_error(conn->tls);
			    conn_disconnect(conn);
			}
		    } else {
			/* return of 0 means socket closed by server */
			xmpp_debug(ctx, "xmpp", "Socket closed by remote host.");
			conn->error = ECONNRESET;
			conn_disconnect(conn);
		    }
		}
	    }

	    break;
	case XMPP_STATE_DISCONNECTED:
	    /* do nothing */
	default:
	    break;
	}

	connitem = connitem->next;
    }

    /* fire any ready handlers */
    handler_fire_timed(ctx);
}
Пример #30
0
/* Read length bytes from tcp socket to stream and return it.
 * Appends to stream s if specified, otherwise it uses stream from tcp layer.
 * Will block until data available.
 * Returns NULL on error. */
STREAM
tcp_recv(rdpTcp * tcp, STREAM s, uint32 length)
{
	int rcvd = 0;
	uint32 p_offset;
	uint32 new_length;
	uint32 end_offset;

	if (s == NULL)
	{
		/* read into "new" stream */
		if (length > tcp->in.size)
		{
			tcp->in.data = (uint8 *) xrealloc(tcp->in.data, length);
			tcp->in.size = length;
		}

		tcp->in.end = tcp->in.p = tcp->in.data;
		s = &(tcp->in);
	}
	else
	{
		/* append to existing stream */
		new_length = (s->end - s->data) + length;
		if (new_length > s->size)
		{
			p_offset = s->p - s->data;
			end_offset = s->end - s->data;
			s->data = (uint8 *) xrealloc(s->data, new_length);
			s->size = new_length;
			s->p = s->data + p_offset;
			s->end = s->data + end_offset;
		}
	}

	while (length > 0)
	{
#ifndef DISABLE_TLS
		if (tcp->iso->mcs->sec->tls_connected)
		{
			rcvd = tls_read(tcp->iso->mcs->sec->ssl, (char*) s->end, length);

			if (rcvd < 0)
				return NULL;
		}
		else
#endif
		{
			if (!ui_select(tcp->iso->mcs->sec->rdp->inst, tcp->sock))
				return NULL; /* user quit */

			rcvd = recv(tcp->sock, s->end, length, 0);
			if (rcvd < 0)
			{
				if (rcvd == -1 && TCP_BLOCKS)
				{
					tcp_can_recv(tcp->sock, 1);
					rcvd = 0;
				}
				else
				{
					ui_error(tcp->iso->mcs->sec->rdp->inst, "recv: %s\n", TCP_STRERROR);
					return NULL;
				}
			}
			else if (rcvd == 0)
			{
				ui_error(tcp->iso->mcs->sec->rdp->inst, "Connection closed\n");
				return NULL;
			}
		}

		s->end += rcvd;
		length -= rcvd;
	}

	return s;
}