📄 msproxy_clientprotocol.c
字号:
/* * 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_DECLSstatic intmsproxy_connect __P((int s, int control, struct socks_t *packet));static intmsproxy_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 voidmsproxy_sessionsend __P((void));/* * Terminates all msproxy sessions. */static voidmsproxy_sessionend __P((int s, struct msproxy_state_t *msproxy));/* * ends the session negotiated with "s" and having state "msproxy". */static voidmsproxy_keepalive __P((int signal));/* * Sends a keepalive packet on behalf of all established sessions. */static voidsigio __P((int sig));__END_DECLSintmsproxy_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;}intmsproxy_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 intmsproxy_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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -