1 /***************************************************************************/
2 /* This code is part of WWW grabber called pavuk */
3 /* Copyright (c) 1997 - 2001 Stefan Ondrejicka */
4 /* Distributed under GPL 2 or later */
5 /***************************************************************************/
6
7 #include <string.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <sys/socket.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13
14 #include "config.h"
15 #include "gcinfo.h"
16 #include "url.h"
17 #include "doc.h"
18 #include "tools.h"
19 #include "http.h"
20 #include "ftp.h"
21 #include "myssl.h"
22
save_global_connection_data(global_connection_info * infop,doc * docp)23 void save_global_connection_data(global_connection_info *infop, doc *docp)
24 {
25 /*** preserve FTP control connection ***/
26 if(docp->ftp_control)
27 {
28 infop->ftp_con.proto = docp->doc_url->type;
29 infop->ftp_con.control = docp->ftp_control;
30 infop->ftp_con.host = new_string(url_get_site(docp->doc_url));
31 infop->ftp_con.port = url_get_port(docp->doc_url);
32 infop->ftp_con.user = new_string(url_get_user(docp->doc_url, NULL));
33 infop->ftp_con.passwd = new_string(url_get_pass(docp->doc_url, NULL));
34 }
35 else
36 {
37 infop->ftp_con.control = NULL;
38 infop->ftp_con.port = 0;
39 _free(infop->ftp_con.host);
40 _free(infop->ftp_con.user);
41 _free(infop->ftp_con.passwd);
42 }
43
44 /*** preserve SSL connection ***/
45 #if defined(USE_SSL) && defined(USE_SSL_IMPL_OPENSSL)
46 if(docp->ssl_data_con.ssl_con)
47 {
48 infop->ssl_con.ssl_con = docp->ssl_data_con.ssl_con;
49 infop->ssl_con.ssl_ctx = docp->ssl_data_con.ssl_ctx;
50 }
51 else
52 {
53 infop->ssl_con.ssl_con = NULL;
54 infop->ssl_con.ssl_ctx = NULL;
55 }
56 #endif
57 /*** preserve HTTP connection infos ***/
58 if(cfg.auth_reuse_nonce)
59 infop->http_con.auth_digest = (http_digest_info *) docp->auth_digest;
60 else
61 infop->http_con.auth_digest = NULL;
62
63 if(cfg.auth_reuse_proxy_nonce)
64 infop->http_con.auth_proxy_digest =
65 (http_digest_info *) docp->auth_proxy_digest;
66 else
67 infop->http_con.auth_proxy_digest = NULL;
68
69 if(docp->datasock)
70 {
71 infop->http_con.connection = docp->datasock;
72 infop->http_con.proto = docp->doc_url->type;
73 infop->http_con.port = url_get_port(docp->doc_url);
74 infop->http_con.host = new_string(url_get_site(docp->doc_url));
75
76 if(docp->http_proxy)
77 {
78 infop->http_con.http_proxy_port = docp->http_proxy_port;
79 infop->http_con.http_proxy = docp->http_proxy;
80 docp->http_proxy = NULL;
81 }
82 else
83 {
84 infop->http_con.http_proxy = NULL;
85 infop->http_con.http_proxy_port = 0;
86 }
87 }
88 else
89 {
90 infop->http_con.connection = NULL;
91 infop->http_con.proto = docp->doc_url->type;
92 infop->http_con.port = 0;
93 _free(infop->http_con.host);
94 _free(infop->http_con.http_proxy);
95 }
96 _free(docp->http_proxy);
97 }
98
restore_global_connection_data(global_connection_info * infop,doc * docp)99 void restore_global_connection_data(global_connection_info *infop, doc *docp)
100 {
101 #if defined(HAVE_MT) && defined(I_FACE)
102 if(cfg.cfg_changed > cfg.timestamp)
103 {
104 privcfg_free(&priv_cfg);
105 privcfg_make_copy(&priv_cfg);
106 }
107 #endif
108 if(infop->ftp_con.control)
109 {
110 char *pass = url_get_pass(docp->doc_url, NULL);
111 char *user = url_get_user(docp->doc_url, NULL);
112 char *host = url_get_site(docp->doc_url);
113 unsigned short port = url_get_port(docp->doc_url);
114
115 if((docp->doc_url->type == URLT_FTP ||
116 docp->doc_url->type == URLT_FTPS) &&
117 infop->ftp_con.proto == docp->doc_url->type &&
118 infop->ftp_con.port == port &&
119 !strcmp(infop->ftp_con.host, host) &&
120 ((pass && infop->ftp_con.passwd &&
121 !strcmp(pass, infop->ftp_con.passwd)) ||
122 (!pass && !infop->ftp_con.passwd)) &&
123 ((user && infop->ftp_con.user &&
124 !strcmp(user, infop->ftp_con.user)) ||
125 (!user && !infop->ftp_con.user)))
126 {
127 docp->ftp_control = infop->ftp_con.control;
128 }
129 else
130 {
131 bufio_write(infop->ftp_con.control, "QUIT\r\n", 6);
132 bufio_close(infop->ftp_con.control);
133 }
134 _free(infop->ftp_con.host);
135 _free(infop->ftp_con.user);
136 _free(infop->ftp_con.passwd);
137 }
138 infop->ftp_con.control = NULL;
139 #if defined(USE_SSL) && defined(USE_SSL_IMPL_OPENSSL)
140 if(infop->ssl_con.ssl_con)
141 {
142 docp->ssl_data_con.ssl_con = infop->ssl_con.ssl_con;
143 docp->ssl_data_con.ssl_ctx = infop->ssl_con.ssl_ctx;
144 }
145 else
146 memset(&docp->ssl_data_con, '\0', sizeof(ssl_connection));
147 #endif
148 if(cfg.auth_reuse_nonce && infop->http_con.auth_digest &&
149 (docp->doc_url->type == URLT_HTTP || docp->doc_url->type == URLT_HTTPS))
150 {
151 if(!strcmp(infop->http_con.auth_digest->site,
152 url_get_site(docp->doc_url)) &&
153 infop->http_con.auth_digest->port == url_get_port(docp->doc_url))
154 {
155 docp->auth_digest = infop->http_con.auth_digest;
156 }
157 else
158 {
159 http_digest_deep_free(infop->http_con.auth_digest);
160 }
161 }
162 infop->http_con.auth_digest = NULL;
163
164 if(cfg.auth_reuse_proxy_nonce)
165 docp->auth_proxy_digest = infop->http_con.auth_proxy_digest;
166 else
167 {
168 if(infop->http_con.auth_proxy_digest)
169 http_digest_deep_free(infop->http_con.auth_proxy_digest);
170 }
171 infop->http_con.auth_proxy_digest = NULL;
172
173 if(infop->http_con.connection)
174 {
175 char *host = url_get_site(docp->doc_url);
176 unsigned short port = url_get_port(docp->doc_url);
177
178 if(infop->http_con.proto == docp->doc_url->type &&
179 infop->http_con.port == port && !strcmp(infop->http_con.host, host))
180 {
181 docp->datasock = infop->http_con.connection;
182 docp->http_proxy = infop->http_con.http_proxy;
183 docp->http_proxy_port = infop->http_con.http_proxy_port;
184 }
185 else
186 {
187 bufio_close(infop->http_con.connection);
188 docp->datasock = NULL;
189 _free(infop->http_con.http_proxy);
190 }
191 infop->http_con.connection = NULL;
192 _free(infop->http_con.host);
193 }
194 }
195
kill_global_connection_data(global_connection_info * infop)196 void kill_global_connection_data(global_connection_info *infop)
197 {
198 /**** close FTP control connection ****/
199 if(infop->ftp_con.control)
200 {
201 bufio_write(infop->ftp_con.control, "QUIT\r\n", 6);
202 bufio_close(infop->ftp_con.control);
203 infop->ftp_con.control = NULL;
204 _free(infop->ftp_con.host);
205 _free(infop->ftp_con.user);
206 _free(infop->ftp_con.passwd);
207 }
208 /*** close preserved SSL connection ***/
209 #if defined(USE_SSL) && defined(USE_SSL_IMPL_OPENSSL)
210 if(infop->ssl_con.ssl_con)
211 my_ssl_connection_close(&infop->ssl_con);
212 #endif
213 if(infop->http_con.auth_digest)
214 http_digest_deep_free(infop->http_con.auth_digest);
215 if(infop->http_con.auth_proxy_digest)
216 http_digest_deep_free(infop->http_con.auth_proxy_digest);
217
218 if(infop->http_con.connection)
219 {
220 bufio_close(infop->http_con.connection);
221 _free(infop->http_con.host);
222 }
223 _free(infop->http_con.http_proxy);
224 }
225
init_global_connection_data(global_connection_info * infop)226 void init_global_connection_data(global_connection_info *infop)
227 {
228 infop->ftp_con.proto = URLT_FTP;
229 infop->ftp_con.port = 0;
230 infop->ftp_con.host = NULL;
231 infop->ftp_con.user = NULL;
232 infop->ftp_con.passwd = NULL;
233 infop->ftp_con.control = NULL;
234 #ifdef USE_SSL
235 memset(&infop->ssl_con, '\0', sizeof(ssl_connection));
236 #endif
237 infop->http_con.auth_digest = NULL;
238 infop->http_con.auth_proxy_digest = NULL;
239 infop->http_con.connection = NULL;
240 infop->http_con.host = NULL;
241 infop->http_con.proto = URLT_HTTP;
242 infop->http_con.port = 0;
243 infop->http_con.http_proxy_port = 0;
244 infop->http_con.http_proxy = NULL;
245 }
246