950
|
1 /*****************************************************************************/
|
|
2 /* socket-connect.c - contains functions for connecting to a server */
|
|
3 /* Copyright (C) 1998-2008 Brian Masney <masneyb@gftp.org> */
|
|
4 /* */
|
|
5 /* This program is free software; you can redistribute it and/or modify */
|
|
6 /* it under the terms of the GNU General Public License as published by */
|
|
7 /* the Free Software Foundation; either version 2 of the License, or */
|
|
8 /* (at your option) any later version. */
|
|
9 /* */
|
|
10 /* This program is distributed in the hope that it will be useful, */
|
|
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
|
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
|
13 /* GNU General Public License for more details. */
|
|
14 /* */
|
|
15 /* You should have received a copy of the GNU General Public License */
|
|
16 /* along with this program; if not, write to the Free Software */
|
|
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */
|
|
18 /*****************************************************************************/
|
|
19
|
|
20 #include "gftp.h"
|
|
21 static const char cvsid[] = "$Id: protocols.c 952 2008-01-24 23:31:26Z masneyb $";
|
|
22
|
|
23 static int
|
|
24 gftp_need_proxy (gftp_request * request, char *service, char *proxy_hostname,
|
952
|
25 unsigned int proxy_port, void **connect_data)
|
950
|
26 {
|
|
27 gftp_config_list_vars * proxy_hosts;
|
|
28 gftp_proxy_hosts * hostname;
|
|
29 size_t hostlen, domlen;
|
|
30 unsigned char addy[4];
|
|
31 GList * templist;
|
|
32 gint32 netaddr;
|
|
33 char *pos;
|
952
|
34
|
|
35 #if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR)
|
|
36 struct hostent host;
|
|
37 int ret;
|
950
|
38 #endif
|
|
39
|
|
40 gftp_lookup_global_option ("dont_use_proxy", &proxy_hosts);
|
|
41
|
|
42 if (proxy_hostname == NULL || *proxy_hostname == '\0')
|
|
43 return (0);
|
|
44 else if (proxy_hosts->list == NULL)
|
|
45 return (proxy_hostname != NULL &&
|
|
46 *proxy_hostname != '\0');
|
|
47
|
|
48 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
|
|
49
|
952
|
50 *connect_data = lookup_host_with_getaddrinfo (request, service,
|
|
51 proxy_hostname, proxy_port);
|
|
52 if (*connect_data == NULL)
|
|
53 return (GFTP_ERETRYABLE);
|
950
|
54
|
|
55 #else /* !HAVE_GETADDRINFO */
|
|
56
|
952
|
57 ret = lookup_host_with_gethostbyname (request, proxy_hostname, &host);
|
|
58 if (ret != 0)
|
|
59 return (ret);
|
950
|
60
|
952
|
61 connect_data = NULL; /* FIXME */
|
950
|
62
|
952
|
63 #endif
|
950
|
64
|
|
65 templist = proxy_hosts->list;
|
|
66 while (templist != NULL)
|
|
67 {
|
|
68 hostname = templist->data;
|
|
69 if (hostname->domain != NULL)
|
|
70 {
|
|
71 hostlen = strlen (request->hostname);
|
|
72 domlen = strlen (hostname->domain);
|
|
73 if (hostlen > domlen)
|
|
74 {
|
|
75 pos = request->hostname + hostlen - domlen;
|
|
76 if (strcmp (hostname->domain, pos) == 0)
|
|
77 return (0);
|
|
78 }
|
|
79 }
|
|
80
|
|
81 if (hostname->ipv4_network_address != 0)
|
|
82 {
|
952
|
83 memcpy (addy, request->remote_addr, sizeof (*addy));
|
950
|
84 netaddr =
|
|
85 (((addy[0] & 0xff) << 24) | ((addy[1] & 0xff) << 16) |
|
|
86 ((addy[2] & 0xff) << 8) | (addy[3] & 0xff)) &
|
|
87 hostname->ipv4_netmask;
|
|
88 if (netaddr == hostname->ipv4_network_address)
|
|
89 return (0);
|
|
90 }
|
|
91 templist = templist->next;
|
|
92 }
|
|
93
|
|
94 return (proxy_hostname != NULL && *proxy_hostname != '\0');
|
|
95 }
|
|
96
|
|
97
|
|
98 int
|
|
99 gftp_connect_server (gftp_request * request, char *service,
|
|
100 char *proxy_hostname, unsigned int proxy_port)
|
|
101 {
|
952
|
102 void *connect_data;
|
|
103 int sock, ret;
|
950
|
104
|
952
|
105 if ((ret = gftp_need_proxy (request, service, proxy_hostname,
|
|
106 proxy_port, &connect_data)) < 0)
|
|
107 return (ret);
|
|
108 request->use_proxy = ret;
|
|
109
|
|
110 /* FIXME - pass connect_data to these functions. This is to bypass a
|
|
111 second DNS lookup */
|
950
|
112 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
|
952
|
113 sock = gftp_connect_server_with_getaddrinfo (request, service, proxy_hostname,
|
|
114 proxy_port);
|
950
|
115 #else
|
|
116 sock = gftp_connect_server_legacy (request, service, proxy_hostname,
|
|
117 proxy_port);
|
|
118 #endif
|
|
119
|
|
120 if (sock < 0)
|
|
121 return (sock);
|
|
122
|
|
123 if (fcntl (sock, F_SETFD, 1) == -1)
|
|
124 {
|
|
125 request->logging_function (gftp_logging_error, request,
|
|
126 _("Error: Cannot set close on exec flag: %s\n"),
|
|
127 g_strerror (errno));
|
|
128 close (sock);
|
|
129 return (GFTP_ERETRYABLE);
|
|
130 }
|
|
131
|
|
132 if (gftp_fd_set_sockblocking (request, sock, 1) < 0)
|
|
133 {
|
|
134 close (sock);
|
|
135 return (GFTP_ERETRYABLE);
|
|
136 }
|
|
137
|
|
138 request->datafd = sock;
|
|
139
|
|
140 if (request->post_connect != NULL)
|
|
141 return (request->post_connect (request));
|
|
142
|
|
143 return (0);
|
|
144 }
|
|
145
|