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