#include #include #include #define PROXY_BUFFER_SIZE 512 #define PROXY_PORT 443 typedef struct { SOCKET in; SOCKET out; } PipeDef; SOCKET Accept(SOCKET listener) { struct sockaddr_in sin; int sinsize = sizeof(sin); return accept(listener, (struct sockaddr*)&sin, &sinsize); } SOCKET Listen(int nPort) { SOCKET sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sd != INVALID_SOCKET) { struct sockaddr_in sinInterface; sinInterface.sin_family = AF_INET; sinInterface.sin_addr.s_addr = INADDR_ANY; sinInterface.sin_port = htons(nPort); if (bind(sd, (struct sockaddr*)&sinInterface, sizeof(struct sockaddr)) != SOCKET_ERROR) { listen(sd, 25); return sd; } } return INVALID_SOCKET; } SOCKET Connect (LPSTR server, WORD port) { SOCKET client; struct hostent host; struct sockaddr_in sin; host = *(struct hostent *) gethostbyname (server); client = socket (AF_INET, SOCK_STREAM, 0); memset (&sin, 0, sizeof sin); sin.sin_family = AF_INET; sin.sin_addr.s_addr = ((struct in_addr *) (host.h_addr))->s_addr; sin.sin_port = htons (port); if (connect (client, &sin, sizeof sin) == SOCKET_ERROR) return INVALID_SOCKET; return client; } void ClearCache(SOCKET s) { int recvd; char buf[64]; do { recvd = recv(s, buf, 64, 0); } while (recvd == 64); } void SocketPipe(PipeDef *Pipe) { char * Buffer = malloc(PROXY_BUFFER_SIZE); int recvd = 0; memset(Buffer, 0, PROXY_BUFFER_SIZE); while (recvd = recv(Pipe->in, Buffer, PROXY_BUFFER_SIZE - 1, 0)) send(Pipe->out, Buffer, recvd, 0); ClearCache(Pipe->in); shutdown(Pipe->out, 0); shutdown(Pipe->in, 0); closesocket(Pipe->out); closesocket(Pipe->in); free(Pipe); } char * RecvString(SOCKET s, char * string, int maxlen) { int i = 0; char c; while (recv(s, &c, 1, 0)) { if (c == '\r' || c == '\n' || c == '\0') { *(string + i) = 0; return i; } *(string+i) = c; i++; } return i; } int main() { WSADATA w; WSAStartup(MAKEWORD(2,0), &w); PipeDef *There, *Here; printf("TPR1.0\n"); SOCKET listener, s, dest; char * header = malloc(512), *connect, *host, *method, *actual, *temp; int port = 0, dummy, get; listener = Listen(PROXY_PORT); while (listener != INVALID_SOCKET) { s = Accept(listener); memset(header, 0, 512); RecvString(s, header, 512); host = strdup(header); method = strtok(host, " "); connect = strtok(NULL, " "); if (strcasecmp(method, "CONNECT") == 0) { // handle CONNECT get = 0; actual = strtok(connect, ":"); // host port = atoi(strtok(NULL, "\0")); // port ClearCache(s); } else { get = 1; // assume HTTP connect += 7; // skip http:// actual = strtok(connect, "/"); // trim trailing / if (temp = strchr(actual, ':')) { // port specified? *temp = 0; temp++; port = atoi(temp); // nab it } } if (port == 0) port = 80; // fixup dest = Connect(actual, port); Here = malloc(sizeof(PipeDef)); There = malloc(sizeof(PipeDef)); There->in = Here->out = s; Here->in = There->out = dest; if (get) send(dest, header, strlen(header), 0); CreateThread(NULL, 0, SocketPipe, There, 0, &dummy); CreateThread(NULL, 0, SocketPipe, Here, 0, &dummy); printf("."); free(host); } return 6; }