960 |
* - 1 if connexion fails |
* - 1 if connexion fails |
961 |
*/ |
*/ |
962 |
int |
int |
963 |
pass_httpproxy(t_irc_server *server) |
pass_httpproxy(int sock, char *address, int port) |
964 |
{ |
{ |
965 |
|
|
966 |
char buffer[256]; |
char buffer[256]; |
973 |
// authentification |
// authentification |
974 |
snprintf(authbuf, sizeof(authbuf), "%s:%s", cfg_proxy_username, cfg_proxy_password); |
snprintf(authbuf, sizeof(authbuf), "%s:%s", cfg_proxy_username, cfg_proxy_password); |
975 |
base64encode(authbuf, authbuf_base64); |
base64encode(authbuf, authbuf_base64); |
976 |
n = snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n", server->address, server->port, authbuf_base64); |
n = snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n", address, port, authbuf_base64); |
977 |
} |
} |
978 |
else |
else |
979 |
{ |
{ |
980 |
// no authentification |
// no authentification |
981 |
n = snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", server->address, server->port); |
n = snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", address, port); |
982 |
} |
} |
983 |
|
|
984 |
m = send (server->sock, buffer, n, 0); |
m = send (sock, buffer, n, 0); |
985 |
if (n != m) |
if (n != m) |
986 |
return 1; |
return 1; |
987 |
|
|
988 |
n = recv(server->sock, buffer, sizeof(buffer), 0); |
n = recv(sock, buffer, sizeof(buffer), 0); |
989 |
|
|
990 |
/* success result must be like : "HTTP/1.0 200 OK" */ |
/* success result must be like : "HTTP/1.0 200 OK" */ |
991 |
if (n < 12) |
if (n < 12) |
1047 |
* - 1 if connexion fails |
* - 1 if connexion fails |
1048 |
*/ |
*/ |
1049 |
int |
int |
1050 |
pass_socks4proxy(t_irc_server *server) |
pass_socks4proxy(int sock, char *address, int port, char *username) |
1051 |
{ |
{ |
1052 |
/* |
/* |
1053 |
* socks4 protocol is explain here: |
* socks4 protocol is explain here: |
1068 |
|
|
1069 |
socks4.version = 4; |
socks4.version = 4; |
1070 |
socks4.method = 1; |
socks4.method = 1; |
1071 |
socks4.port = htons (server->port); |
socks4.port = htons (port); |
1072 |
resolve(server->address, ip_addr, NULL); |
resolve(address, ip_addr, NULL); |
1073 |
socks4.address = inet_addr (ip_addr); |
socks4.address = inet_addr (ip_addr); |
1074 |
strncpy (socks4.user, server->username, sizeof(socks4.user) - 1); |
strncpy (socks4.user, username, sizeof(socks4.user) - 1); |
1075 |
|
|
1076 |
send (server->sock, (char *) &socks4, 8 + strlen(socks4.user) + 1, 0); |
send (sock, (char *) &socks4, 8 + strlen(socks4.user) + 1, 0); |
1077 |
recv (server->sock, buffer, sizeof(buffer), 0); |
recv (sock, buffer, sizeof(buffer), 0); |
1078 |
|
|
1079 |
if (buffer[0] == 0 && buffer[1] == 90) |
if (buffer[0] == 0 && buffer[1] == 90) |
1080 |
return 0; |
return 0; |
1089 |
* - 1 if connexion fails |
* - 1 if connexion fails |
1090 |
*/ |
*/ |
1091 |
int |
int |
1092 |
pass_socks5proxy(t_irc_server *server) |
pass_socks5proxy(int sock, char *address, int port) |
1093 |
{ |
{ |
1094 |
/* |
/* |
1095 |
* socks5 protocol is explained in RFC 1928 |
* socks5 protocol is explained in RFC 1928 |
1116 |
/* without authentication */ |
/* without authentication */ |
1117 |
socks5.method = 0; |
socks5.method = 0; |
1118 |
|
|
1119 |
send (server->sock, (char *) &socks5, sizeof(socks5), 0); |
send (sock, (char *) &socks5, sizeof(socks5), 0); |
1120 |
/* server socks5 must respond with 2 bytes */ |
/* server socks5 must respond with 2 bytes */ |
1121 |
if (recv (server->sock, buffer, 2, 0) != 2) |
if (recv (sock, buffer, 2, 0) != 2) |
1122 |
return 1; |
return 1; |
1123 |
|
|
1124 |
if (strlen(cfg_proxy_username) > 0) |
if (strlen(cfg_proxy_username) > 0) |
1144 |
buffer[2 + username_len] = (unsigned char) password_len; |
buffer[2 + username_len] = (unsigned char) password_len; |
1145 |
memcpy(buffer + 3 + username_len, cfg_proxy_password, password_len); |
memcpy(buffer + 3 + username_len, cfg_proxy_password, password_len); |
1146 |
|
|
1147 |
send (server->sock, buffer, 3 + username_len + password_len, 0); |
send (sock, buffer, 3 + username_len + password_len, 0); |
1148 |
|
|
1149 |
/* server socks5 must respond with 2 bytes */ |
/* server socks5 must respond with 2 bytes */ |
1150 |
if (recv (server->sock, buffer, 2, 0) != 2) |
if (recv (sock, buffer, 2, 0) != 2) |
1151 |
return 1; |
return 1; |
1152 |
|
|
1153 |
/* buffer[1] = auth state, must be 0 for success */ |
/* buffer[1] = auth state, must be 0 for success */ |
1166 |
} |
} |
1167 |
|
|
1168 |
/* authentication successful then giving address/port to connect */ |
/* authentication successful then giving address/port to connect */ |
1169 |
addr_len = strlen(server->address); |
addr_len = strlen(address); |
1170 |
addr_buffer_len = 4 + 1 + addr_len + 2; |
addr_buffer_len = 4 + 1 + addr_len + 2; |
1171 |
addr_buffer = (unsigned char *) malloc ( addr_buffer_len * sizeof(*addr_buffer)); |
addr_buffer = (unsigned char *) malloc ( addr_buffer_len * sizeof(*addr_buffer)); |
1172 |
if (!addr_buffer) |
if (!addr_buffer) |
1176 |
addr_buffer[2] = 0; /* reserved */ |
addr_buffer[2] = 0; /* reserved */ |
1177 |
addr_buffer[3] = 3; /* address type : ipv4 (1), domainname (3), ipv6 (4) */ |
addr_buffer[3] = 3; /* address type : ipv4 (1), domainname (3), ipv6 (4) */ |
1178 |
addr_buffer[4] = (unsigned char) addr_len; |
addr_buffer[4] = (unsigned char) addr_len; |
1179 |
memcpy (addr_buffer + 5, server->address, addr_len); /* server address */ |
memcpy (addr_buffer + 5, address, addr_len); /* server address */ |
1180 |
*((unsigned short *) (addr_buffer + 5 + addr_len)) = htons (server->port); /* server port */ |
*((unsigned short *) (addr_buffer + 5 + addr_len)) = htons (port); /* server port */ |
1181 |
|
|
1182 |
send (server->sock, addr_buffer, addr_buffer_len, 0); |
send (sock, addr_buffer, addr_buffer_len, 0); |
1183 |
free(addr_buffer); |
free(addr_buffer); |
1184 |
|
|
1185 |
/* dialog with proxy server */ |
/* dialog with proxy server */ |
1186 |
if (recv (server->sock, buffer, 4, 0) != 4) |
if (recv (sock, buffer, 4, 0) != 4) |
1187 |
return 1; |
return 1; |
1188 |
|
|
1189 |
if (!(buffer[0] == 5 && buffer[1] == 0)) |
if (!(buffer[0] == 5 && buffer[1] == 0)) |
1196 |
* server socks return server bound address and port |
* server socks return server bound address and port |
1197 |
* address of 4 bytes and port of 2 bytes (= 6 bytes) |
* address of 4 bytes and port of 2 bytes (= 6 bytes) |
1198 |
*/ |
*/ |
1199 |
if (recv (server->sock, buffer, 6, 0) != 6) |
if (recv (sock, buffer, 6, 0) != 6) |
1200 |
return 1; |
return 1; |
1201 |
break; |
break; |
1202 |
case 3: |
case 3: |
1204 |
* server socks return server bound address and port |
* server socks return server bound address and port |
1205 |
*/ |
*/ |
1206 |
/* reading address length */ |
/* reading address length */ |
1207 |
if (recv (server->sock, buffer, 1, 0) != 1) |
if (recv (sock, buffer, 1, 0) != 1) |
1208 |
return 1; |
return 1; |
1209 |
addr_len = buffer[0]; |
addr_len = buffer[0]; |
1210 |
/* reading address + port = addr_len + 2 */ |
/* reading address + port = addr_len + 2 */ |
1211 |
if (recv (server->sock, buffer, addr_len + 2, 0) != (addr_len + 2)) |
if (recv (sock, buffer, addr_len + 2, 0) != (addr_len + 2)) |
1212 |
return 1; |
return 1; |
1213 |
break; |
break; |
1214 |
case 4 : |
case 4 : |
1216 |
* server socks return server bound address and port |
* server socks return server bound address and port |
1217 |
* address of 16 bytes and port of 2 bytes (= 18 bytes) |
* address of 16 bytes and port of 2 bytes (= 18 bytes) |
1218 |
*/ |
*/ |
1219 |
if (recv (server->sock, buffer, 18, 0) != 18) |
if (recv (sock, buffer, 18, 0) != 18) |
1220 |
return 1; |
return 1; |
1221 |
break; |
break; |
1222 |
default: |
default: |
1233 |
* - 1 if connexion fails |
* - 1 if connexion fails |
1234 |
*/ |
*/ |
1235 |
int |
int |
1236 |
pass_proxy(t_irc_server *server) |
pass_proxy(int sock, char *address, int port, char *username) |
1237 |
{ |
{ |
1238 |
if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "http") == 0) |
if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "http") == 0) |
1239 |
return pass_httpproxy(server); |
return pass_httpproxy(sock, address, port); |
1240 |
if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "socks4") == 0) |
if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "socks4") == 0) |
1241 |
return pass_socks4proxy(server); |
return pass_socks4proxy(sock, address, port, username); |
1242 |
if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "socks5") == 0) |
if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "socks5") == 0) |
1243 |
return pass_socks5proxy(server); |
return pass_socks5proxy(sock, address, port); |
1244 |
|
|
1245 |
return 1; |
return 1; |
1246 |
} |
} |
1291 |
return 0; |
return 0; |
1292 |
} |
} |
1293 |
|
|
1294 |
if (pass_proxy(server)) |
if (pass_proxy(server->sock, server->address, server->port, server->username)) |
1295 |
{ |
{ |
1296 |
write(server->child_write, "4", 1); |
write(server->child_write, "4", 1); |
1297 |
freeaddrinfo (res); |
freeaddrinfo (res); |