msproxy_clientprotocol.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:57k
源码类别:
代理服务器
开发平台:
Unix_Linux
- /*
- * Copyright (c) 1997, 1998, 1999
- * Inferno Nettverk A/S, Norway. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. The above copyright notice, this list of conditions and the following
- * disclaimer must appear in all copies of the software, derivative works
- * or modified versions, and any portions thereof, aswell as in all
- * supporting documentation.
- * 2. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by
- * Inferno Nettverk A/S, Norway.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Inferno Nettverk A/S requests users of this software to return to
- *
- * Software Distribution Coordinator or sdc@inet.no
- * Inferno Nettverk A/S
- * Oslo Research Park
- * Gaustadal閑n 21
- * N-0349 Oslo
- * Norway
- *
- * any improvements or extensions that they make and grant Inferno Nettverk A/S
- * the rights to redistribute these changes.
- *
- */
- /*
- * This code is terrible so hopefully it will match the protocol.
- */
- #include "common.h"
- static const char rcsid[] =
- "$Id: msproxy_clientprotocol.c,v 1.22 1999/09/02 10:41:41 michaels Exp $";
- static char executable[] = "TELNET.EXE";
- static struct sigaction oldsigio;
- __BEGIN_DECLS
- static int
- msproxy_connect __P((int s, int control, struct socks_t *packet));
- static int
- msproxy_bind __P((int s, int control, struct socks_t *packet));
- static char *
- mem2response __P((struct msproxy_response_t *res, char *mem, size_t len));
- static char *
- request2mem __P((const struct msproxy_request_t *req, char *mem));
- static void
- msproxy_sessionsend __P((void));
- /*
- * Terminates all msproxy sessions.
- */
- static void
- msproxy_sessionend __P((int s, struct msproxy_state_t *msproxy));
- /*
- * ends the session negotiated with "s" and having state "msproxy".
- */
- static void
- msproxy_keepalive __P((int signal));
- /*
- * Sends a keepalive packet on behalf of all established sessions.
- */
- static void
- sigio __P((int sig));
- __END_DECLS
- int
- msproxy_init(void)
- {
- const char *function = "msproxy_init()";
- struct itimerval timerval;
- struct sigaction sigact, oldsigact;
- if (atexit(msproxy_sessionsend) != 0) {
- swarn("%s: atexit()", function);
- return -1;
- }
- if (sigaction(SIGALRM, NULL, &oldsigact) != 0) {
- swarn("%s: sigaction(SIGALRM)", function);
- return -1;
- }
- /* XXX */
- if (oldsigact.sa_handler != SIG_DFL
- && oldsigact.sa_handler != SIG_IGN) {
- swarnx("%s: could not install signalhandler for SIGALRM, already set",
- function);
- return 0; /* will probably timeout, don't consider it fatal for now. */
- }
- sigemptyset(&sigact.sa_mask);
- sigact.sa_flags = SA_RESTART;
- sigact.sa_handler = msproxy_keepalive;
- if (sigaction(SIGALRM, &sigact, NULL) != 0) {
- swarn("%s: sigaction(SIGALRM)", function);
- return -1;
- }
- timerval.it_value.tv_sec = MSPROXY_PINGINTERVAL;
- timerval.it_value.tv_usec = 0;
- timerval.it_interval = timerval.it_value;
- if (setitimer(ITIMER_REAL, &timerval, NULL) != 0) {
- swarn("%s: setitimer()", function);
- return -1;
- }
- srand((unsigned int)time(NULL) * getpid());
- return 0;
- }
- int
- msproxy_negotiate(s, control, packet)
- int s;
- int control;
- struct socks_t *packet;
- {
- const char *function = "msproxy_negotiate()";
- struct msproxy_request_t req;
- struct msproxy_response_t res;
- int p;
- slog(LOG_DEBUG, "%s: packet #1", function);
- bzero(&req, sizeof(req));
- req.clientid = htonl(0x0a000000);
- req.command = htons(MSPROXY_HELLO);
- /* in case we don't get something more sensible. */
- packet->res.version = packet->req.version;
- packet->res.reply = MSPROXY_FAILURE;
- switch (packet->req.command) {
- case SOCKS_BIND:
- #if 1
- req.packet._1.magic5 = htons(0x4800);
- req.packet._1.magic10 = htons(0x1400);
- req.packet._1.magic15 = htons(0x0400);
- req.packet._1.magic20 = htons(0x5704);
- req.packet._1.magic25 = htons(0x0004);
- req.packet._1.magic30 = htons(0x0100);
- req.packet._1.magic35 = htons(0x4a02);
- req.packet._1.magic40 = htons(0x3000);
- req.packet._1.magic45 = htons(0x4100);
- req.packet._1.magic50 = htons(0x3900);
- #endif
- break;
- case SOCKS_CONNECT:
- #if 0
- req.packet._1.magic5 = htons(0x4b00);
- req.packet._1.magic10 = htons(0x1400);
- req.packet._1.magic15 = htons(0x0400);
- req.packet._1.magic20 = htons(0x5704);
- req.packet._1.magic25 = htons(0x0004);
- req.packet._1.magic30 = htons(0x0100);
- req.packet._1.magic35 = htons(0x4a02);
- req.packet._1.magic40 = htons(0x3000);
- req.packet._1.magic45 = htons(0x4400);
- req.packet._1.magic50 = htons(0x3900);
- #endif
- break;
- case SOCKS_UDPASSOCIATE:
- SERRX(packet->req.command);
- /* NOTREACHED */
- default:
- SERRX(packet->req.command);
- }
- if (socks_getusername(&packet->gw.host, req.username, sizeof(req.username))
- == NULL)
- return -1;
- *req.unknown = NUL;
- strncpy(req.executable, executable, sizeof(req.executable) - 1);
- req.executable[sizeof(req.executable) - 1] = NUL;
- *req.clienthost = NUL;
- #if 0
- strncpy(req.clienthost, "foo", sizeof(req.clienthost) - 1);
- req.clienthost[sizeof(req.clienthost) - 1] = NUL;
- #endif
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- if (recv_mspresponse(control, &packet->state.msproxy, &res) == -1)
- return -1;
- if (strcmp(res.RWSP, "RWSP") != 0)
- serrx(EXIT_FAILURE, "expected "RWSP", got "%s"",
- str2vis(res.RWSP, sizeof(res.RWSP)));
- if (ntohs(res.command) >> 8 != 0x10)
- serrx(EXIT_FAILURE, "expected res.command = 10??, is %x",
- ntohs(res.command));
- packet->state.msproxy.controladdr.sin_family = AF_INET;
- packet->state.msproxy.controladdr.sin_port = res.packet._1.udpport;
- packet->state.msproxy.controladdr.sin_addr.s_addr = res.packet._1.udpaddr;
- packet->state.msproxy.clientid = htonl(rand());
- packet->state.msproxy.serverid = res.serverid;
- slog(LOG_DEBUG, "%s: clientid: 0x%x, serverid: 0x%0x",
- function, packet->state.msproxy.clientid, packet->state.msproxy.serverid);
- /* LINTED pointer casts may be troublesome */
- slog(LOG_DEBUG, "%s: msproxy controladdress: %s",
- function,
- sockaddr2string((struct sockaddr *)&packet->state.msproxy.controladdr,
- NULL, 0));
- slog(LOG_DEBUG, "%s: packet #2", function);
- /* almost identical. */
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- if (recv_mspresponse(control, &packet->state.msproxy, &res) == -1)
- return -1;
- if (res.serverid != packet->state.msproxy.serverid)
- serrx(EXIT_FAILURE, "expected serverid = 0x%x, is 0x%x",
- packet->state.msproxy.serverid, res.serverid);
- if (res.sequence != 0x01)
- serrx(EXIT_FAILURE, "expected res.sequence = 0x%x, is 0x%x",
- 0x01, res.sequence);
- if (ntohs(res.command) != MSPROXY_USERINFO_ACK)
- serrx(EXIT_FAILURE, "expected res.command = 0x%x, is 0x%x",
- MSPROXY_USERINFO_ACK, ntohs(res.command));
- switch (packet->req.command) {
- case SOCKS_BIND:
- p = msproxy_bind(s, control, packet);
- break;
- case SOCKS_CONNECT:
- p = msproxy_connect(s, control, packet);
- break;
- case SOCKS_UDPASSOCIATE:
- default:
- SERRX(packet->req.command);
- }
- return p;
- }
- static int
- msproxy_connect(s, control, packet)
- int s;
- int control;
- struct socks_t *packet;
- {
- const char *function = "msproxy_connect()";
- struct msproxy_request_t req;
- struct msproxy_response_t res;
- struct sockaddr_in addr;
- socklen_t len;
- slog(LOG_DEBUG, function);
- #if 0
- bzero(&req, sizeof(req));
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- req.command = htons(MSPROXY_SOMETHING);
- memcpy(req.packet._3.NTLMSSP, "NTLMSSP", sizeof("NTLMSSP"));
- req.packet._3.bindaddr = htonl(0x02000000);
- req.packet._3.magic5 = htons(0x0100);
- req.packet._3.magic10 = htons(0x9682);
- #if 0
- req.packet._3.magic50 = htons(0x3000);
- req.packet._3.magic55 = htons(0x3000);
- #endif
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- if (recv_mspresponse(control, &packet->state.msproxy, &res) == -1)
- return -1;
- if (res.serverid != packet->state.msproxy.serverid)
- serrx(EXIT_FAILURE, "expected serverid = 0x%x, is 0x%x",
- packet->state.msproxy.serverid, res.serverid);
- if (ntohs(res.command) != MSPROXY_SOMETHING_1_ACK)
- serrx(EXIT_FAILURE, "expected res.command = 0x%x, is 0x%x",
- MSPROXY_SOMETHING_1_ACK, ntohs(res.command));
- slog(LOG_DEBUG, "%s: ntdomain: "%s"", function, res.packet._3.ntdomain);
- slog(LOG_DEBUG, "%s: packet #4", function);
- bzero(&req, sizeof(req));
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- req.command = htons(MSPROXY_SOMETHING_2);
- #if 0
- memcpy(req.packet._4.NTLMSSP, "NTLMSSP", sizeof("NTLMSSP"));
- req.packet._4.magic3 = htons(0x0200);
- req.packet._4.magic5 = htons(0x0300);
- req.packet._4.magic10 = htons(0x1800);
- req.packet._4.magic15 = htons(0x1800);
- req.packet._4.magic20 = htons(0x4900);
- req.packet._4.magic30 = htons(0x6100);
- req.packet._4.magic35 = htons(0x0800);
- req.packet._4.magic40 = htons(0x0800);
- req.packet._4.magic45 = htons(0x3400);
- req.packet._4.magic50 = htons(0x0700);
- req.packet._4.magic55 = htons(0x0700);
- req.packet._4.magic60 = htons(0x3c00);
- req.packet._4.magic65 = htons(0x0600);
- req.packet._4.magic70 = htons(0x0600);
- req.packet._4.magic75 = htons(0x4300);
- #endif
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- if (recv_mspresponse(control, &packet->state.msproxy, &res) == -1)
- return -1;
- if (res.serverid != packet->state.msproxy.serverid)
- serrx(EXIT_FAILURE, "expected res.serverid = 0x%x, is 0x%x",
- packet->state.msproxy.serverid, res.serverid);
- if (res.clientack != 0x01)
- serrx(EXIT_FAILURE, "expected res.clientack = 0x%x, is 0x%x",
- 0x01, res.clientack);
- if (ntohs(res.command) >> 8 != 0x47)
- serrx(EXIT_FAILURE, "expected res.command = 47??, is 0x%x",
- ntohs(res.command));
- #endif
- switch (packet->req.host.atype) {
- case SOCKS_ADDR_IPV4:
- /* LINTED pointer casts may be troublesome */
- sockshost2sockaddr(&packet->req.host, (struct sockaddr *)&addr);
- break;
- case SOCKS_ADDR_DOMAIN:
- slog(LOG_DEBUG, "%s: resolve packet", function);
- bzero(&req, sizeof(req));
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- req.command = htons(MSPROXY_RESOLVE);
- req.packet.resolve.hostlength
- = (unsigned char)(strlen(packet->req.host.addr.domain) + 1);
- memcpy(&req.packet.resolve.host, packet->req.host.addr.domain,
- (size_t)req.packet.resolve.hostlength);
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- if (recv_mspresponse(control, &packet->state.msproxy, &res) == -1)
- return -1;
- if (ntohs(res.command) != MSPROXY_RESOLVE_ACK)
- serrx(EXIT_FAILURE, "expected res.command = 0x%x, is 0x%x",
- MSPROXY_RESOLVE_ACK, ntohs(res.command));
- addr.sin_addr.s_addr = res.packet.resolve.hostaddr;
- slog(LOG_DEBUG, "%s: ip address of %s: %s",
- function, packet->req.host.addr.domain, inet_ntoa(addr.sin_addr));
- break;
- default:
- SERRX(packet->req.host.atype);
- }
- slog(LOG_DEBUG, "%s: packet #5", function);
- bzero(&req, sizeof(req));
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- req.command = htons(MSPROXY_CONNECT);
- req.packet._5.magic6 = htons(0x0200);
- req.packet._5.destport = packet->req.host.port;
- req.packet._5.destaddr = addr.sin_addr.s_addr;
- /*
- * need to tell server what port we will connect from, so if socket
- * is not bound, bind it.
- */
- len = sizeof(addr);
- /* LINTED pointer casts may be troublesome */
- if (getsockname(s, (struct sockaddr *)&addr, &len) != 0)
- return -1;
- if (!ADDRISBOUND(addr)) {
- /*
- * Don't have any specific preference for what address to bind and
- * proxyserver only expects to be told port.
- */
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- /* LINTED pointer casts may be troublesome */
- if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
- return -1;
- len = sizeof(addr);
- /* LINTED pointer casts may be troublesome */
- if (getsockname(s, (struct sockaddr *)&addr, &len) != 0)
- return -1;
- }
- req.packet._5.srcport = addr.sin_port;
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- if (recv_mspresponse(control, &packet->state.msproxy, &res) == -1)
- return -1;
- if (ntohs(res.command) != MSPROXY_CONNECT_ACK) {
- swarnx("expected res.command = 0x%x, is 0x%x",
- MSPROXY_CONNECT_ACK, ntohs(res.command));
- packet->res.reply = MSPROXY_NOTALLOWED;
- return -1;
- }
- packet->res.host.atype = SOCKS_ADDR_IPV4;
- packet->res.host.port = res.packet._5.clientport;
- packet->res.host.addr.ipv4.s_addr = res.packet._5.clientaddr;
- if (socks_connect(s, &packet->res.host) != 0) {
- swarn("%s: failed to connect to %s",
- function, sockshost2string(&packet->res.host, NULL, 0));
- return -1;
- }
- else
- slog(LOG_DEBUG, "%s: connected to %s",
- function, sockshost2string(&packet->res.host, NULL, 0));
- packet->res.host.atype = SOCKS_ADDR_IPV4;
- packet->res.host.port = res.packet._5.clientport;
- packet->res.host.addr.ipv4.s_addr = res.packet._5.clientaddr;
- /* LINTED pointer casts may be troublesome */
- slog(LOG_DEBUG, "%s: server will use as source address: %s",
- function, sockshost2string(&packet->res.host, NULL, 0));
- slog(LOG_DEBUG, "%s: packet #6", function);
- bzero(&req, sizeof(req));
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- req.command = htons(MSPROXY_CONNECTED);
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- /* make response look sensible. */
- packet->res.version = packet->req.version;
- packet->res.reply = MSPROXY_SUCCESS;
- packet->res.flag = 0;
- packet->res.auth = NULL;
- return 0;
- }
- static int
- msproxy_bind(s, control, packet)
- int s;
- int control;
- struct socks_t *packet;
- {
- const char *function = "msproxy_bind()";
- struct msproxy_request_t req;
- struct msproxy_response_t res;
- struct sockaddr_in addr;
- socklen_t len;
- slog(LOG_DEBUG, function);
- bzero(&req, sizeof(req));
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- req.command = htons(MSPROXY_BIND);
- req.packet._3.magic2 = htons(0x0100);
- req.packet._3.bindaddr = packet->req.host.addr.ipv4.s_addr;
- req.packet._3.bindport = packet->req.host.port;
- req.packet._3.magic3 = htons(0x0200);
- len = sizeof(addr);
- /* LINTED pointer casts may be troublesome */
- if (getsockname(s, (struct sockaddr *)&addr, &len) != 0)
- return -1;
- req.packet._3.boundport = addr.sin_port;
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- if (recv_mspresponse(control, &packet->state.msproxy, &res) == -1)
- return -1;
- if (res.serverid != packet->state.msproxy.serverid)
- serrx(EXIT_FAILURE, "expected serverid = 0x%x, is 0x%x",
- packet->state.msproxy.serverid, res.serverid);
- if (ntohs(res.command) != MSPROXY_BIND_ACK) {
- swarnx("expected res.command = 0x%x, is 0x%x",
- MSPROXY_BIND_ACK, ntohs(res.command));
- packet->res.reply = MSPROXY_NOTALLOWED;
- return -1;
- }
- packet->state.msproxy.bindid = res.packet._3.magic10;
- packet->res.host.atype = SOCKS_ADDR_IPV4;
- packet->res.host.port = res.packet._3.boundport;
- packet->res.host.addr.ipv4.s_addr = res.packet._3.boundaddr;
- slog(LOG_DEBUG, "%s: server bound for us: %s",
- function, sockshost2string(&packet->res.host, NULL, 0));
- slog(LOG_DEBUG, "%s: packet #4", function);
- bzero(&req, sizeof(req));
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- req.command = htons(MSPROXY_BIND2);
- req.packet._4.magic1 = htons(0x0100);
- req.packet._4.magic2 = packet->state.msproxy.bindid;
- req.packet._4.magic3 = htons(0x0500);
- memcpy(req.packet._4.pad3 + 2, &addr.sin_port, sizeof(addr.sin_port));
- req.packet._4.magic4 = htons(0x0200);
- req.packet._4.boundport = addr.sin_port;
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- if (recv_mspresponse(control, &packet->state.msproxy, &res) == -1)
- return -1;
- if (res.serverid != packet->state.msproxy.serverid)
- serrx(EXIT_FAILURE, "expected res.serverid = 0x%x, is 0x%x",
- packet->state.msproxy.serverid, res.serverid);
- if (res.clientack != 0x01)
- serrx(EXIT_FAILURE, "expected res.clientack = 0x%x, is 0x%x",
- 0x01, res.clientack);
- if (ntohs(res.command) != MSPROXY_BIND2_ACK) {
- swarnx("expected res.command = %x, is 0x%x",
- MSPROXY_BIND2_ACK, ntohs(res.command));
- return -1;
- }
- slog(LOG_DEBUG, "%s: packet #5", function);
- bzero(&req, sizeof(req));
- req.clientid = packet->state.msproxy.clientid;
- req.serverid = packet->state.msproxy.serverid;
- req.command = htons(MSPROXY_LISTEN);
- req.packet._5.magic6 = htons(0x0200);
- req.packet._5.destport = packet->res.host.port;
- req.packet._5.destaddr = packet->res.host.addr.ipv4.s_addr;
- if (send_msprequest(control, &packet->state.msproxy, &req) == -1)
- return -1;
- /*
- * When the server accepts the client, it will send us a new
- * controlpacket. That will be caught in sigio().
- */
- slog(LOG_DEBUG, "%s: waiting for forwarded connection...", function);
- /* make response look sensible. */
- packet->res.version = packet->req.version;
- packet->res.reply = MSPROXY_SUCCESS;
- packet->res.flag = 0;
- packet->res.auth = NULL;
- return 0;
- }
- int
- msproxy_sigio(s)
- int s;
- {
- const char *function = "msproxy_sigio()";
- static int init;
- const int errno_s = errno;
- struct socksfd_t *socksfd;
- int p;
- /*
- * The msproxy protocol sends a udp packet which we must ack
- * before it will connect to us. We set up the controlsocket
- * for signaldriven i/o so we can ack it asynchronously.
- *
- */
- SASSERTX(socks_addrisok((unsigned int)s));
- socksfd = socks_getaddr((unsigned int)s);
- SASSERTX(socksfd->state.version == MSPROXY_V2);
- if (!init) { /* could be smarter about this... */
- struct sigaction sigact;
- sigemptyset(&sigact.sa_mask);
- sigact.sa_flags = SA_RESTART;
- sigact.sa_handler = sigio;
- if (sigaction(SIGIO, &sigact, &oldsigio) != 0)
- return -1;
- init = 1;
- }
- if (fcntl(socksfd->control, F_SETOWN, getpid()) == -1)
- return -1;
- p = 1;
- if (ioctl(socksfd->control, FIOASYNC, &p) == -1)
- return -1;
- slog(LOG_DEBUG, "%s: set up sigio for %d", function, socksfd->control);
- errno = errno_s;
- return 0;
- }
- /* ARGSUSED */
- static void
- sigio(sig)
- int sig;
- {
- const char *function = "sigio()";
- const int errno_s = errno;
- int i, max, dset;
- struct socksfd_t *socksfd;
- fd_set rset;
- struct timeval timeout;
- int dbits;
- slog(LOG_DEBUG, function);
- /*
- * Find the socket we were signalled for.
- */
- dbits = -1;
- FD_ZERO(&rset);
- for (i = 0, max = getdtablesize(); i < max; ++i) {
- if ((socksfd = socks_getaddr((unsigned int)i)) == NULL)
- continue;
- if (socksfd->state.command != SOCKS_BIND
- || socksfd->state.version != MSPROXY_V2
- || !socksfd->state.inprogress)
- continue;
- if (!socks_addrisok((unsigned int)i))
- continue;
- SASSERTX(fdisopen(socksfd->control));
- FD_SET(socksfd->control, &rset);
- dbits = MAX(dbits, socksfd->control);
- }
- if (dbits == -1) {
- if (oldsigio.sa_handler != NULL)
- oldsigio.sa_handler(sig);
- return; /* old signal handler. */
- }
- dset = 0;
- do {
- fd_set newrset;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- newrset = rset;
- switch (selectn(dbits + 1, &newrset, NULL, NULL, &timeout)) {
- case -1:
- SERR(-1);
- /* NOTREACHED */
- case 0:
- dset = 0;
- slog(LOG_DEBUG, "%s: no descriptors readable", function);
- if (oldsigio.sa_handler != NULL)
- oldsigio.sa_handler(sig);
- break;
- default: {
- dset = 1;
- for (i = 0, max = getdtablesize(); i < max; ++i) {
- if ((socksfd = socks_getaddr((unsigned int)i)) == NULL)
- continue;
- if (FD_ISSET(socksfd->control, &newrset)) {
- struct sockshost_t host;
- struct msproxy_request_t req;
- struct msproxy_response_t res;
- int p;
- SASSERTX(socksfd->state.command == SOCKS_BIND
- && socksfd->state.version == MSPROXY_V2
- && socksfd->state.inprogress);
- slog(LOG_DEBUG, "%s: attempting to receive bind info...",
- function);
- FD_CLR(socksfd->control, &newrset);
- if (recv_mspresponse(socksfd->control,
- &socksfd->state.msproxy, &res) == -1)
- continue;
- if (ntohs(res.command) != MSPROXY_BINDINFO) {
- swarnx("%s: expected res.command = %x, is 0x%x",
- function, MSPROXY_BINDINFO, ntohs(res.command));
- continue;
- }
- /* no need for more signals on this socket. */
- p = 0;
- if (ioctl(socksfd->control, FIOASYNC, &p) == -1) {
- swarn("%s: ioctl(socksfd->control)", function);
- continue;
- }
- slog(LOG_DEBUG, "%s: turned off sigio for %d",
- function, socksfd->control);
- /*
- * if we asked server to bind INADDR_ANY, we don't know
- * what address it bound until now.
- */
- host.atype = SOCKS_ADDR_IPV4;
- host.port = res.packet._5.boundport;
- host.addr.ipv4.s_addr = res.packet._5.boundaddr;
- sockshost2sockaddr(&host, &socksfd->remote);
- slog(LOG_DEBUG, "%s: server bound address %s",
- function, sockshost2string(&host, NULL, 0));
- host.atype = SOCKS_ADDR_IPV4;
- host.port = res.packet._5.clientport;
- host.addr.ipv4.s_addr = res.packet._5.clientaddr;
- sockshost2sockaddr(&host, &socksfd->accepted);
- slog(LOG_DEBUG, "%s: server accepted: %s",
- function, sockshost2string(&host, NULL, 0));
- slog(LOG_DEBUG, "%s: server will connect to us from port %d",
- function, ntohs(res.packet._5.serverport));
- /* LINTED pointer casts may be troublesome */
- ((struct sockaddr_in *)&socksfd->reply)->sin_port
- = res.packet._5.serverport;
- slog(LOG_DEBUG, "%s: packet #6", function);
- bzero(&req, sizeof(req));
- req.clientid = socksfd->state.msproxy.clientid;
- req.serverid = socksfd->state.msproxy.serverid;
- req.command = htons(MSPROXY_BINDINFO_ACK);
- req.packet._6.magic1 = res.packet._5.magic1;
- req.packet._6.magic5 = htons(0x0100);
- req.packet._6.magic10 = socksfd->state.msproxy.bindid;
- req.packet._6.magic15 = htons(0x0100);
- req.packet._6.magic16 = socksfd->state.msproxy.bindid;
- req.packet._6.magic20 = htons(0x0200);
- req.packet._6.clientport = res.packet._5.clientport;
- req.packet._6.clientaddr = res.packet._5.clientaddr;
- req.packet._6.magic30 = res.packet._5.magic10;
- req.packet._6.magic35 = res.packet._5.magic15;
- req.packet._6.serverport = res.packet._5.serverport;
- req.packet._6.srcport = res.packet._5.srcport;
- req.packet._6.boundport = res.packet._5.boundport;
- req.packet._6.boundaddr = res.packet._5.boundaddr;
- if (send_msprequest(socksfd->control, &socksfd->state.msproxy,
- &req) == -1)
- continue;
- if (recv_mspresponse(socksfd->control,
- &socksfd->state.msproxy, &res) == -1)
- continue;
- /* all done. Can accept(). */
- socksfd->state.inprogress = 0;
- }
- }
- }
- }
- } while (dset != 0);
- errno = errno_s;
- }
- int
- recv_mspresponse(s, state, response)
- int s;
- struct msproxy_state_t *state;
- struct msproxy_response_t *response;
- {
- const char *function = "recv_mspresponse()";
- /* CONSTCOND */
- char responsemem[MAX(sizeof(*response), 1024)];
- ssize_t r;
- /* CONSTCOND */
- while (1) {
- if ((r = read(s, responsemem, sizeof(responsemem))) < MSPROXY_MINLENGTH) {
- swarn("%s: expected to read atleast %d, read %d",
- function, MSPROXY_MINLENGTH, r);
- return -1;
- }
- if (mem2response(response, responsemem, (size_t)r) == NULL) {
- swarnx("%s: bad response from server", function);
- return -1;
- }
- if (state->seq_recv > 0) {
- if (response->sequence == state->seq_recv + 1)
- break; /* all ok. */
- else if (response->sequence < state->seq_recv) {
- /*
- * sequence number less that last, sometimes this happens too,
- * don't know why.
- */
- slog(LOG_DEBUG, "%s: sequence (%d) < seq_recv (%d)",
- function, response->sequence, state->seq_recv);
- break;
- }
- else if (response->sequence == state->seq_recv) {
- slog(LOG_DEBUG, "%s: seq_recv: %d, dup response, seqnumber: 0x%x",
- function, state->seq_recv, response->sequence);
- if (response->clientack == state->seq_sent) {
- slog(LOG_DEBUG,
- "%s: ack matches last sent though, hoping it's a new one...",
- function);
- break;
- }
- }
- else if (response->sequence > state->seq_recv) {
- slog(LOG_DEBUG, "%s: sequence (%d) > seq_recv (%d)",
- function, response->sequence, state->seq_recv);
- break;
- }
- }
- else
- break; /* not started incrementing yet. */
- }
- state->seq_recv = response->sequence;
- return r;
- }
- int
- send_msprequest(s, state, request)
- int s;
- struct msproxy_state_t *state;
- struct msproxy_request_t *request;
- {
- const char *function = "send_msprequest()";
- ssize_t w;
- char requestmem[sizeof(struct msproxy_request_t)], *p;
- request->magic25 = htonl(MSPROXY_VERSION);
- request->serverack = state->seq_recv;
- /* don't start incrementing sequence until we are acking packet #2. */
- request->sequence
- = (unsigned char)(request->serverack >= 2 ? state->seq_sent + 1 : 0);
- memcpy(request->RWSP, "RWSP", sizeof(request->RWSP));
- p = request2mem(request, requestmem);
- /* all requests must be atleast MSPROXY_MINLENGTH it seems. */
- if (p - requestmem < MSPROXY_MINLENGTH) {
- bzero(p, (size_t)(MSPROXY_MINLENGTH - (p - requestmem)));
- p = requestmem + MSPROXY_MINLENGTH;
- }
- if ((w = write(s, requestmem, (size_t)(p - requestmem)))
- != (ssize_t)(p - requestmem)) {
- swarn("%s: write()", function);
- return -1;
- }
- state->seq_sent = request->sequence;
- return w;
- }
- static char *
- mem2response(res, mem, len)
- struct msproxy_response_t *res;
- char *mem;
- size_t len;
- {
- const char *function = "mem2response()";
- if (len < sizeof(res->packetid))
- return NULL;
- memcpy(&res->packetid, mem, sizeof(res->packetid));
- mem += sizeof(res->packetid);
- len -= sizeof(res->packetid);
- if (len < sizeof(res->magic5))
- return NULL;
- memcpy(&res->magic5, mem, sizeof(res->magic5));
- mem += sizeof(res->magic5);
- len -= sizeof(res->magic5);
- if (len < sizeof(res->serverid))
- return NULL;
- memcpy(&res->serverid, mem, sizeof(res->serverid));
- mem += sizeof(res->serverid);
- len -= sizeof(res->serverid);
- if (len < sizeof(res->clientack))
- return NULL;
- memcpy(&res->clientack, mem, sizeof(res->clientack));
- mem += sizeof(res->clientack);
- len -= sizeof(res->clientack);
- if (len < sizeof(res->pad5))
- return NULL;
- memcpy(res->pad5, mem, sizeof(res->pad5));
- mem += sizeof(res->pad5);
- len -= sizeof(res->pad5);
- if (len < sizeof(res->sequence))
- return NULL;
- memcpy(&res->sequence, mem, sizeof(res->sequence));
- mem += sizeof(res->sequence);
- len -= sizeof(res->sequence);
- if (len < sizeof(res->pad10))
- return NULL;
- memcpy(res->pad10, mem, sizeof(res->pad10));
- mem += sizeof(res->pad10);
- len -= sizeof(res->pad10);
- if (len < sizeof(res->RWSP))
- return NULL;
- memcpy(res->RWSP, mem, sizeof(res->RWSP));
- mem += sizeof(res->RWSP);
- len -= sizeof(res->RWSP);
- if (len < sizeof(res->pad15))
- return NULL;
- memcpy(res->pad15, mem, sizeof(res->pad15));
- mem += sizeof(res->pad15);
- len -= sizeof(res->pad15);
- if (len < sizeof(res->command))
- return NULL;
- memcpy(&res->command, mem, sizeof(res->command));
- mem += sizeof(res->command);
- len -= sizeof(res->command);
- switch (ntohs(res->command)) {
- case MSPROXY_HELLO_ACK:
- if (len < sizeof(res->packet._1.pad5))
- return NULL;
- memcpy(res->packet._1.pad5, mem, sizeof(res->packet._1.pad5));
- mem += sizeof(res->packet._1.pad5);
- len -= sizeof(res->packet._1.pad5);
- if (len < sizeof(res->packet._1.magic20))
- return NULL;
- memcpy(&res->packet._1.magic20, mem, sizeof(res->packet._1.magic20));
- mem += sizeof(res->packet._1.magic20);
- len -= sizeof(res->packet._1.magic20);
- if (len < sizeof(res->packet._1.pad10))
- return NULL;
- memcpy(&res->packet._1.pad10, mem, sizeof(res->packet._1.pad10));
- mem += sizeof(res->packet._1.pad10);
- len -= sizeof(res->packet._1.pad10);
- if (len < sizeof(res->packet._1.magic30))
- return NULL;
- memcpy(&res->packet._1.magic30, mem, sizeof(res->packet._1.magic30));
- mem += sizeof(res->packet._1.magic30);
- len -= sizeof(res->packet._1.magic30);
- if (len < sizeof(res->packet._1.pad15))
- return NULL;
- memcpy(res->packet._1.pad15, mem, sizeof(res->packet._1.pad15));
- mem += sizeof(res->packet._1.pad15);
- len -= sizeof(res->packet._1.pad15);
- if (len < sizeof(res->packet._1.magic35))
- return NULL;
- memcpy(&res->packet._1.magic35, mem, sizeof(res->packet._1.magic35));
- mem += sizeof(res->packet._1.magic35);
- len -= sizeof(res->packet._1.magic35);
- if (len < sizeof(res->packet._1.pad20))
- return NULL;
- memcpy(res->packet._1.pad20, mem, sizeof(res->packet._1.pad20));
- mem += sizeof(res->packet._1.pad20);
- len -= sizeof(res->packet._1.pad20);
- if (len < sizeof(res->packet._1.magic50))
- return NULL;
- memcpy(&res->packet._1.magic50, mem, sizeof(res->packet._1.magic50));
- mem += sizeof(res->packet._1.magic50);
- len -= sizeof(res->packet._1.magic50);
- if (len < sizeof(res->packet._1.pad30))
- return NULL;
- memcpy(res->packet._1.pad30, mem, sizeof(res->packet._1.pad30));
- mem += sizeof(res->packet._1.pad30);
- len -= sizeof(res->packet._1.pad30);
- if (len < sizeof(res->packet._1.magic60))
- return NULL;
- memcpy(&res->packet._1.magic60, mem, sizeof(res->packet._1.magic60));
- mem += sizeof(res->packet._1.magic60);
- len -= sizeof(res->packet._1.magic60);
- if (len < sizeof(res->packet._1.pad35))
- return NULL;
- memcpy(res->packet._1.pad35, mem, sizeof(res->packet._1.pad35));
- mem += sizeof(res->packet._1.pad35);
- len -= sizeof(res->packet._1.pad35);
- if (len < sizeof(res->packet._1.magic65))
- return NULL;
- memcpy(&res->packet._1.magic65, mem, sizeof(res->packet._1.magic65));
- mem += sizeof(res->packet._1.magic65);
- len -= sizeof(res->packet._1.magic65);
- if (len < sizeof(res->packet._1.pad40))
- return NULL;
- memcpy(res->packet._1.pad40, mem, sizeof(res->packet._1.pad40));
- mem += sizeof(res->packet._1.pad40);
- len -= sizeof(res->packet._1.pad40);
- if (len < sizeof(res->packet._1.udpport))
- return NULL;
- memcpy(&res->packet._1.udpport, mem, sizeof(res->packet._1.udpport));
- mem += sizeof(res->packet._1.udpport);
- len -= sizeof(res->packet._1.udpport);
- if (len < sizeof(res->packet._1.udpaddr))
- return NULL;
- memcpy(&res->packet._1.udpaddr, mem, sizeof(res->packet._1.udpaddr));
- mem += sizeof(res->packet._1.udpaddr);
- len -= sizeof(res->packet._1.udpaddr);
- break;
- case MSPROXY_USERINFO_ACK:
- if (len < sizeof(res->packet._2.pad5))
- return NULL;
- memcpy(res->packet._2.pad5, mem, sizeof(res->packet._2.pad5));
- mem += sizeof(res->packet._2.pad5);
- len -= sizeof(res->packet._2.pad5);
- if (len < sizeof(res->packet._2.magic5))
- return NULL;
- memcpy(&res->packet._2.magic5, mem, sizeof(res->packet._2.magic5));
- mem += sizeof(res->packet._2.magic5);
- len -= sizeof(res->packet._2.magic5);
- break;
- case MSPROXY_BIND_ACK:
- case MSPROXY_SOMETHING_1_ACK:
- if (len < sizeof(res->packet._3.pad1))
- return NULL;
- memcpy(res->packet._3.pad1, mem, sizeof(res->packet._3.pad1));
- mem += sizeof(res->packet._3.pad1);
- len -= sizeof(res->packet._3.pad1);
- if (len < sizeof(res->packet._3.magic10))
- return NULL;
- memcpy(&res->packet._3.magic10, mem, sizeof(res->packet._3.magic10));
- mem += sizeof(res->packet._3.magic10);
- len -= sizeof(res->packet._3.magic10);
- if (len < sizeof(res->packet._3.pad3))
- return NULL;
- memcpy(res->packet._3.pad3, mem, sizeof(res->packet._3.pad3));
- mem += sizeof(res->packet._3.pad3);
- len -= sizeof(res->packet._3.pad3);
- if (len < sizeof(res->packet._3.boundport))
- return NULL;
- memcpy(&res->packet._3.boundport, mem,
- sizeof(res->packet._3.boundport));
- mem += sizeof(res->packet._3.boundport);
- len -= sizeof(res->packet._3.boundport);
- if (len < sizeof(res->packet._3.boundaddr))
- return NULL;
- memcpy(&res->packet._3.boundaddr, mem,
- sizeof(res->packet._3.boundaddr));
- mem += sizeof(res->packet._3.boundaddr);
- len -= sizeof(res->packet._3.boundaddr);
- if (len < sizeof(res->packet._3.pad10))
- return NULL;
- memcpy(res->packet._3.pad10, mem, sizeof(res->packet._3.pad10));
- mem += sizeof(res->packet._3.pad10);
- len -= sizeof(res->packet._3.pad10);
- if (len < sizeof(res->packet._3.magic15))
- return NULL;
- memcpy(&res->packet._3.magic15, mem, sizeof(res->packet._3.magic15));
- mem += sizeof(res->packet._3.magic15);
- len -= sizeof(res->packet._3.magic15);
- if (len < sizeof(res->packet._3.pad15))
- return NULL;
- memcpy(res->packet._3.pad15, mem, sizeof(res->packet._3.pad15));
- mem += sizeof(res->packet._3.pad15);
- len -= sizeof(res->packet._3.pad15);
- if (len < sizeof(res->packet._3.NTLMSSP))
- return NULL;
- memcpy(res->packet._3.NTLMSSP, mem, sizeof(res->packet._3.NTLMSSP));
- mem += sizeof(res->packet._3.NTLMSSP);
- len -= sizeof(res->packet._3.NTLMSSP);
- if (len < sizeof(res->packet._3.magic50))
- return NULL;
- memcpy(&res->packet._3.magic50, mem, sizeof(res->packet._3.magic50));
- mem += sizeof(res->packet._3.magic50);
- len -= sizeof(res->packet._3.magic50);
- if (len < sizeof(res->packet._3.pad50))
- return NULL;
- memcpy(res->packet._3.pad50, mem, sizeof(res->packet._3.pad50));
- mem += sizeof(res->packet._3.pad50);
- len -= sizeof(res->packet._3.pad50);
- if (len < sizeof(res->packet._3.magic55))
- return NULL;
- memcpy(&res->packet._3.magic55, mem, sizeof(res->packet._3.magic55));
- mem += sizeof(res->packet._3.magic55);
- len -= sizeof(res->packet._3.magic55);
- if (len < sizeof(res->packet._3.magic60))
- return NULL;
- memcpy(&res->packet._3.magic60, mem, sizeof(res->packet._3.magic60));
- mem += sizeof(res->packet._3.magic60);
- len -= sizeof(res->packet._3.magic60);
- if (len < sizeof(res->packet._3.magic65))
- return NULL;
- memcpy(&res->packet._3.magic65, mem, sizeof(res->packet._3.magic65));
- mem += sizeof(res->packet._3.magic65);
- len -= sizeof(res->packet._3.magic65);
- if (len < sizeof(res->packet._3.pad60))
- return NULL;
- memcpy(res->packet._3.pad60, mem, sizeof(res->packet._3.pad60));
- mem += sizeof(res->packet._3.pad60);
- len -= sizeof(res->packet._3.pad60);
- if (len < sizeof(res->packet._3.magic70))
- return NULL;
- memcpy(&res->packet._3.magic70, mem, sizeof(res->packet._3.magic70));
- mem += sizeof(res->packet._3.magic70);
- len -= sizeof(res->packet._3.magic70);
- if (len < sizeof(res->packet._3.magic75))
- return NULL;
- memcpy(&res->packet._3.magic75, mem, sizeof(res->packet._3.magic75));
- mem += sizeof(res->packet._3.magic75);
- len -= sizeof(res->packet._3.magic75);
- if (len < sizeof(res->packet._3.pad70))
- return NULL;
- memcpy(res->packet._3.pad70, mem, sizeof(res->packet._3.pad70));
- mem += sizeof(res->packet._3.pad70);
- len -= sizeof(res->packet._3.pad70);
- if (len > sizeof(res->packet._3.ntdomain))
- swarnx("hmm, ntdomain length is %d, our max is %d?",
- len, sizeof(res->packet._3.ntdomain) - 1);
- memcpy(res->packet._3.ntdomain, mem,
- MIN(len, sizeof(res->packet._3.ntdomain) - 1));
- res->packet._3.ntdomain[len] = NUL;
- mem += len;
- len -= len;
- break;
- case MSPROXY_SOMETHING_2_ACK:
- case MSPROXY_SOMETHING_2_ACK2:
- case MSPROXY_BIND2_ACK:
- if (len < sizeof(res->packet._4.pad5))
- return NULL;
- memcpy(res->packet._4.pad5, mem, sizeof(res->packet._4.pad5));
- mem += sizeof(res->packet._4.pad5);
- len -= sizeof(res->packet._4.pad5);
- break;
- case MSPROXY_RESOLVE_ACK: {
- if (len < sizeof(res->packet.resolve.addroffset))
- return NULL;
- memcpy(&res->packet.resolve.addroffset, mem,
- sizeof(res->packet.resolve.addroffset));
- mem += sizeof(res->packet.resolve.addroffset);
- len -= sizeof(res->packet.resolve.addroffset);
- if (len < sizeof(res->packet.resolve.pad5))
- return NULL;
- memcpy(res->packet.resolve.pad5, mem,
- sizeof(res->packet.resolve.pad5));
- mem += sizeof(res->packet.resolve.pad5);
- len -= sizeof(res->packet.resolve.pad5);
- mem += res->packet.resolve.addroffset;
- if (len < sizeof(res->packet.resolve.hostaddr))
- return NULL;
- memcpy(&res->packet.resolve.hostaddr, mem,
- sizeof(res->packet.resolve.hostaddr));
- mem += sizeof(res->packet.resolve.hostaddr);
- len -= sizeof(res->packet.resolve.hostaddr);
- break;
- }
- case MSPROXY_CONNECT_ACK:
- case MSPROXY_BINDINFO:
- if (len < sizeof(res->packet._5.magic1))
- return NULL;
- memcpy(&res->packet._5.magic1, mem, sizeof(res->packet._5.magic1));
- mem += sizeof(res->packet._5.magic1);
- len -= sizeof(res->packet._5.magic1);
- if (len < sizeof(res->packet._5.pad5))
- return NULL;
- memcpy(res->packet._5.pad5, mem, sizeof(res->packet._5.pad5));
- mem += sizeof(res->packet._5.pad5);
- len -= sizeof(res->packet._5.pad5);
- if (len < sizeof(res->packet._5.clientport))
- return NULL;
- memcpy(&res->packet._5.clientport, mem,
- sizeof(res->packet._5.clientport));
- mem += sizeof(res->packet._5.clientport);
- len -= sizeof(res->packet._5.clientport);
- if (len < sizeof(res->packet._5.clientaddr))
- return NULL;
- memcpy(&res->packet._5.clientaddr, mem,
- sizeof(res->packet._5.clientaddr));
- mem += sizeof(res->packet._5.clientaddr);
- len -= sizeof(res->packet._5.clientaddr);
- if (len < sizeof(res->packet._5.magic10))
- return NULL;
- memcpy(&res->packet._5.magic10, mem, sizeof(res->packet._5.magic10));
- mem += sizeof(res->packet._5.magic10);
- len -= sizeof(res->packet._5.magic10);
- if (len < sizeof(res->packet._5.magic15))
- return NULL;
- memcpy(&res->packet._5.magic15, mem, sizeof(res->packet._5.magic15));
- mem += sizeof(res->packet._5.magic15);
- len -= sizeof(res->packet._5.magic15);
- if (len < sizeof(res->packet._5.serverport))
- return NULL;
- memcpy(&res->packet._5.serverport, mem,
- sizeof(res->packet._5.serverport));
- mem += sizeof(res->packet._5.serverport);
- len -= sizeof(res->packet._5.serverport);
- if (len < sizeof(res->packet._5.srcport))
- return NULL;
- memcpy(&res->packet._5.srcport, mem, sizeof(res->packet._5.srcport));
- mem += sizeof(res->packet._5.srcport);
- len -= sizeof(res->packet._5.srcport);
- if (len < sizeof(res->packet._5.boundport))
- return NULL;
- memcpy(&res->packet._5.boundport, mem,
- sizeof(res->packet._5.boundport));
- mem += sizeof(res->packet._5.boundport);
- len -= sizeof(res->packet._5.boundport);
- if (len < sizeof(res->packet._5.boundaddr))
- return NULL;
- memcpy(&res->packet._5.boundaddr, mem,
- sizeof(res->packet._5.boundaddr));
- mem += sizeof(res->packet._5.boundaddr);
- len -= sizeof(res->packet._5.boundaddr);
- if (len < sizeof(res->packet._5.pad10))
- return NULL;
- memcpy(res->packet._5.pad10, mem, sizeof(res->packet._5.pad10));
- mem += sizeof(res->packet._5.pad10);
- len -= sizeof(res->packet._5.pad10);
- break;
- case MSPROXY_CONNECT_AUTHFAILED:
- case MSPROXY_BIND_AUTHFAILED:
- break;
- default:
- if (ntohs(res->command) >> 8 == MSPROXY_CONNREFUSED
- || ntohs(res->command) >> 12 == MSPROXY_CONNREFUSED)
- ;
- else
- slog(LOG_DEBUG, "%s: unknown command in msproxy reply: 0x%x",
- function, ntohs(res->command));
- }
- return mem;
- }
- static char *
- request2mem(req, mem)
- const struct msproxy_request_t *req;
- char *mem;
- {
- memcpy(mem, &req->clientid, sizeof(req->clientid));
- mem += sizeof(req->clientid);
- memcpy(mem, &req->magic25, sizeof(req->magic25));
- mem += sizeof(req->magic25);
- memcpy(mem, &req->serverid, sizeof(req->serverid));
- mem += sizeof(req->serverid);
- memcpy(mem, &req->serverack, sizeof(req->serverack));
- mem += sizeof(req->serverack);
- memcpy(mem, &req->pad10, sizeof(req->pad10));
- mem += sizeof(req->pad10);
- memcpy(mem, &req->sequence, sizeof(req->sequence));
- mem += sizeof(req->sequence);
- memcpy(mem, &req->pad11, sizeof(req->pad11));
- mem += sizeof(req->pad11);
- memcpy(mem, &req->RWSP, sizeof(req->RWSP));
- mem += sizeof(req->RWSP);
- memcpy(mem, &req->pad15, sizeof(req->pad15));
- mem += sizeof(req->pad15);
- memcpy(mem, &req->command, sizeof(req->command));
- mem += sizeof(req->command);
- switch (ntohs(req->command)) {
- case MSPROXY_HELLO:
- memcpy(mem, &req->packet._1.pad1, sizeof(req->packet._1.pad1));
- mem += sizeof(req->packet._1.pad1);
- memcpy(mem, &req->packet._1.magic3, sizeof(req->packet._1.magic3));
- mem += sizeof(req->packet._1.magic3);
- memcpy(mem, &req->packet._1.pad3, sizeof(req->packet._1.pad3));
- mem += sizeof(req->packet._1.pad3);
- memcpy(mem, &req->packet._1.magic5, sizeof(req->packet._1.magic5));
- mem += sizeof(req->packet._1.magic5);
- memcpy(mem, &req->packet._1.pad5, sizeof(req->packet._1.pad5));
- mem += sizeof(req->packet._1.pad5);
- memcpy(mem, &req->packet._1.magic10, sizeof(req->packet._1.magic10));
- mem += sizeof(req->packet._1.magic10);
- memcpy(mem, &req->packet._1.pad6, sizeof(req->packet._1.pad6));
- mem += sizeof(req->packet._1.pad6);
- memcpy(mem, &req->packet._1.magic15, sizeof(req->packet._1.magic15));
- mem += sizeof(req->packet._1.magic15);
- memcpy(mem, &req->packet._1.pad10, sizeof(req->packet._1.pad10));
- mem += sizeof(req->packet._1.pad10);
- memcpy(mem, &req->packet._1.magic20, sizeof(req->packet._1.magic20));
- mem += sizeof(req->packet._1.magic20);
- memcpy(mem, &req->packet._1.magic25, sizeof(req->packet._1.magic25));
- mem += sizeof(req->packet._1.magic25);
- memcpy(mem, &req->packet._1.magic30, sizeof(req->packet._1.magic30));
- mem += sizeof(req->packet._1.magic30);
- memcpy(mem, &req->packet._1.pad20, sizeof(req->packet._1.pad20));
- mem += sizeof(req->packet._1.pad20);
- memcpy(mem, &req->packet._1.magic35, sizeof(req->packet._1.magic35));
- mem += sizeof(req->packet._1.magic35);
- memcpy(mem, &req->packet._1.pad30, sizeof(req->packet._1.pad30));
- mem += sizeof(req->packet._1.pad30);
- memcpy(mem, &req->packet._1.magic40, sizeof(req->packet._1.magic40));
- mem += sizeof(req->packet._1.magic40);
- memcpy(mem, &req->packet._1.pad40, sizeof(req->packet._1.pad40));
- mem += sizeof(req->packet._1.pad40);
- memcpy(mem, &req->packet._1.magic45, sizeof(req->packet._1.magic45));
- mem += sizeof(req->packet._1.magic45);
- memcpy(mem, &req->packet._1.pad45, sizeof(req->packet._1.pad45));
- mem += sizeof(req->packet._1.pad45);
- memcpy(mem, &req->packet._1.magic50, sizeof(req->packet._1.magic50));
- mem += sizeof(req->packet._1.magic50);
- memcpy(mem, &req->packet._1.pad50, sizeof(req->packet._1.pad50));
- mem += sizeof(req->packet._1.pad50);
- strcpy(mem, req->username);
- mem += strlen(req->username) + 1;
- strcpy(mem, req->unknown);
- mem += strlen(req->unknown) + 1;
- strcpy(mem, req->executable);
- mem += strlen(req->executable) + 1;
- strcpy(mem, req->clienthost);
- mem += strlen(req->clienthost) + 1;
- break;
- case MSPROXY_USERINFO:
- memcpy(mem, &req->packet._2.pad1, sizeof(req->packet._2.pad1));
- mem += sizeof(req->packet._2.pad1);
- memcpy(mem, &req->packet._2.magic3, sizeof(req->packet._2.magic3));
- mem += sizeof(req->packet._2.magic3);
- memcpy(mem, &req->packet._2.pad3, sizeof(req->packet._2.pad3));
- mem += sizeof(req->packet._2.pad3);
- memcpy(mem, &req->packet._2.magic5, sizeof(req->packet._2.magic5));
- mem += sizeof(req->packet._2.magic5);
- memcpy(mem, &req->packet._2.pad5, sizeof(req->packet._2.pad5));
- mem += sizeof(req->packet._2.pad5);
- memcpy(mem, &req->packet._2.magic10, sizeof(req->packet._2.magic10));
- mem += sizeof(req->packet._2.magic10);
- memcpy(mem, &req->packet._2.pad10, sizeof(req->packet._2.pad10));
- mem += sizeof(req->packet._2.pad10);
- memcpy(mem, &req->packet._2.magic15, sizeof(req->packet._2.magic15));
- mem += sizeof(req->packet._2.magic15);
- memcpy(mem, &req->packet._2.pad15, sizeof(req->packet._2.pad15));
- mem += sizeof(req->packet._2.pad15);
- memcpy(mem, &req->packet._2.magic20, sizeof(req->packet._2.magic20));
- mem += sizeof(req->packet._2.magic20);
- memcpy(mem, &req->packet._2.magic25, sizeof(req->packet._2.magic25));
- mem += sizeof(req->packet._2.magic25);
- memcpy(mem, &req->packet._2.magic30, sizeof(req->packet._2.magic30));
- mem += sizeof(req->packet._2.magic30);
- memcpy(mem, &req->packet._2.pad20, sizeof(req->packet._2.pad20));
- mem += sizeof(req->packet._2.pad20);
- memcpy(mem, &req->packet._2.magic35, sizeof(req->packet._2.magic35));
- mem += sizeof(req->packet._2.magic35);
- memcpy(mem, &req->packet._2.pad25, sizeof(req->packet._2.pad25));
- mem += sizeof(req->packet._2.pad25);
- memcpy(mem, &req->packet._2.magic35, sizeof(req->packet._2.magic35));
- mem += sizeof(req->packet._2.magic35);
- memcpy(mem, &req->packet._2.pad25, sizeof(req->packet._2.pad25));
- mem += sizeof(req->packet._2.pad25);
- memcpy(mem, &req->packet._2.magic50, sizeof(req->packet._2.magic50));
- mem += sizeof(req->packet._2.magic50);
- memcpy(mem, &req->packet._2.pad50, sizeof(req->packet._2.pad50));
- mem += sizeof(req->packet._2.pad50);
- memcpy(mem, &req->packet._2.magic55, sizeof(req->packet._2.magic55));
- mem += sizeof(req->packet._2.magic55);
- memcpy(mem, &req->packet._2.pad55, sizeof(req->packet._2.pad55));
- mem += sizeof(req->packet._2.pad55);
- memcpy(mem, &req->packet._2.magic60, sizeof(req->packet._2.magic60));
- mem += sizeof(req->packet._2.magic60);
- strcpy(mem, req->username);
- mem += strlen(req->username) + 1;
- strcpy(mem, req->unknown);
- mem += strlen(req->unknown) + 1;
- strcpy(mem, req->executable);
- mem += strlen(req->executable) + 1;
- strcpy(mem, req->clienthost);
- mem += strlen(req->clienthost) + 1;
- break;
- case MSPROXY_BIND:
- case MSPROXY_SOMETHING:
- memcpy(mem, &req->packet._3.pad1, sizeof(req->packet._3.pad1));
- mem += sizeof(req->packet._3.pad1);
- memcpy(mem, &req->packet._3.magic2, sizeof(req->packet._3.magic2));
- mem += sizeof(req->packet._3.magic2);
- memcpy(mem, &req->packet._3.pad10, sizeof(req->packet._3.pad10));
- mem += sizeof(req->packet._3.pad10);
- memcpy(mem, &req->packet._3.bindaddr, sizeof(req->packet._3.bindaddr));
- mem += sizeof(req->packet._3.bindaddr);
- memcpy(mem, &req->packet._3.bindport, sizeof(req->packet._3.bindport));
- mem += sizeof(req->packet._3.bindport);
- memcpy(mem, &req->packet._3.pad15, sizeof(req->packet._3.pad15));
- mem += sizeof(req->packet._3.pad15);
- memcpy(mem, &req->packet._3.magic3, sizeof(req->packet._3.magic3));
- mem += sizeof(req->packet._3.magic3);
- memcpy(mem, &req->packet._3.boundport,
- sizeof(req->packet._3.boundport));
- mem += sizeof(req->packet._3.boundport);
- memcpy(mem, &req->packet._3.pad20, sizeof(req->packet._3.pad20));
- mem += sizeof(req->packet._3.pad20);
- memcpy(mem, &req->packet._3.NTLMSSP, sizeof(req->packet._3.NTLMSSP));
- mem += sizeof(req->packet._3.NTLMSSP);
- memcpy(mem, &req->packet._3.magic5, sizeof(req->packet._3.magic5));
- mem += sizeof(req->packet._3.magic5);
- memcpy(mem, &req->packet._3.pad25, sizeof(req->packet._3.pad25));
- mem += sizeof(req->packet._3.pad25);
- memcpy(mem, &req->packet._3.magic10, sizeof(req->packet._3.magic10));
- mem += sizeof(req->packet._3.magic10);
- memcpy(mem, &req->packet._3.magic15, sizeof(req->packet._3.magic15));
- mem += sizeof(req->packet._3.magic15);
- memcpy(mem, &req->packet._3.magic20, sizeof(req->packet._3.magic20));
- mem += sizeof(req->packet._3.magic20);
- memcpy(mem, &req->packet._3.pad30, sizeof(req->packet._3.pad30));
- mem += sizeof(req->packet._3.pad30);
- memcpy(mem, &req->packet._3.magic25, sizeof(req->packet._3.magic25));
- mem += sizeof(req->packet._3.magic25);
- memcpy(mem, &req->packet._3.magic30, sizeof(req->packet._3.magic30));
- mem += sizeof(req->packet._3.magic30);
- memcpy(mem, &req->packet._3.pad40, sizeof(req->packet._3.pad40));
- mem += sizeof(req->packet._3.pad40);
- memcpy(mem, &req->packet._3.magic50, sizeof(req->packet._3.magic50));
- mem += sizeof(req->packet._3.magic50);
- memcpy(mem, &req->packet._3.pad50, sizeof(req->packet._3.pad50));
- mem += sizeof(req->packet._3.pad50);
- memcpy(mem, &req->packet._3.magic55, sizeof(req->packet._3.magic55));
- mem += sizeof(req->packet._3.magic55);
- memcpy(mem, &req->packet._3.pad55, sizeof(req->packet._3.pad55));
- mem += sizeof(req->packet._3.pad55);
- break;
- case MSPROXY_BIND2:
- case MSPROXY_SOMETHING_2:
- memcpy(mem, &req->packet._4.pad1, sizeof(req->packet._4.pad1));
- mem += sizeof(req->packet._4.pad1);
- memcpy(mem, &req->packet._4.magic1, sizeof(req->packet._4.magic1));
- mem += sizeof(req->packet._4.magic1);
- memcpy(mem, &req->packet._4.magic2, sizeof(req->packet._4.magic2));
- mem += sizeof(req->packet._4.magic2);
- memcpy(mem, &req->packet._4.pad2, sizeof(req->packet._4.pad2));
- mem += sizeof(req->packet._4.pad2);
- memcpy(mem, &req->packet._4.magic3, sizeof(req->packet._4.magic3));
- mem += sizeof(req->packet._4.magic3);
- memcpy(mem, &req->packet._4.pad3, sizeof(req->packet._4.pad3));
- mem += sizeof(req->packet._4.pad3);
- memcpy(mem, &req->packet._4.magic4, sizeof(req->packet._4.magic4));
- mem += sizeof(req->packet._4.magic4);
- memcpy(mem, &req->packet._4.boundport,
- sizeof(req->packet._4.boundport));
- mem += sizeof(req->packet._4.boundport);
- memcpy(mem, &req->packet._4.pad4, sizeof(req->packet._4.pad4));
- mem += sizeof(req->packet._4.pad4);
- memcpy(mem, &req->packet._4.NTLMSSP, sizeof(req->packet._4.NTLMSSP));
- mem += sizeof(req->packet._4.NTLMSSP);
- memcpy(mem, &req->packet._4.magic5, sizeof(req->packet._4.magic5));
- mem += sizeof(req->packet._4.magic5);
- memcpy(mem, &req->packet._4.pad5, sizeof(req->packet._4.pad5));
- mem += sizeof(req->packet._4.pad5);
- memcpy(mem, &req->packet._4.magic10, sizeof(req->packet._4.magic10));
- mem += sizeof(req->packet._4.magic10);
- memcpy(mem, &req->packet._4.magic10, sizeof(req->packet._4.magic10));
- mem += sizeof(req->packet._4.magic10);
- memcpy(mem, &req->packet._4.magic20, sizeof(req->packet._4.magic20));
- mem += sizeof(req->packet._4.magic20);
- memcpy(mem, &req->packet._4.pad10, sizeof(req->packet._4.pad10));
- mem += sizeof(req->packet._4.pad10);
- memcpy(mem, &req->packet._4.magic30, sizeof(req->packet._4.magic30));
- mem += sizeof(req->packet._4.magic30);
- memcpy(mem, &req->packet._4.pad15, sizeof(req->packet._4.pad15));
- mem += sizeof(req->packet._4.pad15);
- memcpy(mem, &req->packet._4.magic35, sizeof(req->packet._4.magic35));
- mem += sizeof(req->packet._4.magic35);
- memcpy(mem, &req->packet._4.magic40, sizeof(req->packet._4.magic40));
- mem += sizeof(req->packet._4.magic40);
- memcpy(mem, &req->packet._4.magic45, sizeof(req->packet._4.magic45));
- mem += sizeof(req->packet._4.magic45);
- memcpy(mem, &req->packet._4.pad20, sizeof(req->packet._4.pad20));
- mem += sizeof(req->packet._4.pad20);
- memcpy(mem, &req->packet._4.magic50, sizeof(req->packet._4.magic50));
- mem += sizeof(req->packet._4.magic50);
- memcpy(mem, &req->packet._4.magic55, sizeof(req->packet._4.magic55));
- mem += sizeof(req->packet._4.magic55);
- memcpy(mem, &req->packet._4.magic60, sizeof(req->packet._4.magic60));
- mem += sizeof(req->packet._4.magic60);
- memcpy(mem, &req->packet._4.pad25, sizeof(req->packet._4.pad25));
- mem += sizeof(req->packet._4.pad25);
- memcpy(mem, &req->packet._4.magic65, sizeof(req->packet._4.magic65));
- mem += sizeof(req->packet._4.magic65);
- memcpy(mem, &req->packet._4.magic70, sizeof(req->packet._4.magic70));
- mem += sizeof(req->packet._4.magic70);
- memcpy(mem, &req->packet._4.magic75, sizeof(req->packet._4.magic75));
- mem += sizeof(req->packet._4.magic75);
- break;
- case MSPROXY_RESOLVE:
- memcpy(mem, &req->packet.resolve.hostlength,
- sizeof(req->packet.resolve.hostlength));
- mem += sizeof(req->packet.resolve.hostlength);
- memcpy(mem, &req->packet.resolve.pad1,
- sizeof(req->packet.resolve.pad1));
- mem += sizeof(req->packet.resolve.pad1);
- memcpy(mem, &req->packet.resolve.host,
- (size_t)req->packet.resolve.hostlength);
- mem += req->packet.resolve.hostlength;
- break;
- case MSPROXY_LISTEN:
- case MSPROXY_CONNECT:
- memcpy(mem, &req->packet._5.magic1, sizeof(req->packet._5.magic1));
- mem += sizeof(req->packet._5.magic1);
- memcpy(mem, &req->packet._5.pad1, sizeof(req->packet._5.pad1));
- mem += sizeof(req->packet._5.pad1);
- memcpy(mem, &req->packet._5.magic3, sizeof(req->packet._5.magic3));
- mem += sizeof(req->packet._5.magic3);
- memcpy(mem, &req->packet._5.pad5, sizeof(req->packet._5.pad5));
- mem += sizeof(req->packet._5.pad5);
- memcpy(mem, &req->packet._5.magic6, sizeof(req->packet._5.magic6));
- mem += sizeof(req->packet._5.magic6);
- memcpy(mem, &req->packet._5.destport, sizeof(req->packet._5.destport));
- mem += sizeof(req->packet._5.destport);
- memcpy(mem, &req->packet._5.destaddr, sizeof(req->packet._5.destaddr));
- mem += sizeof(req->packet._5.destaddr);
- memcpy(mem, &req->packet._5.pad10, sizeof(req->packet._5.pad10));
- mem += sizeof(req->packet._5.pad10);
- memcpy(mem, &req->packet._5.magic10, sizeof(req->packet._5.magic10));
- mem += sizeof(req->packet._5.magic10);
- memcpy(mem, &req->packet._5.pad15, sizeof(req->packet._5.pad15));
- mem += sizeof(req->packet._5.pad15);
- memcpy(mem, &req->packet._5.srcport, sizeof(req->packet._5.srcport));
- mem += sizeof(req->packet._5.srcport);
- memcpy(mem, &req->packet._5.pad20, sizeof(req->packet._5.pad20));
- mem += sizeof(req->packet._5.pad20);
- strcpy(mem, req->executable);
- break;
- case MSPROXY_BINDINFO_ACK:
- case MSPROXY_CONNECTED:
- memcpy(mem, &req->packet._6.magic1, sizeof(req->packet._6.magic1));
- mem += sizeof(req->packet._6.magic1);
- memcpy(mem, req->packet._6.pad5, sizeof(req->packet._6.pad5));
- mem += sizeof(req->packet._6.pad5);
- memcpy(mem, &req->packet._6.magic5, sizeof(req->packet._6.magic5));
- mem += sizeof(req->packet._6.magic5);
- memcpy(mem, &req->packet._6.magic10, sizeof(req->packet._6.magic10));
- mem += sizeof(req->packet._6.magic10);
- memcpy(mem, req->packet._6.pad10, sizeof(req->packet._6.pad10));
- mem += sizeof(req->packet._6.pad10);
- memcpy(mem, &req->packet._6.magic15, sizeof(req->packet._6.magic15));
- mem += sizeof(req->packet._6.magic15);
- memcpy(mem, &req->packet._6.magic16, sizeof(req->packet._6.magic16));
- mem += sizeof(req->packet._6.magic16);
- memcpy(mem, &req->packet._6.magic20, sizeof(req->packet._6.magic20));
- mem += sizeof(req->packet._6.magic20);
- memcpy(mem, &req->packet._6.clientport,
- sizeof(req->packet._6.clientport));
- mem += sizeof(req->packet._6.clientport);
- memcpy(mem, &req->packet._6.clientaddr,
- sizeof(req->packet._6.clientaddr));
- mem += sizeof(req->packet._6.clientaddr);
- memcpy(mem, &req->packet._6.magic30, sizeof(req->packet._6.magic30));
- mem += sizeof(req->packet._6.magic30);
- memcpy(mem, &req->packet._6.magic35, sizeof(req->packet._6.magic35));
- mem += sizeof(req->packet._6.magic35);
- memcpy(mem, &req->packet._6.serverport,
- sizeof(req->packet._6.serverport));
- mem += sizeof(req->packet._6.serverport);
- memcpy(mem, &req->packet._6.srcport, sizeof(req->packet._6.srcport));
- mem += sizeof(req->packet._6.srcport);
- memcpy(mem, &req->packet._6.boundport,
- sizeof(req->packet._6.boundport));
- mem += sizeof(req->packet._6.boundport);
- memcpy(mem, &req->packet._6.boundaddr,
- sizeof(req->packet._6.boundaddr));
- mem += sizeof(req->packet._6.boundaddr);
- memcpy(mem, req->packet._6.pad30, sizeof(req->packet._6.pad30));
- mem += sizeof(req->packet._6.pad30);
- break;
- case MSPROXY_SESSIONEND:
- break;
- default:
- SERRX(req->command);
- }
- return mem;
- }
- void
- msproxy_sessionsend(void)
- {
- const char *function = "msproxy_sessionsend()";
- int i, max;
- struct socksfd_t *socksfd;
- slog(LOG_DEBUG, function);
- for (i = 0, max = getdtablesize(); i < max; ++i) {
- if ((socksfd = socks_getaddr((unsigned int)i)) == NULL)
- continue;
- if (socksfd->state.version != MSPROXY_V2)
- continue;
- msproxy_sessionend(socksfd->control, &socksfd->state.msproxy);
- }
- }
- static void
- msproxy_sessionend(s, msproxy)
- int s;
- struct msproxy_state_t *msproxy;
- {
- const char *function = "msproxy_sessionend()";
- struct msproxy_request_t req;
- slog(LOG_DEBUG, function);
- bzero(&req, sizeof(req));
- *req.username = NUL;
- *req.unknown = NUL;
- *req.executable = NUL;
- *req.clienthost = NUL;
- req.clientid = msproxy->clientid;
- req.serverid = msproxy->serverid;
- req.command = htons(MSPROXY_SESSIONEND);
- send_msprequest(s, msproxy, &req);
- }
- /* ARGSUSED */
- static void
- msproxy_keepalive(sig)
- int sig;
- {
- const char *function = "msproxy_keepalive()";
- struct msproxy_request_t req;
- struct msproxy_response_t res;
- struct socksfd_t *socksfd;
- int i, max;
- slog(LOG_DEBUG, function);
- for (i = 0, max = getdtablesize(); i < max; ++i) {
- if ((socksfd = socks_getaddr((unsigned int)i)) == NULL)
- continue;
- if (socksfd->state.version != MSPROXY_V2
- || socksfd->state.inprogress)
- continue;
- slog(LOG_DEBUG, "%s: sending keepalive packet", function);
- bzero(&req, sizeof(req));
- req.clientid = socksfd->state.msproxy.clientid;
- req.serverid = socksfd->state.msproxy.serverid;
- req.command = htons(MSPROXY_HELLO);
- if (send_msprequest(socksfd->control, &socksfd->state.msproxy, &req)
- == -1)
- return;
- if (recv_mspresponse(socksfd->control, &socksfd->state.msproxy, &res)
- == -1)
- return;
- }
- }