summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2013-03-09 14:50:58 +0100
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2013-03-09 15:31:43 +0100
commitf3acc95c926749eaefda4dfec49cad586125e80a (patch)
treefcb650322eb68d2907d37e9fc271fc718b3ca81a
parent05ef536cc35015b0ba0d5a52c34db93b845b6beb (diff)
downloadecon-f3acc95c926749eaefda4dfec49cad586125e80a.tar.gz
econ-f3acc95c926749eaefda4dfec49cad586125e80a.tar.bz2
econ-f3acc95c926749eaefda4dfec49cad586125e80a.zip
econproxy: Add read_packet
Tries to verify packet integrity, e.g. datasize, recordCount.. Command 21 isnt handled yet, since that has another structure than other commands.
-rw-r--r--econproxy.c105
1 files changed, 79 insertions, 26 deletions
diff --git a/econproxy.c b/econproxy.c
index df9545f..ea20f54 100644
--- a/econproxy.c
+++ b/econproxy.c
@@ -87,6 +87,52 @@ send_packet(struct ep *ep)
return writev(ep->ec_fd, ep->iov, i);
}
+static int
+read_packet(struct ep *ep)
+{
+ ssize_t len;
+
+ init_iov(ep);
+
+ len = readv(ep->ec_fd, ep->iov, 3);
+ if (len < 0)
+ return -1;
+
+ if (len < sizeof(struct econ_header)) {
+ fprintf(stderr, "read_packet: error: incomplete header\n");
+ return -1;
+ }
+
+ if (len < sizeof(struct econ_header) + ep->ehdr.datasize) {
+ fprintf(stderr, "packet has invalid datasize\n");
+ return -1;
+ }
+
+ if (ep->ehdr.datasize > 0) {
+ if (ep->ehdr.datasize < sizeof(struct econ_command)) {
+ fprintf(stderr,
+ "read_packet: error: command to short\n");
+ return -1;
+ }
+
+ if (ep->ecmd.recordCount > 0) {
+ if (ep->ecmd.recordCount > 1) {
+ fprintf(stderr, "read_packet: did not expect a"
+ " packet with more that one record: %d, datasize: %d.\n",
+ ep->ecmd.recordCount, ep->ehdr.datasize);
+ return -1;
+ }
+ if (ep->ehdr.datasize != (sizeof (struct econ_command) +
+ sizeof (struct econ_record))) {
+ fprintf(stderr, "read_packet: datasize incorrect\n");
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
static void
write_ppm(FILE *img, int width, int height, int bpp, uint8_t *buf)
{
@@ -115,35 +161,43 @@ ep_keepalive(struct ep *ep)
static int
ep_get_clientinfo(struct ep *ep)
{
- char buf[BUFSIZ], buf2[BUFSIZ];
- size_t len;
-
init_packet(ep, E_CMD_IPSEARCH);
send_packet(ep);
- len = read(ep->ec_fd, buf, BUFSIZ);
- struct econ_header *hdr = (void *) buf;
- printf("cmd: %d, len: %zd\n", hdr->commandID, len);
+ if (read_packet(ep) < 0)
+ return -1;
+ if (ep->ehdr.commandID != E_CMD_CLIENTINFO) {
+ fprintf(stderr, "expected clientinfo, got: %d\n",
+ ep->ehdr.commandID);
+ return -1;
+ }
- if (len < (sizeof (struct econ_header) +
- sizeof (struct econ_command) +
- sizeof (struct econ_record))) {
- fprintf(stderr, "error: Invalid packet received.\n");
+ if (ep->ehdr.datasize == 0 || ep->ecmd.recordCount == 0) {
+ fprintf(stderr, "missing record in clientinfo\n");
return -1;
}
+ printf("clientinfo: read cmd: %d\n", ep->ehdr.commandID);
- struct econ_command *ecmd = (void *) (buf + sizeof (struct econ_header));
printf("clientinfo unknown value: %hu\n",
- ecmd->command.clientinfo.unknown_field_1);
+ ep->ecmd.command.clientinfo.unknown_field_1);
/* cache projUniqInfo needed for reqconnect */
- struct econ_record *erec = (void *) (buf + sizeof (struct econ_header) +
- sizeof (struct econ_command));
- memcpy(ep->projUniqInfo, erec->projUniqInfo, ECON_UNIQINFO_LENGTH);
+ memcpy(ep->projUniqInfo, ep->erec.projUniqInfo, ECON_UNIQINFO_LENGTH);
#if 1
- len = read(ep->ec_fd, buf2, BUFSIZ);
- hdr = (void *) buf2;
+ char buf[BUFSIZ];
+ ssize_t len = read(ep->ec_fd, buf, BUFSIZ);
+ struct econ_header *hdr = (void *) buf;
printf("cmd: %d, len: %zd\n", hdr->commandID, len);
+#if 0
+ if (read_packet(ep) < 0)
+ return -1;
+#endif
+
+ if (hdr->commandID != 21) {
+ fprintf(stderr, "expected ex clientinfo (21), got: %d\n",
+ hdr->commandID);
+ return -1;
+ }
#endif
return 0;
@@ -204,7 +258,8 @@ ep_reqconnect(struct ep *ep, rfbServerInitMsg *vnes)
send_packet(ep);
- readv(ep->ec_fd, ep->iov, 3);
+ if (read_packet(ep) < 0)
+ return -1;
if (ep->ehdr.commandID != E_CMD_CONNECTED) {
fprintf(stderr, "failed to connect: command was: %d\n",
ep->ehdr.commandID);
@@ -233,15 +288,8 @@ create_data_sockets(struct ep *ep, const char *beamer)
static int
ep_read_ack(struct ep *ep)
{
- size_t len;
-
- init_iov(ep);
-
- len = readv(ep->ec_fd, ep->iov, 2);
- if (len < ep->iov[0].iov_len + ep->iov[1].iov_len) {
- fprintf(stderr, "error: command received is to short\n");
+ if (read_packet(ep) < 0)
return -1;
- }
switch (ep->ehdr.commandID) {
/* cack for connection video sockets */
@@ -258,6 +306,11 @@ ep_read_ack(struct ep *ep)
return -1;
}
+ if (ep->ehdr.datasize == 0) {
+ fprintf(stderr, "error: command 22 received is to short\n");
+ return -1;
+ }
+
init_packet(ep, E_CMD_25);
ep->ehdr.datasize = sizeof ep->ecmd;
ep->ecmd.command.cmd25.unknown_field1 = 1;