コード例 #1
0
ファイル: privsep.c プロジェクト: ft/debian_fdm
int
privsep_recv(struct io *io, struct msg *msg, struct msgbuf *msgbuf)
{
	char	*tmpbuf;

	if (msgbuf != NULL) {
		msgbuf->buf = NULL;
		msgbuf->len = 0;
	}

	if (io_wait(io, sizeof *msg, INFTIM, NULL) != 0)
		return (-1);
	if (io_read2(io, msg, sizeof *msg) != 0)
		return (-1);

	if (msg->size == 0)
		return (0);

	if (io_wait(io, msg->size, INFTIM, NULL) != 0)
		return (-1);
	if (msgbuf == NULL) {
		if ((tmpbuf = io_read(io, msg->size)) == NULL)
			return (-1);
		xfree(tmpbuf);
	} else {
		if ((msgbuf->buf = io_read(io, msg->size)) == NULL)
			return (-1);
		msgbuf->len = msg->size;
	}

	return (0);
}
コード例 #2
0
ファイル: connect.c プロジェクト: avkrotov/fdm
int
socks5proxy(struct server *srv,
    struct proxy *pr, struct io *io, int timeout, char **cause)
{
	int	port, auth;
	char	buf[1024], *ptr;
	size_t	len;

	if ((port = getport(srv->port)) < 0) {
		xasprintf(cause, "bad port: %s", srv->port);
		return (-1);
	}

	/* Method selection. */
	auth = pr->user != NULL && pr->pass != NULL;
	buf[0] = 5;
	buf[1] = auth ? 2 : 1;
	buf[2] = 0;	/* 0 = no auth */
	buf[3] = 2;	/* 2 = user/pass auth */
	io_write(io, buf, auth ? 4 : 3);

	if (io_wait(io, 2, timeout, cause) != 0)
		return (-1);
	io_read2(io, buf, 2);
	if (buf[0] != 5) {
		xasprintf(cause, "bad protocol version: %d", buf[0]);
		return (-1);
	}
	if ((buf[1] != 0 && buf[1] != 2) || (auth == 0 && buf[1] == 2)) {
		xasprintf(cause, "unexpected method: %d", buf[1]);
		return (-1);
	}

	/* User/pass negotiation. */
	if (buf[1] == 2) {
		ptr = buf;
		*ptr++ = 5;
		len = strlen(pr->user);
		if (len > 255) {
			xasprintf(cause, "user too long");
			return (-1);
		}
		*ptr++ = len;
		memcpy(ptr, pr->user, len);
		ptr += len;
		len = strlen(pr->pass);
		if (len > 255) {
			xasprintf(cause, "pass too long");
			return (-1);
		}
		*ptr++ = len;
		memcpy(ptr, pr->pass, len);
		ptr += len;
		io_write(io, buf, ptr - buf);

		if (io_wait(io, 2, timeout, cause) != 0)
			return (-1);
		io_read2(io, buf, 2);
		if (buf[0] != 5) {
			xasprintf(cause, "bad protocol version: %d", buf[0]);
			return (-1);
		}
		if (buf[1] != 0) {
			xasprintf(cause, "authentication failed");
			return (-1);
		}
	}

	/* Connect request. */
	ptr = buf;
	*ptr++ = 5;
	*ptr++ = 1; /* 1 = connect */
	*ptr++ = 0; /* reserved */
	*ptr++ = 3; /* 3 = domain name */
	len = strlen(srv->host);
	if (len > 255) {
		xasprintf(cause, "host too long");
		return (-1);
	}
	*ptr++ = len;
	memcpy(ptr, srv->host, len);
	ptr += len;
	*ptr++ = (port >> 8) & 0xff;
	*ptr++ = port & 0xff;
	io_write(io, buf, ptr - buf);

	/* Connect response. */
	if (io_wait(io, 5, timeout, cause) != 0)
		return (-1);
	io_read2(io, buf, 5);
	if (buf[0] != 5) {
		xasprintf(cause, "bad protocol version: %d", buf[0]);
		return (-1);
	}
	switch (buf[1]) {
	case 0:
		break;
	case 1:
		xasprintf(cause, "%d: server failure", buf[1]);
		return (-1);
	case 2:
		xasprintf(cause, "%d: connection not permitted", buf[1]);
		return (-1);
	case 3:
		xasprintf(cause, "%d: network unreachable", buf[1]);
		return (-1);
	case 4:
		xasprintf(cause, "%d: host unreachable", buf[1]);
		return (-1);
	case 5:
		xasprintf(cause, "%d: connection refused", buf[1]);
		return (-1);
	case 6:
		xasprintf(cause, "%d: TTL expired", buf[1]);
		return (-1);
	case 7:
		xasprintf(cause, "%d: command not supported", buf[1]);
		return (-1);
	case 8:
		xasprintf(cause, "%d: address type not supported", buf[1]);
		return (-1);
	default:
		xasprintf(cause, "%d: unknown failure", buf[1]);
		return (-1);
	}

	/* Flush the rest. */
	switch (buf[3]) {
	case 1: /* IPv4 */
		len = 5;
		break;
	case 3: /* host */
		len = buf[4] + 2;
		break;
	case 4: /* IPv6 */
		len = 17;
		break;
	default:
		xasprintf(cause, "unknown address type: %d", buf[3]);
		return (-1);
	}
	if (io_wait(io, len, timeout, cause) != 0)
		return (-1);
	io_read2(io, buf, len);

	return (0);
}