| 45 |
49 |
| 46 #include <fcntl.h> |
50 #include <fcntl.h> |
| 47 #include <errno.h> |
51 #include <errno.h> |
| 48 #include "gaim.h" |
52 #include "gaim.h" |
| 49 #include "proxy.h" |
53 #include "proxy.h" |
| |
54 #include "prefs.h" |
| 50 |
55 |
| 51 #ifdef _WIN32 |
56 #ifdef _WIN32 |
| 52 #include "win32dep.h" |
57 #include "win32dep.h" |
| 53 #endif |
58 #endif |
| 54 |
59 |
| 55 #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) |
60 #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) |
| 56 #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) |
61 #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) |
| 57 |
62 |
| 58 struct gaim_proxy_info global_proxy_info; |
63 static GaimProxyInfo *global_proxy_info = NULL; |
| |
64 static gboolean global_proxy_info_from_prefs = FALSE; |
| 59 |
65 |
| 60 struct PHB { |
66 struct PHB { |
| 61 GaimInputFunction func; |
67 GaimInputFunction func; |
| 62 gpointer data; |
68 gpointer data; |
| 63 char *host; |
69 char *host; |
| 64 int port; |
70 int port; |
| 65 gint inpa; |
71 gint inpa; |
| 66 struct gaim_proxy_info *gpi; |
72 GaimProxyInfo *gpi; |
| 67 GaimAccount *account; |
73 GaimAccount *account; |
| 68 }; |
74 }; |
| 69 |
75 |
| 70 typedef struct _GaimIOClosure { |
76 typedef struct _GaimIOClosure { |
| 71 GaimInputFunction function; |
77 GaimInputFunction function; |
| 72 guint result; |
78 guint result; |
| 73 gpointer data; |
79 gpointer data; |
| |
80 |
| 74 } GaimIOClosure; |
81 } GaimIOClosure; |
| 75 |
82 |
| |
83 /************************************************************************** |
| |
84 * Proxy structure API |
| |
85 **************************************************************************/ |
| |
86 GaimProxyInfo * |
| |
87 gaim_proxy_info_new(void) |
| |
88 { |
| |
89 return g_new0(GaimProxyInfo, 1); |
| |
90 } |
| |
91 |
| |
92 void |
| |
93 gaim_proxy_info_destroy(GaimProxyInfo *info) |
| |
94 { |
| |
95 g_return_if_fail(info != NULL); |
| |
96 |
| |
97 if (info->host != NULL) g_free(info->host); |
| |
98 if (info->username != NULL) g_free(info->username); |
| |
99 if (info->password != NULL) g_free(info->password); |
| |
100 |
| |
101 g_free(info); |
| |
102 } |
| |
103 |
| |
104 void |
| |
105 gaim_proxy_info_set_type(GaimProxyInfo *info, GaimProxyType type) |
| |
106 { |
| |
107 g_return_if_fail(info != NULL); |
| |
108 |
| |
109 info->type = type; |
| |
110 } |
| |
111 |
| |
112 void |
| |
113 gaim_proxy_info_set_host(GaimProxyInfo *info, const char *host) |
| |
114 { |
| |
115 g_return_if_fail(info != NULL); |
| |
116 |
| |
117 if (info->host != NULL) |
| |
118 g_free(info->host); |
| |
119 |
| |
120 info->host = (host == NULL ? NULL : g_strdup(host)); |
| |
121 } |
| |
122 |
| |
123 void |
| |
124 gaim_proxy_info_set_port(GaimProxyInfo *info, int port) |
| |
125 { |
| |
126 g_return_if_fail(info != NULL); |
| |
127 |
| |
128 info->port = port; |
| |
129 } |
| |
130 |
| |
131 void |
| |
132 gaim_proxy_info_set_username(GaimProxyInfo *info, const char *username) |
| |
133 { |
| |
134 g_return_if_fail(info != NULL); |
| |
135 |
| |
136 if (info->username != NULL) |
| |
137 g_free(info->username); |
| |
138 |
| |
139 info->username = (username == NULL ? NULL : g_strdup(username)); |
| |
140 } |
| |
141 |
| |
142 void |
| |
143 gaim_proxy_info_set_password(GaimProxyInfo *info, const char *password) |
| |
144 { |
| |
145 g_return_if_fail(info != NULL); |
| |
146 |
| |
147 if (info->password != NULL) |
| |
148 g_free(info->password); |
| |
149 |
| |
150 info->password = (password == NULL ? NULL : g_strdup(password)); |
| |
151 } |
| |
152 |
| |
153 GaimProxyType |
| |
154 gaim_proxy_info_get_type(const GaimProxyInfo *info) |
| |
155 { |
| |
156 g_return_val_if_fail(info != NULL, GAIM_PROXY_NONE); |
| |
157 |
| |
158 return info->type; |
| |
159 } |
| |
160 |
| |
161 const char * |
| |
162 gaim_proxy_info_get_host(const GaimProxyInfo *info) |
| |
163 { |
| |
164 g_return_val_if_fail(info != NULL, NULL); |
| |
165 |
| |
166 return info->host; |
| |
167 } |
| |
168 |
| |
169 int |
| |
170 gaim_proxy_info_get_port(const GaimProxyInfo *info) |
| |
171 { |
| |
172 g_return_val_if_fail(info != NULL, 0); |
| |
173 |
| |
174 return info->port; |
| |
175 } |
| |
176 |
| |
177 const char * |
| |
178 gaim_proxy_info_get_username(const GaimProxyInfo *info) |
| |
179 { |
| |
180 g_return_val_if_fail(info != NULL, NULL); |
| |
181 |
| |
182 return info->username; |
| |
183 } |
| |
184 |
| |
185 const char * |
| |
186 gaim_proxy_info_get_password(const GaimProxyInfo *info) |
| |
187 { |
| |
188 g_return_val_if_fail(info != NULL, NULL); |
| |
189 |
| |
190 return info->password; |
| |
191 } |
| |
192 |
| |
193 /************************************************************************** |
| |
194 * Global Proxy API |
| |
195 **************************************************************************/ |
| |
196 void |
| |
197 gaim_global_proxy_set_from_prefs(gboolean from_prefs) |
| |
198 { |
| |
199 global_proxy_info_from_prefs = from_prefs; |
| |
200 } |
| |
201 |
| |
202 GaimProxyInfo * |
| |
203 gaim_global_proxy_get_info(void) |
| |
204 { |
| |
205 return global_proxy_info; |
| |
206 } |
| |
207 |
| |
208 gboolean |
| |
209 gaim_global_proxy_is_from_prefs(void) |
| |
210 { |
| |
211 return global_proxy_info_from_prefs; |
| |
212 } |
| |
213 |
| |
214 /************************************************************************** |
| |
215 * Proxy API |
| |
216 **************************************************************************/ |
| 76 static void gaim_io_destroy(gpointer data) |
217 static void gaim_io_destroy(gpointer data) |
| 77 { |
218 { |
| 78 g_free(data); |
219 g_free(data); |
| 79 } |
220 } |
| 80 |
221 |
| 624 ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len); |
768 ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len); |
| 625 if (ret < 0 || error != 0) { |
769 if (ret < 0 || error != 0) { |
| 626 if(ret==0) errno = error; |
770 if(ret==0) errno = error; |
| 627 close(source); |
771 close(source); |
| 628 gaim_input_remove(phb->inpa); |
772 gaim_input_remove(phb->inpa); |
| 629 if(!phb->account || phb->account->gc) |
773 |
| |
774 if (phb->account == NULL || |
| |
775 gaim_account_get_connection(phb->account) != NULL) { |
| |
776 |
| 630 phb->func(phb->data, -1, GAIM_INPUT_READ); |
777 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
778 } |
| |
779 |
| 631 g_free(phb->host); |
780 g_free(phb->host); |
| 632 g_free(phb); |
781 g_free(phb); |
| 633 |
782 |
| 634 gaim_debug(GAIM_DEBUG_ERROR, "proxy", |
783 gaim_debug(GAIM_DEBUG_ERROR, "proxy", |
| 635 "getsockopt SO_ERROR check: %s\n", strerror(errno)); |
784 "getsockopt SO_ERROR check: %s\n", strerror(errno)); |
| 636 return; |
785 return; |
| 637 } |
786 } |
| |
787 |
| 638 fcntl(source, F_SETFL, 0); |
788 fcntl(source, F_SETFL, 0); |
| 639 gaim_input_remove(phb->inpa); |
789 gaim_input_remove(phb->inpa); |
| 640 if(!phb->account || phb->account->gc) |
790 |
| |
791 if (phb->account == NULL || |
| |
792 gaim_account_get_connection(phb->account) != NULL) { |
| |
793 |
| 641 phb->func(phb->data, source, GAIM_INPUT_READ); |
794 phb->func(phb->data, source, GAIM_INPUT_READ); |
| |
795 } |
| |
796 |
| 642 g_free(phb->host); |
797 g_free(phb->host); |
| 643 g_free(phb); |
798 g_free(phb); |
| 644 } |
799 } |
| 645 |
800 |
| 646 static gboolean clean_connect(gpointer data) |
801 static gboolean clean_connect(gpointer data) |
| 647 { |
802 { |
| 648 struct PHB *phb = data; |
803 struct PHB *phb = data; |
| 649 |
804 |
| 650 if(!phb->account || phb->account->gc) |
805 if (phb->account == NULL || |
| |
806 gaim_account_get_connection(phb->account) != NULL) { |
| |
807 |
| 651 phb->func(phb->data, phb->port, GAIM_INPUT_READ); |
808 phb->func(phb->data, phb->port, GAIM_INPUT_READ); |
| |
809 } |
| |
810 |
| 652 g_free(phb->host); |
811 g_free(phb->host); |
| 653 g_free(phb); |
812 g_free(phb); |
| 654 |
813 |
| 655 return FALSE; |
814 return FALSE; |
| 656 } |
815 } |
| 657 |
816 |
| 658 |
817 |
| 659 static int proxy_connect_none(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
818 static int |
| |
819 proxy_connect_none(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
| 660 { |
820 { |
| 661 int fd = -1; |
821 int fd = -1; |
| 662 |
822 |
| 663 gaim_debug(GAIM_DEBUG_INFO, "proxy", |
823 gaim_debug(GAIM_DEBUG_INFO, "proxy", |
| 664 "Connecting to %s:%d with no proxy\n", phb->host, phb->port); |
824 "Connecting to %s:%d with no proxy\n", phb->host, phb->port); |
| 768 |
933 |
| 769 gaim_debug(GAIM_DEBUG_INFO, "http proxy", "Connected.\n"); |
934 gaim_debug(GAIM_DEBUG_INFO, "http proxy", "Connected.\n"); |
| 770 |
935 |
| 771 if (phb->inpa > 0) |
936 if (phb->inpa > 0) |
| 772 gaim_input_remove(phb->inpa); |
937 gaim_input_remove(phb->inpa); |
| |
938 |
| 773 len = sizeof(error); |
939 len = sizeof(error); |
| |
940 |
| 774 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
941 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 775 close(source); |
942 close(source); |
| 776 if(!phb->account || phb->account->gc) |
943 |
| |
944 if (phb->account == NULL || |
| |
945 gaim_account_get_connection(phb->account) != NULL) { |
| |
946 |
| 777 phb->func(phb->data, -1, GAIM_INPUT_READ); |
947 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
948 } |
| |
949 |
| 778 g_free(phb->host); |
950 g_free(phb->host); |
| 779 g_free(phb); |
951 g_free(phb); |
| 780 return; |
952 return; |
| 781 } |
953 } |
| 782 request_len = g_snprintf(request, sizeof(request), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, |
954 request_len = g_snprintf(request, sizeof(request), |
| 783 phb->host, phb->port); |
955 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", |
| 784 |
956 phb->host, phb->port, phb->host, phb->port); |
| 785 if (phb->gpi->proxyuser) { |
957 |
| |
958 if (gaim_proxy_info_get_username(phb->gpi) != NULL) { |
| 786 char *t1, *t2; |
959 char *t1, *t2; |
| 787 t1 = g_strdup_printf("%s:%s", phb->gpi->proxyuser, phb->gpi->proxypass); |
960 t1 = g_strdup_printf("%s:%s", |
| |
961 gaim_proxy_info_get_username(phb->gpi), |
| |
962 gaim_proxy_info_get_password(phb->gpi)); |
| |
963 |
| 788 t2 = tobase64(t1, strlen(t1)); |
964 t2 = tobase64(t1, strlen(t1)); |
| 789 g_free(t1); |
965 g_free(t1); |
| 790 g_return_if_fail(request_len < sizeof(request)); |
966 g_return_if_fail(request_len < sizeof(request)); |
| 791 request_len += g_snprintf(request + request_len, sizeof(request) - request_len, "Proxy-Authorization: Basic %s\r\n", t2); |
967 request_len += g_snprintf(request + request_len, |
| |
968 sizeof(request) - request_len, |
| |
969 "Proxy-Authorization: Basic %s\r\n", t2); |
| 792 g_free(t2); |
970 g_free(t2); |
| 793 } |
971 } |
| 794 |
972 |
| 795 g_return_if_fail(request_len < sizeof(request)); |
973 g_return_if_fail(request_len < sizeof(request)); |
| 796 strcpy(request + request_len, "\r\n"); |
974 strcpy(request + request_len, "\r\n"); |
| 797 request_len += 2; |
975 request_len += 2; |
| 798 |
976 |
| 799 if (write(source, request, request_len) < 0) { |
977 if (write(source, request, request_len) < 0) { |
| 800 close(source); |
978 close(source); |
| 801 if(!phb->account || phb->account->gc) |
979 |
| |
980 if (phb->account == NULL || |
| |
981 gaim_account_get_connection(phb->account) != NULL) { |
| |
982 |
| 802 phb->func(phb->data, -1, GAIM_INPUT_READ); |
983 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
984 } |
| |
985 |
| 803 g_free(phb->host); |
986 g_free(phb->host); |
| 804 g_free(phb); |
987 g_free(phb); |
| 805 return; |
988 return; |
| 806 } |
989 } |
| 807 |
990 |
| 808 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb); |
991 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb); |
| 809 } |
992 } |
| 810 |
993 |
| 811 static int proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
994 static int |
| |
995 proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
| 812 { |
996 { |
| 813 int fd = -1; |
997 int fd = -1; |
| 814 |
998 |
| 815 gaim_debug(GAIM_DEBUG_INFO, "http proxy", |
999 gaim_debug(GAIM_DEBUG_INFO, "http proxy", |
| 816 "Connecting to %s:%d via %s:%d using HTTP\n", |
1000 "Connecting to %s:%d via %s:%d using HTTP\n", |
| 817 phb->host, phb->port, phb->gpi->proxyhost, |
1001 phb->host, phb->port, |
| 818 phb->gpi->proxyport); |
1002 gaim_proxy_info_get_host(phb->gpi), |
| |
1003 gaim_proxy_info_get_port(phb->gpi)); |
| 819 |
1004 |
| 820 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
1005 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
| 821 return -1; |
1006 return -1; |
| 822 } |
1007 } |
| 823 |
1008 |
| 918 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; |
1128 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; |
| 919 packet[8] = 0; |
1129 packet[8] = 0; |
| 920 |
1130 |
| 921 if (write(source, packet, 9) != 9) { |
1131 if (write(source, packet, 9) != 9) { |
| 922 close(source); |
1132 close(source); |
| 923 if(!phb->account || phb->account->gc) |
1133 |
| |
1134 if (phb->account == NULL || |
| |
1135 gaim_account_get_connection(phb->account) != NULL) { |
| |
1136 |
| 924 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1137 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1138 } |
| |
1139 |
| 925 g_free(phb->host); |
1140 g_free(phb->host); |
| 926 g_free(phb); |
1141 g_free(phb); |
| 927 return; |
1142 return; |
| 928 } |
1143 } |
| 929 |
1144 |
| 930 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s4_canread, phb); |
1145 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s4_canread, phb); |
| 931 } |
1146 } |
| 932 |
1147 |
| 933 static int proxy_connect_socks4(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
1148 static int |
| |
1149 proxy_connect_socks4(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
| 934 { |
1150 { |
| 935 int fd = -1; |
1151 int fd = -1; |
| 936 |
1152 |
| 937 gaim_debug(GAIM_DEBUG_INFO, "socks4 proxy", |
1153 gaim_debug(GAIM_DEBUG_INFO, "socks4 proxy", |
| 938 "Connecting to %s:%d via %s:%d using SOCKS4\n", |
1154 "Connecting to %s:%d via %s:%d using SOCKS4\n", |
| 939 phb->host, phb->port, phb->gpi->proxyhost, |
1155 phb->host, phb->port, |
| 940 phb->gpi->proxyport); |
1156 gaim_proxy_info_get_host(phb->gpi), |
| 941 |
1157 gaim_proxy_info_get_port(phb->gpi)); |
| 942 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
1158 |
| |
1159 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) |
| 943 return -1; |
1160 return -1; |
| 944 } |
|
| 945 |
1161 |
| 946 fcntl(fd, F_SETFL, O_NONBLOCK); |
1162 fcntl(fd, F_SETFL, O_NONBLOCK); |
| |
1163 |
| 947 if (connect(fd, addr, addrlen) < 0) { |
1164 if (connect(fd, addr, addrlen) < 0) { |
| 948 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
1165 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
| 949 gaim_debug(GAIM_DEBUG_WARNING, "socks4 proxy", |
1166 gaim_debug(GAIM_DEBUG_WARNING, "socks4 proxy", |
| 950 "Connect would have blocked.\n"); |
1167 "Connect would have blocked.\n"); |
| 951 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, phb); |
1168 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, phb); |
| 952 } else { |
1169 } |
| |
1170 else { |
| 953 close(fd); |
1171 close(fd); |
| 954 return -1; |
1172 return -1; |
| 955 } |
1173 } |
| 956 } else { |
1174 } else { |
| 957 unsigned int len; |
1175 unsigned int len; |
| 959 |
1177 |
| 960 gaim_debug(GAIM_DEBUG_MISC, "socks4 proxy", |
1178 gaim_debug(GAIM_DEBUG_MISC, "socks4 proxy", |
| 961 "Connect didn't block.\n"); |
1179 "Connect didn't block.\n"); |
| 962 |
1180 |
| 963 len = sizeof(error); |
1181 len = sizeof(error); |
| |
1182 |
| 964 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
1183 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 965 close(fd); |
1184 close(fd); |
| 966 return -1; |
1185 return -1; |
| 967 } |
1186 } |
| |
1187 |
| 968 fcntl(fd, F_SETFL, 0); |
1188 fcntl(fd, F_SETFL, 0); |
| 969 s4_canwrite(phb, fd, GAIM_INPUT_WRITE); |
1189 s4_canwrite(phb, fd, GAIM_INPUT_WRITE); |
| 970 } |
1190 } |
| 971 |
1191 |
| 972 return fd; |
1192 return fd; |
| 973 } |
1193 } |
| 974 |
1194 |
| 975 static void s5_canread_again(gpointer data, gint source, GaimInputCondition cond) |
1195 static void |
| |
1196 s5_canread_again(gpointer data, gint source, GaimInputCondition cond) |
| 976 { |
1197 { |
| 977 unsigned char buf[512]; |
1198 unsigned char buf[512]; |
| 978 struct PHB *phb = data; |
1199 struct PHB *phb = data; |
| 979 |
1200 |
| 980 gaim_input_remove(phb->inpa); |
1201 gaim_input_remove(phb->inpa); |
| 981 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Able to read again.\n"); |
1202 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Able to read again.\n"); |
| 982 |
1203 |
| 983 if (read(source, buf, 10) < 10) { |
1204 if (read(source, buf, 10) < 10) { |
| 984 gaim_debug(GAIM_DEBUG_WARNING, "socks5 proxy", "or not...\n"); |
1205 gaim_debug(GAIM_DEBUG_WARNING, "socks5 proxy", "or not...\n"); |
| 985 close(source); |
1206 close(source); |
| 986 if(!phb->account || phb->account->gc) |
1207 |
| |
1208 if (phb->account == NULL || |
| |
1209 gaim_account_get_connection(phb->account) != NULL) { |
| |
1210 |
| 987 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1211 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1212 } |
| |
1213 |
| 988 g_free(phb->host); |
1214 g_free(phb->host); |
| 989 g_free(phb); |
1215 g_free(phb); |
| 990 return; |
1216 return; |
| 991 } |
1217 } |
| 992 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { |
1218 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { |
| 993 gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "Bad data.\n"); |
1219 gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "Bad data.\n"); |
| 994 close(source); |
1220 close(source); |
| 995 if(!phb->account || phb->account->gc) |
1221 |
| |
1222 if (phb->account == NULL || |
| |
1223 gaim_account_get_connection(phb->account) != NULL) { |
| |
1224 |
| 996 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1225 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1226 } |
| |
1227 |
| 997 g_free(phb->host); |
1228 g_free(phb->host); |
| 998 g_free(phb); |
1229 g_free(phb); |
| 999 return; |
1230 return; |
| 1000 } |
1231 } |
| 1001 |
1232 |
| 1002 if(!phb->account || phb->account->gc) |
1233 if (phb->account == NULL || |
| |
1234 gaim_account_get_connection(phb->account) != NULL) { |
| |
1235 |
| 1003 phb->func(phb->data, source, GAIM_INPUT_READ); |
1236 phb->func(phb->data, source, GAIM_INPUT_READ); |
| |
1237 } |
| |
1238 |
| 1004 g_free(phb->host); |
1239 g_free(phb->host); |
| 1005 g_free(phb); |
1240 g_free(phb); |
| 1006 return; |
1241 } |
| 1007 } |
1242 |
| 1008 |
1243 static void |
| 1009 static void s5_sendconnect(gpointer data, gint source) |
1244 s5_sendconnect(gpointer data, gint source) |
| 1010 { |
1245 { |
| 1011 unsigned char buf[512]; |
1246 unsigned char buf[512]; |
| 1012 struct PHB *phb = data; |
1247 struct PHB *phb = data; |
| 1013 int hlen = strlen(phb->host); |
1248 int hlen = strlen(phb->host); |
| 1014 |
1249 |
| 1021 buf[5 + strlen(phb->host)] = phb->port >> 8; |
1256 buf[5 + strlen(phb->host)] = phb->port >> 8; |
| 1022 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; |
1257 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; |
| 1023 |
1258 |
| 1024 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { |
1259 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { |
| 1025 close(source); |
1260 close(source); |
| 1026 if(!phb->account || phb->account->gc) |
1261 |
| |
1262 if (phb->account == NULL || |
| |
1263 gaim_account_get_connection(phb->account) != NULL) { |
| |
1264 |
| 1027 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1265 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1266 } |
| |
1267 |
| 1028 g_free(phb->host); |
1268 g_free(phb->host); |
| 1029 g_free(phb); |
1269 g_free(phb); |
| 1030 return; |
1270 return; |
| 1031 } |
1271 } |
| 1032 |
1272 |
| 1033 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb); |
1273 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb); |
| 1034 } |
1274 } |
| 1035 |
1275 |
| 1036 static void s5_readauth(gpointer data, gint source, GaimInputCondition cond) |
1276 static void |
| |
1277 s5_readauth(gpointer data, gint source, GaimInputCondition cond) |
| 1037 { |
1278 { |
| 1038 unsigned char buf[512]; |
1279 unsigned char buf[512]; |
| 1039 struct PHB *phb = data; |
1280 struct PHB *phb = data; |
| 1040 |
1281 |
| 1041 gaim_input_remove(phb->inpa); |
1282 gaim_input_remove(phb->inpa); |
| 1042 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got auth response.\n"); |
1283 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got auth response.\n"); |
| 1043 |
1284 |
| 1044 if (read(source, buf, 2) < 2) { |
1285 if (read(source, buf, 2) < 2) { |
| 1045 close(source); |
1286 close(source); |
| 1046 if(!phb->account || phb->account->gc) |
1287 |
| |
1288 if (phb->account == NULL || |
| |
1289 gaim_account_get_connection(phb->account) != NULL) { |
| |
1290 |
| 1047 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1291 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1292 } |
| |
1293 |
| 1048 g_free(phb->host); |
1294 g_free(phb->host); |
| 1049 g_free(phb); |
1295 g_free(phb); |
| 1050 return; |
1296 return; |
| 1051 } |
1297 } |
| 1052 |
1298 |
| 1053 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { |
1299 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { |
| 1054 close(source); |
1300 close(source); |
| 1055 if(!phb->account || phb->account->gc) |
1301 |
| |
1302 if (phb->account == NULL || |
| |
1303 gaim_account_get_connection(phb->account) != NULL) { |
| |
1304 |
| 1056 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1305 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1306 } |
| |
1307 |
| 1057 g_free(phb->host); |
1308 g_free(phb->host); |
| 1058 g_free(phb); |
1309 g_free(phb); |
| 1059 return; |
1310 return; |
| 1060 } |
1311 } |
| 1061 |
1312 |
| 1062 s5_sendconnect(phb, source); |
1313 s5_sendconnect(phb, source); |
| 1063 } |
1314 } |
| 1064 |
1315 |
| 1065 static void s5_canread(gpointer data, gint source, GaimInputCondition cond) |
1316 static void |
| |
1317 s5_canread(gpointer data, gint source, GaimInputCondition cond) |
| 1066 { |
1318 { |
| 1067 unsigned char buf[512]; |
1319 unsigned char buf[512]; |
| 1068 struct PHB *phb = data; |
1320 struct PHB *phb = data; |
| 1069 |
1321 |
| 1070 gaim_input_remove(phb->inpa); |
1322 gaim_input_remove(phb->inpa); |
| 1071 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Able to read.\n"); |
1323 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Able to read.\n"); |
| 1072 |
1324 |
| 1073 if (read(source, buf, 2) < 2) { |
1325 if (read(source, buf, 2) < 2) { |
| 1074 close(source); |
1326 close(source); |
| 1075 if(!phb->account || phb->account->gc) |
1327 |
| |
1328 if (phb->account == NULL || |
| |
1329 gaim_account_get_connection(phb->account) != NULL) { |
| |
1330 |
| 1076 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1331 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1332 } |
| |
1333 |
| 1077 g_free(phb->host); |
1334 g_free(phb->host); |
| 1078 g_free(phb); |
1335 g_free(phb); |
| 1079 return; |
1336 return; |
| 1080 } |
1337 } |
| 1081 |
1338 |
| 1082 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { |
1339 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { |
| 1083 close(source); |
1340 close(source); |
| 1084 if(!phb->account || phb->account->gc) |
1341 |
| |
1342 if (phb->account == NULL || |
| |
1343 gaim_account_get_connection(phb->account) != NULL) { |
| |
1344 |
| 1085 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1345 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1346 } |
| |
1347 |
| 1086 g_free(phb->host); |
1348 g_free(phb->host); |
| 1087 g_free(phb); |
1349 g_free(phb); |
| 1088 return; |
1350 return; |
| 1089 } |
1351 } |
| 1090 |
1352 |
| 1091 if (buf[1] == 0x02) { |
1353 if (buf[1] == 0x02) { |
| 1092 unsigned int i = strlen(phb->gpi->proxyuser), j = strlen(phb->gpi->proxypass); |
1354 unsigned int i, j; |
| |
1355 |
| |
1356 i = strlen(gaim_proxy_info_get_username(phb->gpi)); |
| |
1357 j = strlen(gaim_proxy_info_get_password(phb->gpi)); |
| |
1358 |
| 1093 buf[0] = 0x01; /* version 1 */ |
1359 buf[0] = 0x01; /* version 1 */ |
| 1094 buf[1] = i; |
1360 buf[1] = i; |
| 1095 memcpy(buf + 2, phb->gpi->proxyuser, i); |
1361 memcpy(buf + 2, gaim_proxy_info_get_username(phb->gpi), i); |
| 1096 buf[2 + i] = j; |
1362 buf[2 + i] = j; |
| 1097 memcpy(buf + 2 + i + 1, phb->gpi->proxypass, j); |
1363 memcpy(buf + 2 + i + 1, gaim_proxy_info_get_password(phb->gpi), j); |
| 1098 |
1364 |
| 1099 if (write(source, buf, 3 + i + j) < 3 + i + j) { |
1365 if (write(source, buf, 3 + i + j) < 3 + i + j) { |
| 1100 close(source); |
1366 close(source); |
| 1101 if(!phb->account || phb->account->gc) |
1367 |
| |
1368 if (phb->account == NULL || |
| |
1369 gaim_account_get_connection(phb->account) != NULL) { |
| |
1370 |
| 1102 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1371 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1372 } |
| |
1373 |
| 1103 g_free(phb->host); |
1374 g_free(phb->host); |
| 1104 g_free(phb); |
1375 g_free(phb); |
| 1105 return; |
1376 return; |
| 1106 } |
1377 } |
| 1107 |
1378 |
| 1108 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_readauth, phb); |
1379 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_readauth, phb); |
| 1109 } else { |
1380 } |
| |
1381 else { |
| 1110 s5_sendconnect(phb, source); |
1382 s5_sendconnect(phb, source); |
| 1111 } |
1383 } |
| 1112 } |
1384 } |
| 1113 |
1385 |
| 1114 static void s5_canwrite(gpointer data, gint source, GaimInputCondition cond) |
1386 static void |
| |
1387 s5_canwrite(gpointer data, gint source, GaimInputCondition cond) |
| 1115 { |
1388 { |
| 1116 unsigned char buf[512]; |
1389 unsigned char buf[512]; |
| 1117 int i; |
1390 int i; |
| 1118 struct PHB *phb = data; |
1391 struct PHB *phb = data; |
| 1119 unsigned int len; |
1392 unsigned int len; |
| 1121 |
1394 |
| 1122 gaim_debug(GAIM_INFO, "socks5 proxy", "Connected.\n"); |
1395 gaim_debug(GAIM_INFO, "socks5 proxy", "Connected.\n"); |
| 1123 |
1396 |
| 1124 if (phb->inpa > 0) |
1397 if (phb->inpa > 0) |
| 1125 gaim_input_remove(phb->inpa); |
1398 gaim_input_remove(phb->inpa); |
| |
1399 |
| 1126 len = sizeof(error); |
1400 len = sizeof(error); |
| 1127 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
1401 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 1128 close(source); |
1402 close(source); |
| 1129 if(!phb->account || phb->account->gc) |
1403 if (phb->account == NULL || |
| |
1404 gaim_account_get_connection(phb->account) != NULL) { |
| |
1405 |
| 1130 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1406 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1407 } |
| |
1408 |
| 1131 g_free(phb->host); |
1409 g_free(phb->host); |
| 1132 g_free(phb); |
1410 g_free(phb); |
| 1133 return; |
1411 return; |
| 1134 } |
1412 } |
| 1135 fcntl(source, F_SETFL, 0); |
1413 fcntl(source, F_SETFL, 0); |
| 1136 |
1414 |
| 1137 i = 0; |
1415 i = 0; |
| 1138 buf[0] = 0x05; /* SOCKS version 5 */ |
1416 buf[0] = 0x05; /* SOCKS version 5 */ |
| 1139 if (phb->gpi->proxyuser[0]) { |
1417 |
| |
1418 if (gaim_proxy_info_get_username(phb->gpi) != NULL) { |
| 1140 buf[1] = 0x02; /* two methods */ |
1419 buf[1] = 0x02; /* two methods */ |
| 1141 buf[2] = 0x00; /* no authentication */ |
1420 buf[2] = 0x00; /* no authentication */ |
| 1142 buf[3] = 0x02; /* username/password authentication */ |
1421 buf[3] = 0x02; /* username/password authentication */ |
| 1143 i = 4; |
1422 i = 4; |
| 1144 } else { |
1423 } |
| |
1424 else { |
| 1145 buf[1] = 0x01; |
1425 buf[1] = 0x01; |
| 1146 buf[2] = 0x00; |
1426 buf[2] = 0x00; |
| 1147 i = 3; |
1427 i = 3; |
| 1148 } |
1428 } |
| 1149 |
1429 |
| 1150 if (write(source, buf, i) < i) { |
1430 if (write(source, buf, i) < i) { |
| 1151 gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "Unable to write\n"); |
1431 gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "Unable to write\n"); |
| 1152 close(source); |
1432 close(source); |
| 1153 if(!phb->account || phb->account->gc) |
1433 |
| |
1434 if (phb->account == NULL || |
| |
1435 gaim_account_get_connection(phb->account) != NULL) { |
| |
1436 |
| 1154 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1437 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1438 } |
| |
1439 |
| 1155 g_free(phb->host); |
1440 g_free(phb->host); |
| 1156 g_free(phb); |
1441 g_free(phb); |
| 1157 return; |
1442 return; |
| 1158 } |
1443 } |
| 1159 |
1444 |
| 1160 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread, phb); |
1445 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread, phb); |
| 1161 } |
1446 } |
| 1162 |
1447 |
| 1163 static int proxy_connect_socks5(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
1448 static int |
| |
1449 proxy_connect_socks5(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
| 1164 { |
1450 { |
| 1165 int fd = -1; |
1451 int fd = -1; |
| 1166 |
1452 |
| 1167 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", |
1453 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", |
| 1168 "Connecting to %s:%d via %s:%d using SOCKS5\n", |
1454 "Connecting to %s:%d via %s:%d using SOCKS5\n", |
| 1169 phb->host, phb->port, phb->gpi->proxyhost, |
1455 phb->host, phb->port, |
| 1170 phb->gpi->proxyport); |
1456 gaim_proxy_info_get_host(phb->gpi), |
| 1171 |
1457 gaim_proxy_info_get_port(phb->gpi)); |
| 1172 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
1458 |
| |
1459 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) |
| 1173 return -1; |
1460 return -1; |
| 1174 } |
|
| 1175 |
1461 |
| 1176 fcntl(fd, F_SETFL, O_NONBLOCK); |
1462 fcntl(fd, F_SETFL, O_NONBLOCK); |
| |
1463 |
| 1177 if (connect(fd, addr, addrlen) < 0) { |
1464 if (connect(fd, addr, addrlen) < 0) { |
| 1178 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
1465 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
| 1179 gaim_debug(GAIM_DEBUG_WARNING, "socks5 proxy", |
1466 gaim_debug(GAIM_DEBUG_WARNING, "socks5 proxy", |
| 1180 "Connect would have blocked.\n"); |
1467 "Connect would have blocked.\n"); |
| |
1468 |
| 1181 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, phb); |
1469 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, phb); |
| 1182 } else { |
1470 } |
| |
1471 else { |
| 1183 close(fd); |
1472 close(fd); |
| 1184 return -1; |
1473 return -1; |
| 1185 } |
1474 } |
| 1186 } else { |
1475 } |
| |
1476 else { |
| 1187 unsigned int len; |
1477 unsigned int len; |
| 1188 int error = ETIMEDOUT; |
1478 int error = ETIMEDOUT; |
| 1189 |
1479 |
| 1190 gaim_debug(GAIM_DEBUG_MISC, "socks5 proxy", |
1480 gaim_debug(GAIM_DEBUG_MISC, "socks5 proxy", |
| 1191 "Connect didn't block.\n"); |
1481 "Connect didn't block.\n"); |
| |
1482 |
| 1192 len = sizeof(error); |
1483 len = sizeof(error); |
| |
1484 |
| 1193 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
1485 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 1194 close(fd); |
1486 close(fd); |
| 1195 return -1; |
1487 return -1; |
| 1196 } |
1488 } |
| |
1489 |
| 1197 fcntl(fd, F_SETFL, 0); |
1490 fcntl(fd, F_SETFL, 0); |
| 1198 s5_canwrite(phb, fd, GAIM_INPUT_WRITE); |
1491 s5_canwrite(phb, fd, GAIM_INPUT_WRITE); |
| 1199 } |
1492 } |
| 1200 |
1493 |
| 1201 return fd; |
1494 return fd; |
| 1202 } |
1495 } |
| 1203 |
1496 |
| 1204 static void connection_host_resolved(GSList *hosts, gpointer data, const char *error_message) |
1497 static void |
| |
1498 connection_host_resolved(GSList *hosts, gpointer data, |
| |
1499 const char *error_message) |
| 1205 { |
1500 { |
| 1206 struct PHB *phb = (struct PHB*)data; |
1501 struct PHB *phb = (struct PHB*)data; |
| 1207 size_t addrlen; |
1502 size_t addrlen; |
| 1208 struct sockaddr *addr; |
1503 struct sockaddr *addr; |
| 1209 int ret = -1; |
1504 int ret = -1; |
| 1210 |
1505 |
| 1211 while(hosts) { |
1506 while (hosts) { |
| 1212 addrlen = GPOINTER_TO_INT(hosts->data); |
1507 addrlen = GPOINTER_TO_INT(hosts->data); |
| 1213 hosts = hosts->next; |
1508 hosts = hosts->next; |
| 1214 addr = hosts->data; |
1509 addr = hosts->data; |
| 1215 hosts = hosts->next; |
1510 hosts = hosts->next; |
| 1216 |
1511 |
| 1217 switch(phb->gpi->proxytype) |
1512 switch (gaim_proxy_info_get_type(phb->gpi)) |
| 1218 { |
1513 { |
| 1219 case PROXY_NONE: |
1514 case GAIM_PROXY_NONE: |
| 1220 ret = proxy_connect_none(phb, addr, addrlen); |
1515 ret = proxy_connect_none(phb, addr, addrlen); |
| 1221 break; |
1516 break; |
| 1222 case PROXY_HTTP: |
1517 |
| |
1518 case GAIM_PROXY_HTTP: |
| 1223 ret = proxy_connect_http(phb, addr, addrlen); |
1519 ret = proxy_connect_http(phb, addr, addrlen); |
| 1224 break; |
1520 break; |
| 1225 case PROXY_SOCKS4: |
1521 |
| |
1522 case GAIM_PROXY_SOCKS4: |
| 1226 ret = proxy_connect_socks4(phb, addr, addrlen); |
1523 ret = proxy_connect_socks4(phb, addr, addrlen); |
| 1227 break; |
1524 break; |
| 1228 case PROXY_SOCKS5: |
1525 |
| |
1526 case GAIM_PROXY_SOCKS5: |
| 1229 ret = proxy_connect_socks5(phb, addr, addrlen); |
1527 ret = proxy_connect_socks5(phb, addr, addrlen); |
| 1230 break; |
1528 break; |
| 1231 } |
1529 |
| |
1530 default: |
| |
1531 break; |
| |
1532 } |
| |
1533 |
| 1232 if (ret > 0) |
1534 if (ret > 0) |
| 1233 break; |
1535 break; |
| 1234 } |
1536 } |
| 1235 if(ret < 0) { |
1537 |
| 1236 if(!phb->account || phb->account->gc) |
1538 if (ret < 0) { |
| |
1539 if (phb->account == NULL || |
| |
1540 gaim_account_get_connection(phb->account) != NULL) { |
| |
1541 |
| 1237 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1542 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| |
1543 } |
| |
1544 |
| 1238 g_free(phb->host); |
1545 g_free(phb->host); |
| 1239 g_free(phb); |
1546 g_free(phb); |
| 1240 } |
1547 } |
| 1241 } |
1548 } |
| 1242 |
1549 |
| 1243 int |
1550 int |
| 1244 proxy_connect(GaimAccount *account, const char *host, int port, GaimInputFunction func, gpointer data) |
1551 gaim_proxy_connect(GaimAccount *account, const char *host, int port, |
| |
1552 GaimInputFunction func, gpointer data) |
| 1245 { |
1553 { |
| 1246 const char *connecthost = host; |
1554 const char *connecthost = host; |
| 1247 int connectport = port; |
1555 int connectport = port; |
| 1248 struct PHB *phb = g_new0(struct PHB, 1); |
1556 struct PHB *phb = g_new0(struct PHB, 1); |
| 1249 if(!account || !account->gpi) |
1557 |
| 1250 phb->gpi = &global_proxy_info; |
1558 g_return_val_if_fail(host != NULL, -1); |
| |
1559 g_return_val_if_fail(port != 0 && port != -1, -1); |
| |
1560 g_return_val_if_fail(func != NULL, -1); |
| |
1561 |
| |
1562 if (account == NULL || gaim_account_get_proxy_info(account) == NULL) |
| |
1563 phb->gpi = gaim_global_proxy_get_info(); |
| 1251 else |
1564 else |
| 1252 phb->gpi = account->gpi; |
1565 phb->gpi = gaim_account_get_proxy_info(account); |
| |
1566 |
| 1253 phb->func = func; |
1567 phb->func = func; |
| 1254 phb->data = data; |
1568 phb->data = data; |
| 1255 phb->host = g_strdup(host); |
1569 phb->host = g_strdup(host); |
| 1256 phb->port = port; |
1570 phb->port = port; |
| 1257 phb->account = account; |
1571 phb->account = account; |
| 1258 |
1572 |
| 1259 if (!host || !port || (port == -1) || !func) { |
1573 if ((gaim_proxy_info_get_type(phb->gpi) != GAIM_PROXY_NONE) && |
| 1260 if(host) |
1574 (gaim_proxy_info_get_host(phb->gpi) == NULL || |
| 1261 g_free(phb->host); |
1575 gaim_proxy_info_get_port(phb->gpi) == 0 || |
| 1262 g_free(phb); |
1576 gaim_proxy_info_get_port(phb->gpi) == -1)) { |
| 1263 return -1; |
1577 |
| 1264 } |
1578 gaim_proxy_info_set_type(phb->gpi, GAIM_PROXY_NONE); |
| 1265 |
1579 } |
| 1266 if ((phb->gpi->proxytype!=PROXY_NONE) && (!phb->gpi->proxyhost || !phb->gpi->proxyhost[0] || !phb->gpi->proxyport || (phb->gpi->proxyport == -1))) |
1580 |
| 1267 phb->gpi->proxytype=PROXY_NONE; |
1581 switch (gaim_proxy_info_get_type(phb->gpi)) |
| 1268 |
|
| 1269 switch(phb->gpi->proxytype) |
|
| 1270 { |
1582 { |
| 1271 case PROXY_NONE: |
1583 case GAIM_PROXY_NONE: |
| 1272 break; |
1584 break; |
| 1273 case PROXY_HTTP: |
1585 |
| 1274 case PROXY_SOCKS4: |
1586 case GAIM_PROXY_HTTP: |
| 1275 case PROXY_SOCKS5: |
1587 case GAIM_PROXY_SOCKS4: |
| 1276 connecthost=phb->gpi->proxyhost; |
1588 case GAIM_PROXY_SOCKS5: |
| 1277 connectport=phb->gpi->proxyport; |
1589 connecthost = gaim_proxy_info_get_host(phb->gpi); |
| |
1590 connectport = gaim_proxy_info_get_port(phb->gpi); |
| 1278 break; |
1591 break; |
| |
1592 |
| 1279 default: |
1593 default: |
| 1280 g_free(phb->host); |
1594 g_free(phb->host); |
| 1281 g_free(phb); |
1595 g_free(phb); |
| 1282 return -1; |
1596 return -1; |
| 1283 } |
1597 } |
| 1284 |
1598 |
| 1285 return gaim_gethostbyname_async(connecthost, connectport, connection_host_resolved, phb); |
1599 return gaim_gethostbyname_async(connecthost, connectport, |
| 1286 } |
1600 connection_host_resolved, phb); |
| |
1601 } |
| |
1602 |
| |
1603 |
| |
1604 static void |
| |
1605 proxy_pref_cb(const char *name, GaimPrefType type, gpointer value, |
| |
1606 gpointer data) |
| |
1607 { |
| |
1608 GaimProxyInfo *info = gaim_global_proxy_get_info(); |
| |
1609 |
| |
1610 if (!strcmp(name, "/core/proxy/type")) |
| |
1611 gaim_proxy_info_set_type(info, GPOINTER_TO_INT(value)); |
| |
1612 else if (!strcmp(name, "/core/proxy/host")) |
| |
1613 gaim_proxy_info_set_host(info, value); |
| |
1614 else if (!strcmp(name, "/core/proxy/port")) |
| |
1615 gaim_proxy_info_set_port(info, GPOINTER_TO_INT(value)); |
| |
1616 else if (!strcmp(name, "/core/proxy/username")) |
| |
1617 gaim_proxy_info_set_username(info, value); |
| |
1618 else if (!strcmp(name, "/core/proxy/password")) |
| |
1619 gaim_proxy_info_set_password(info, value); |
| |
1620 } |
| |
1621 |
| |
1622 void |
| |
1623 gaim_proxy_init(void) |
| |
1624 { |
| |
1625 /* Initialize a default proxy info struct. */ |
| |
1626 global_proxy_info = gaim_proxy_info_new(); |
| |
1627 |
| |
1628 /* Proxy */ |
| |
1629 gaim_prefs_add_none("/core/proxy"); |
| |
1630 gaim_prefs_add_string("/core/proxy/type", "none"); |
| |
1631 gaim_prefs_add_string("/core/proxy/host", ""); |
| |
1632 gaim_prefs_add_int("/core/proxy/port", 0); |
| |
1633 gaim_prefs_add_string("/core/proxy/username", ""); |
| |
1634 gaim_prefs_add_string("/core/proxy/password", ""); |
| |
1635 |
| |
1636 /* Setup callbacks for the preferences. */ |
| |
1637 gaim_prefs_connect_callback("/core/proxy/type", |
| |
1638 proxy_pref_cb, NULL); |
| |
1639 gaim_prefs_connect_callback("/core/proxy/host", |
| |
1640 proxy_pref_cb, NULL); |
| |
1641 gaim_prefs_connect_callback("/core/proxy/port", |
| |
1642 proxy_pref_cb, NULL); |
| |
1643 gaim_prefs_connect_callback("/core/proxy/username", |
| |
1644 proxy_pref_cb, NULL); |
| |
1645 gaim_prefs_connect_callback("/core/proxy/password", |
| |
1646 proxy_pref_cb, NULL); |
| |
1647 } |