| 10 | |
| 11 | |
| 12 | int clientnegotiate(struct chain * redir, struct clientparam * param, struct sockaddr * addr){ |
| 13 | unsigned char *buf; |
| 14 | unsigned char *username; |
| 15 | int res; |
| 16 | int len=0; |
| 17 | unsigned char * user, *pass; |
| 18 | |
| 19 | |
| 20 | user = redir->extuser; |
| 21 | pass = redir->extpass; |
| 22 | if (param->srvinbuf < 4096){ |
| 23 | if(param->srvbuf)myfree(param->srvbuf); |
| 24 | param->srvbuf = myalloc(4096); |
| 25 | param->srvbufsize = 4096; |
| 26 | } |
| 27 | buf = param->srvbuf; |
| 28 | username = buf + 2048; |
| 29 | if(user) { |
| 30 | if (*user == '*') { |
| 31 | if(!param->username) return 4; |
| 32 | user = param->username; |
| 33 | pass = param->password; |
| 34 | } |
| 35 | } |
| 36 | switch(redir->type){ |
| 37 | case R_TCP: |
| 38 | case R_HTTP: |
| 39 | return 0; |
| 40 | case R_CONNECT: |
| 41 | case R_CONNECTP: |
| 42 | { |
| 43 | len = sprintf((char *)buf, "CONNECT "); |
| 44 | if(redir->type == R_CONNECTP && param->hostname) { |
| 45 | char * needreplace; |
| 46 | needreplace = strchr((char *)param->hostname, ':'); |
| 47 | if(needreplace) buf[len++] = '['; |
| 48 | len += sprintf((char *)buf + len, "%.256s", (char *)param->hostname); |
| 49 | if(needreplace) buf[len++] = ']'; |
| 50 | } |
| 51 | else { |
| 52 | if(*SAFAMILY(addr) == AF_INET6) buf[len++] = '['; |
| 53 | len += myinet_ntop(*SAFAMILY(addr), SAADDR(addr), (char *)buf+len, 256); |
| 54 | if(*SAFAMILY(addr) == AF_INET6) buf[len++] = ']'; |
| 55 | } |
| 56 | len += sprintf((char *)buf + len, |
| 57 | ":%hu HTTP/1.0\r\nProxy-Connection: keep-alive\r\n", ntohs(*SAPORT(addr))); |
| 58 | if(user){ |
| 59 | len += sprintf((char *)buf + len, "Proxy-authorization: basic "); |
| 60 | sprintf((char *)username, "%.128s:%.128s", user, pass?pass:(unsigned char *)""); |
| 61 | en64(username, buf+len, (int)strlen((char *)username)); |
| 62 | len = (int)strlen((char *)buf); |
| 63 | len += sprintf((char *)buf + len, "\r\n"); |
| 64 | } |
| 65 | len += sprintf((char *)buf + len, "\r\n"); |
| 66 | if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != (int)strlen((char *)buf)) |
| 67 | return 31; |
| 68 | param->statssrv64+=len; |
| 69 | param->nwrites++; |
no test coverage detected