diff options
-rw-r--r-- | src/irc/irc-dcc.c | 46 | ||||
-rw-r--r-- | src/irc/irc-server.c | 60 | ||||
-rw-r--r-- | src/irc/irc.h | 8 | ||||
-rw-r--r-- | weechat/src/irc/irc-dcc.c | 46 | ||||
-rw-r--r-- | weechat/src/irc/irc-server.c | 60 | ||||
-rw-r--r-- | weechat/src/irc/irc.h | 8 |
6 files changed, 142 insertions, 86 deletions
diff --git a/src/irc/irc-dcc.c b/src/irc/irc-dcc.c index 1309a2475..985bedcb5 100644 --- a/src/irc/irc-dcc.c +++ b/src/irc/irc-dcc.c @@ -34,6 +34,8 @@ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> #include "../common/weechat.h" #include "irc.h" @@ -233,6 +235,8 @@ int dcc_connect (t_irc_dcc *ptr_dcc) { struct sockaddr_in addr; + struct hostent *hostent; + char *ip4; if (ptr_dcc->type == DCC_CHAT_SEND) ptr_dcc->status = DCC_WAITING; @@ -245,12 +249,12 @@ dcc_connect (t_irc_dcc *ptr_dcc) if (ptr_dcc->sock == -1) return 0; } - if (fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK) == -1) - return 0; - + /* for sending (chat or file), listen to socket for a connection */ if (DCC_IS_SEND(ptr_dcc->type)) - { + { + if (fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK) == -1) + return 0; if (listen (ptr_dcc->sock, 1) == -1) return 0; if (fcntl (ptr_dcc->sock, F_SETFL, 0) == -1) @@ -260,11 +264,35 @@ dcc_connect (t_irc_dcc *ptr_dcc) /* for receiving (chat or file), connect to listening host */ if (DCC_IS_RECV(ptr_dcc->type)) { - memset (&addr, 0, sizeof (addr)); - addr.sin_port = htons (ptr_dcc->port); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl (ptr_dcc->addr); - connect (ptr_dcc->sock, (struct sockaddr *) &addr, sizeof (addr)); + if (cfg_proxy_use) + { + memset (&addr, 0, sizeof (addr)); + addr.sin_addr.s_addr = htonl (ptr_dcc->addr); + ip4 = inet_ntoa(addr.sin_addr); + + memset (&addr, 0, sizeof (addr)); + addr.sin_port = htons (cfg_proxy_port); + addr.sin_family = AF_INET; + if ((hostent = gethostbyname (cfg_proxy_address)) == NULL) + return 0; + memcpy(&(addr.sin_addr),*(hostent->h_addr_list), sizeof(struct in_addr)); + + if (connect (ptr_dcc->sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) + return 0; + if (pass_proxy(ptr_dcc->sock, ip4, ptr_dcc->port, ptr_dcc->server->username) == -1) + return 0; + } + else + { + memset (&addr, 0, sizeof (addr)); + addr.sin_port = htons (ptr_dcc->port); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl (ptr_dcc->addr); + if (connect (ptr_dcc->sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) + return 0; + } + if (fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK) == -1) + return 0; } return 1; diff --git a/src/irc/irc-server.c b/src/irc/irc-server.c index fabee4213..6645f0129 100644 --- a/src/irc/irc-server.c +++ b/src/irc/irc-server.c @@ -960,7 +960,7 @@ base64encode(char *from, char *to) * - 1 if connexion fails */ int -pass_httpproxy(t_irc_server *server) +pass_httpproxy(int sock, char *address, int port) { char buffer[256]; @@ -973,19 +973,19 @@ pass_httpproxy(t_irc_server *server) // authentification snprintf(authbuf, sizeof(authbuf), "%s:%s", cfg_proxy_username, cfg_proxy_password); base64encode(authbuf, authbuf_base64); - 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); } else { // no authentification - 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); } - m = send (server->sock, buffer, n, 0); + m = send (sock, buffer, n, 0); if (n != m) return 1; - n = recv(server->sock, buffer, sizeof(buffer), 0); + n = recv(sock, buffer, sizeof(buffer), 0); /* success result must be like : "HTTP/1.0 200 OK" */ if (n < 12) @@ -1047,7 +1047,7 @@ resolve (char *hostname, char *ip, int *version) * - 1 if connexion fails */ int -pass_socks4proxy(t_irc_server *server) +pass_socks4proxy(int sock, char *address, int port, char *username) { /* * socks4 protocol is explain here: @@ -1068,13 +1068,13 @@ pass_socks4proxy(t_irc_server *server) socks4.version = 4; socks4.method = 1; - socks4.port = htons (server->port); - resolve(server->address, ip_addr, NULL); + socks4.port = htons (port); + resolve(address, ip_addr, NULL); socks4.address = inet_addr (ip_addr); - strncpy (socks4.user, server->username, sizeof(socks4.user) - 1); + strncpy (socks4.user, username, sizeof(socks4.user) - 1); - send (server->sock, (char *) &socks4, 8 + strlen(socks4.user) + 1, 0); - recv (server->sock, buffer, sizeof(buffer), 0); + send (sock, (char *) &socks4, 8 + strlen(socks4.user) + 1, 0); + recv (sock, buffer, sizeof(buffer), 0); if (buffer[0] == 0 && buffer[1] == 90) return 0; @@ -1089,7 +1089,7 @@ pass_socks4proxy(t_irc_server *server) * - 1 if connexion fails */ int -pass_socks5proxy(t_irc_server *server) +pass_socks5proxy(int sock, char *address, int port) { /* * socks5 protocol is explained in RFC 1928 @@ -1116,9 +1116,9 @@ pass_socks5proxy(t_irc_server *server) /* without authentication */ socks5.method = 0; - send (server->sock, (char *) &socks5, sizeof(socks5), 0); + send (sock, (char *) &socks5, sizeof(socks5), 0); /* server socks5 must respond with 2 bytes */ - if (recv (server->sock, buffer, 2, 0) != 2) + if (recv (sock, buffer, 2, 0) != 2) return 1; if (strlen(cfg_proxy_username) > 0) @@ -1144,10 +1144,10 @@ pass_socks5proxy(t_irc_server *server) buffer[2 + username_len] = (unsigned char) password_len; memcpy(buffer + 3 + username_len, cfg_proxy_password, password_len); - send (server->sock, buffer, 3 + username_len + password_len, 0); + send (sock, buffer, 3 + username_len + password_len, 0); /* server socks5 must respond with 2 bytes */ - if (recv (server->sock, buffer, 2, 0) != 2) + if (recv (sock, buffer, 2, 0) != 2) return 1; /* buffer[1] = auth state, must be 0 for success */ @@ -1166,7 +1166,7 @@ pass_socks5proxy(t_irc_server *server) } /* authentication successful then giving address/port to connect */ - addr_len = strlen(server->address); + addr_len = strlen(address); addr_buffer_len = 4 + 1 + addr_len + 2; addr_buffer = (unsigned char *) malloc ( addr_buffer_len * sizeof(*addr_buffer)); if (!addr_buffer) @@ -1176,14 +1176,14 @@ pass_socks5proxy(t_irc_server *server) addr_buffer[2] = 0; /* reserved */ addr_buffer[3] = 3; /* address type : ipv4 (1), domainname (3), ipv6 (4) */ addr_buffer[4] = (unsigned char) addr_len; - memcpy (addr_buffer + 5, server->address, addr_len); /* server address */ - *((unsigned short *) (addr_buffer + 5 + addr_len)) = htons (server->port); /* server port */ + memcpy (addr_buffer + 5, address, addr_len); /* server address */ + *((unsigned short *) (addr_buffer + 5 + addr_len)) = htons (port); /* server port */ - send (server->sock, addr_buffer, addr_buffer_len, 0); + send (sock, addr_buffer, addr_buffer_len, 0); free(addr_buffer); /* dialog with proxy server */ - if (recv (server->sock, buffer, 4, 0) != 4) + if (recv (sock, buffer, 4, 0) != 4) return 1; if (!(buffer[0] == 5 && buffer[1] == 0)) @@ -1196,7 +1196,7 @@ pass_socks5proxy(t_irc_server *server) * server socks return server bound address and port * address of 4 bytes and port of 2 bytes (= 6 bytes) */ - if (recv (server->sock, buffer, 6, 0) != 6) + if (recv (sock, buffer, 6, 0) != 6) return 1; break; case 3: @@ -1204,11 +1204,11 @@ pass_socks5proxy(t_irc_server *server) * server socks return server bound address and port */ /* reading address length */ - if (recv (server->sock, buffer, 1, 0) != 1) + if (recv (sock, buffer, 1, 0) != 1) return 1; addr_len = buffer[0]; /* reading address + port = addr_len + 2 */ - if (recv (server->sock, buffer, addr_len + 2, 0) != (addr_len + 2)) + if (recv (sock, buffer, addr_len + 2, 0) != (addr_len + 2)) return 1; break; case 4 : @@ -1216,7 +1216,7 @@ pass_socks5proxy(t_irc_server *server) * server socks return server bound address and port * address of 16 bytes and port of 2 bytes (= 18 bytes) */ - if (recv (server->sock, buffer, 18, 0) != 18) + if (recv (sock, buffer, 18, 0) != 18) return 1; break; default: @@ -1233,14 +1233,14 @@ pass_socks5proxy(t_irc_server *server) * - 1 if connexion fails */ int -pass_proxy(t_irc_server *server) +pass_proxy(int sock, char *address, int port, char *username) { if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "http") == 0) - return pass_httpproxy(server); + return pass_httpproxy(sock, address, port); if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "socks4") == 0) - return pass_socks4proxy(server); + return pass_socks4proxy(sock, address, port, username); if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "socks5") == 0) - return pass_socks5proxy(server); + return pass_socks5proxy(sock, address, port); return 1; } @@ -1291,7 +1291,7 @@ server_child (t_irc_server *server) return 0; } - if (pass_proxy(server)) + if (pass_proxy(server->sock, server->address, server->port, server->username)) { write(server->child_write, "4", 1); freeaddrinfo (res); diff --git a/src/irc/irc.h b/src/irc/irc.h index 915f91e3e..96b39e71e 100644 --- a/src/irc/irc.h +++ b/src/irc/irc.h @@ -290,11 +290,11 @@ extern void server_print_log (t_irc_server *); /* proxy functions (irc-server.c) */ extern void convbase64_8x3_to_6x4(char *from, char* to); extern void base64encode(char *from, char *to); -extern int pass_httpproxy(t_irc_server *server); +extern int pass_httpproxy(int, char*, int); extern int resolve(char *hostname, char *ip, int *version); -extern int pass_socks4proxy(t_irc_server *server); -extern int pass_socks5proxy(t_irc_server *server); -extern int pass_proxy(t_irc_server *server); +extern int pass_socks4proxy(int, char*, int, char*); +extern int pass_socks5proxy(int, char*, int); +extern int pass_proxy(int, char*, int, char*); /* channel functions (irc-channel.c) */ diff --git a/weechat/src/irc/irc-dcc.c b/weechat/src/irc/irc-dcc.c index 1309a2475..985bedcb5 100644 --- a/weechat/src/irc/irc-dcc.c +++ b/weechat/src/irc/irc-dcc.c @@ -34,6 +34,8 @@ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> #include "../common/weechat.h" #include "irc.h" @@ -233,6 +235,8 @@ int dcc_connect (t_irc_dcc *ptr_dcc) { struct sockaddr_in addr; + struct hostent *hostent; + char *ip4; if (ptr_dcc->type == DCC_CHAT_SEND) ptr_dcc->status = DCC_WAITING; @@ -245,12 +249,12 @@ dcc_connect (t_irc_dcc *ptr_dcc) if (ptr_dcc->sock == -1) return 0; } - if (fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK) == -1) - return 0; - + /* for sending (chat or file), listen to socket for a connection */ if (DCC_IS_SEND(ptr_dcc->type)) - { + { + if (fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK) == -1) + return 0; if (listen (ptr_dcc->sock, 1) == -1) return 0; if (fcntl (ptr_dcc->sock, F_SETFL, 0) == -1) @@ -260,11 +264,35 @@ dcc_connect (t_irc_dcc *ptr_dcc) /* for receiving (chat or file), connect to listening host */ if (DCC_IS_RECV(ptr_dcc->type)) { - memset (&addr, 0, sizeof (addr)); - addr.sin_port = htons (ptr_dcc->port); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl (ptr_dcc->addr); - connect (ptr_dcc->sock, (struct sockaddr *) &addr, sizeof (addr)); + if (cfg_proxy_use) + { + memset (&addr, 0, sizeof (addr)); + addr.sin_addr.s_addr = htonl (ptr_dcc->addr); + ip4 = inet_ntoa(addr.sin_addr); + + memset (&addr, 0, sizeof (addr)); + addr.sin_port = htons (cfg_proxy_port); + addr.sin_family = AF_INET; + if ((hostent = gethostbyname (cfg_proxy_address)) == NULL) + return 0; + memcpy(&(addr.sin_addr),*(hostent->h_addr_list), sizeof(struct in_addr)); + + if (connect (ptr_dcc->sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) + return 0; + if (pass_proxy(ptr_dcc->sock, ip4, ptr_dcc->port, ptr_dcc->server->username) == -1) + return 0; + } + else + { + memset (&addr, 0, sizeof (addr)); + addr.sin_port = htons (ptr_dcc->port); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl (ptr_dcc->addr); + if (connect (ptr_dcc->sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) + return 0; + } + if (fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK) == -1) + return 0; } return 1; diff --git a/weechat/src/irc/irc-server.c b/weechat/src/irc/irc-server.c index fabee4213..6645f0129 100644 --- a/weechat/src/irc/irc-server.c +++ b/weechat/src/irc/irc-server.c @@ -960,7 +960,7 @@ base64encode(char *from, char *to) * - 1 if connexion fails */ int -pass_httpproxy(t_irc_server *server) +pass_httpproxy(int sock, char *address, int port) { char buffer[256]; @@ -973,19 +973,19 @@ pass_httpproxy(t_irc_server *server) // authentification snprintf(authbuf, sizeof(authbuf), "%s:%s", cfg_proxy_username, cfg_proxy_password); base64encode(authbuf, authbuf_base64); - 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); } else { // no authentification - 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); } - m = send (server->sock, buffer, n, 0); + m = send (sock, buffer, n, 0); if (n != m) return 1; - n = recv(server->sock, buffer, sizeof(buffer), 0); + n = recv(sock, buffer, sizeof(buffer), 0); /* success result must be like : "HTTP/1.0 200 OK" */ if (n < 12) @@ -1047,7 +1047,7 @@ resolve (char *hostname, char *ip, int *version) * - 1 if connexion fails */ int -pass_socks4proxy(t_irc_server *server) +pass_socks4proxy(int sock, char *address, int port, char *username) { /* * socks4 protocol is explain here: @@ -1068,13 +1068,13 @@ pass_socks4proxy(t_irc_server *server) socks4.version = 4; socks4.method = 1; - socks4.port = htons (server->port); - resolve(server->address, ip_addr, NULL); + socks4.port = htons (port); + resolve(address, ip_addr, NULL); socks4.address = inet_addr (ip_addr); - strncpy (socks4.user, server->username, sizeof(socks4.user) - 1); + strncpy (socks4.user, username, sizeof(socks4.user) - 1); - send (server->sock, (char *) &socks4, 8 + strlen(socks4.user) + 1, 0); - recv (server->sock, buffer, sizeof(buffer), 0); + send (sock, (char *) &socks4, 8 + strlen(socks4.user) + 1, 0); + recv (sock, buffer, sizeof(buffer), 0); if (buffer[0] == 0 && buffer[1] == 90) return 0; @@ -1089,7 +1089,7 @@ pass_socks4proxy(t_irc_server *server) * - 1 if connexion fails */ int -pass_socks5proxy(t_irc_server *server) +pass_socks5proxy(int sock, char *address, int port) { /* * socks5 protocol is explained in RFC 1928 @@ -1116,9 +1116,9 @@ pass_socks5proxy(t_irc_server *server) /* without authentication */ socks5.method = 0; - send (server->sock, (char *) &socks5, sizeof(socks5), 0); + send (sock, (char *) &socks5, sizeof(socks5), 0); /* server socks5 must respond with 2 bytes */ - if (recv (server->sock, buffer, 2, 0) != 2) + if (recv (sock, buffer, 2, 0) != 2) return 1; if (strlen(cfg_proxy_username) > 0) @@ -1144,10 +1144,10 @@ pass_socks5proxy(t_irc_server *server) buffer[2 + username_len] = (unsigned char) password_len; memcpy(buffer + 3 + username_len, cfg_proxy_password, password_len); - send (server->sock, buffer, 3 + username_len + password_len, 0); + send (sock, buffer, 3 + username_len + password_len, 0); /* server socks5 must respond with 2 bytes */ - if (recv (server->sock, buffer, 2, 0) != 2) + if (recv (sock, buffer, 2, 0) != 2) return 1; /* buffer[1] = auth state, must be 0 for success */ @@ -1166,7 +1166,7 @@ pass_socks5proxy(t_irc_server *server) } /* authentication successful then giving address/port to connect */ - addr_len = strlen(server->address); + addr_len = strlen(address); addr_buffer_len = 4 + 1 + addr_len + 2; addr_buffer = (unsigned char *) malloc ( addr_buffer_len * sizeof(*addr_buffer)); if (!addr_buffer) @@ -1176,14 +1176,14 @@ pass_socks5proxy(t_irc_server *server) addr_buffer[2] = 0; /* reserved */ addr_buffer[3] = 3; /* address type : ipv4 (1), domainname (3), ipv6 (4) */ addr_buffer[4] = (unsigned char) addr_len; - memcpy (addr_buffer + 5, server->address, addr_len); /* server address */ - *((unsigned short *) (addr_buffer + 5 + addr_len)) = htons (server->port); /* server port */ + memcpy (addr_buffer + 5, address, addr_len); /* server address */ + *((unsigned short *) (addr_buffer + 5 + addr_len)) = htons (port); /* server port */ - send (server->sock, addr_buffer, addr_buffer_len, 0); + send (sock, addr_buffer, addr_buffer_len, 0); free(addr_buffer); /* dialog with proxy server */ - if (recv (server->sock, buffer, 4, 0) != 4) + if (recv (sock, buffer, 4, 0) != 4) return 1; if (!(buffer[0] == 5 && buffer[1] == 0)) @@ -1196,7 +1196,7 @@ pass_socks5proxy(t_irc_server *server) * server socks return server bound address and port * address of 4 bytes and port of 2 bytes (= 6 bytes) */ - if (recv (server->sock, buffer, 6, 0) != 6) + if (recv (sock, buffer, 6, 0) != 6) return 1; break; case 3: @@ -1204,11 +1204,11 @@ pass_socks5proxy(t_irc_server *server) * server socks return server bound address and port */ /* reading address length */ - if (recv (server->sock, buffer, 1, 0) != 1) + if (recv (sock, buffer, 1, 0) != 1) return 1; addr_len = buffer[0]; /* reading address + port = addr_len + 2 */ - if (recv (server->sock, buffer, addr_len + 2, 0) != (addr_len + 2)) + if (recv (sock, buffer, addr_len + 2, 0) != (addr_len + 2)) return 1; break; case 4 : @@ -1216,7 +1216,7 @@ pass_socks5proxy(t_irc_server *server) * server socks return server bound address and port * address of 16 bytes and port of 2 bytes (= 18 bytes) */ - if (recv (server->sock, buffer, 18, 0) != 18) + if (recv (sock, buffer, 18, 0) != 18) return 1; break; default: @@ -1233,14 +1233,14 @@ pass_socks5proxy(t_irc_server *server) * - 1 if connexion fails */ int -pass_proxy(t_irc_server *server) +pass_proxy(int sock, char *address, int port, char *username) { if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "http") == 0) - return pass_httpproxy(server); + return pass_httpproxy(sock, address, port); if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "socks4") == 0) - return pass_socks4proxy(server); + return pass_socks4proxy(sock, address, port, username); if (strcmp(cfg_proxy_type_values[cfg_proxy_type], "socks5") == 0) - return pass_socks5proxy(server); + return pass_socks5proxy(sock, address, port); return 1; } @@ -1291,7 +1291,7 @@ server_child (t_irc_server *server) return 0; } - if (pass_proxy(server)) + if (pass_proxy(server->sock, server->address, server->port, server->username)) { write(server->child_write, "4", 1); freeaddrinfo (res); diff --git a/weechat/src/irc/irc.h b/weechat/src/irc/irc.h index 915f91e3e..96b39e71e 100644 --- a/weechat/src/irc/irc.h +++ b/weechat/src/irc/irc.h @@ -290,11 +290,11 @@ extern void server_print_log (t_irc_server *); /* proxy functions (irc-server.c) */ extern void convbase64_8x3_to_6x4(char *from, char* to); extern void base64encode(char *from, char *to); -extern int pass_httpproxy(t_irc_server *server); +extern int pass_httpproxy(int, char*, int); extern int resolve(char *hostname, char *ip, int *version); -extern int pass_socks4proxy(t_irc_server *server); -extern int pass_socks5proxy(t_irc_server *server); -extern int pass_proxy(t_irc_server *server); +extern int pass_socks4proxy(int, char*, int, char*); +extern int pass_socks5proxy(int, char*, int); +extern int pass_proxy(int, char*, int, char*); /* channel functions (irc-channel.c) */ |