static int send_socks_request(struct connreq *conn) { int rc = 0; if (conn->path->type == 4) rc = send_socksv4_request(conn); else rc = send_socksv5_method(conn); return(rc); }
static int send_socks_request(struct connreq *conn) { int rc = 0; #ifdef USE_TOR_DNS if (conn->path->type == 4) { char *name = get_pool_entry(pool, &(conn->connaddr.sin_addr)); if(name != NULL) { rc = send_socksv4a_request(conn,name); } else { rc = send_socksv4_request(conn); } #else if (conn->path->type == 4) { rc = send_socksv4_request(conn); #endif } else { rc = send_socksv5_method(conn); } return(rc); } #ifdef USE_TOR_DNS static int send_socksv4a_request(struct connreq *conn,const char *onion_host) { struct passwd *user; struct sockreq *thisreq; int endOfUser; /* Determine the current username */ user = getpwuid(getuid()); thisreq = (struct sockreq *) conn->buffer; endOfUser=sizeof(struct sockreq) + (user == NULL ? 0 : strlen(user->pw_name)) + 1; /* Check the buffer has enough space for the request */ /* and the user name */ conn->datalen = endOfUser+ (onion_host == NULL ? 0 : strlen(onion_host)) + 1; if (sizeof(conn->buffer) < conn->datalen) { show_msg(MSGERR, "The SOCKS username is too long"); conn->state = FAILED; return(ECONNREFUSED); } /* Create the request */ thisreq->version = 4; thisreq->command = 1; thisreq->dstport = conn->connaddr.sin_port; thisreq->dstip = htonl(1); /* Copy the username */ strcpy((char *) thisreq + sizeof(struct sockreq), (user == NULL ? "" : user->pw_name)); /* Copy the onion host */ strcpy((char *) thisreq + endOfUser, (onion_host == NULL ? "" : onion_host)); conn->datadone = 0; conn->state = SENDING; conn->nextstate = SENTV4REQ; return(0); } #endif /* USE_TOR_DNS */ static int send_socksv4_request(struct connreq *conn) { struct passwd *user; struct sockreq *thisreq; /* Determine the current username */ user = getpwuid(getuid()); thisreq = (struct sockreq *) conn->buffer; /* Check the buffer has enough space for the request */ /* and the user name */ conn->datalen = sizeof(struct sockreq) + (user == NULL ? 0 : strlen(user->pw_name)) + 1; if (sizeof(conn->buffer) < conn->datalen) { show_msg(MSGERR, "The SOCKS username is too long"); conn->state = FAILED; return(ECONNREFUSED); } /* Create the request */ thisreq->version = 4; thisreq->command = 1; thisreq->dstport = conn->connaddr.sin_port; thisreq->dstip = conn->connaddr.sin_addr.s_addr; /* Copy the username */ strcpy((char *) thisreq + sizeof(struct sockreq), (user == NULL ? "" : user->pw_name)); conn->datadone = 0; conn->state = SENDING; conn->nextstate = SENTV4REQ; return(0); } static int send_socksv5_method(struct connreq *conn) { char verstring[] = { 0x05, /* Version 5 SOCKS */ 0x02, /* No. Methods */ 0x00, /* Null Auth */ 0x02 }; /* User/Pass Auth */ show_msg(MSGDEBUG, "Constructing V5 method negotiation\n"); conn->state = SENDING; conn->nextstate = SENTV5METHOD; memcpy(conn->buffer, verstring, sizeof(verstring)); conn->datalen = sizeof(verstring); conn->datadone = 0; return(0); }