|
ali@14
|
1 |
/*
|
|
ali@14
|
2 |
* A program to explore http support on MS-Windows.
|
|
ali@14
|
3 |
*/
|
|
ali@14
|
4 |
|
|
ali@14
|
5 |
#include "config.h"
|
|
ali@14
|
6 |
#include <stdlib.h>
|
|
ali@14
|
7 |
#include <stdio.h>
|
|
ali@14
|
8 |
#include <glib.h>
|
|
ali@14
|
9 |
#include <razor.h>
|
|
ali@14
|
10 |
#if HAVE_WINHTTP_H
|
|
ali@14
|
11 |
#include <windows.h>
|
|
ali@14
|
12 |
#include <winhttp.h>
|
|
ali@14
|
13 |
#include <wincrypt.h>
|
|
ali@14
|
14 |
|
|
ali@14
|
15 |
#ifndef PKCS12_NO_PERSIST_KEY
|
|
ali@14
|
16 |
#define PKCS12_NO_PERSIST_KEY 0x00008000
|
|
ali@14
|
17 |
#endif
|
|
ali@14
|
18 |
|
|
ali@14
|
19 |
static gboolean debug=FALSE;
|
|
ali@14
|
20 |
|
|
ali@14
|
21 |
static GOptionEntry entries[] =
|
|
ali@14
|
22 |
{
|
|
ali@14
|
23 |
{ "debug",'d',0,G_OPTION_ARG_NONE,&debug,"Output debugging",NULL },
|
|
ali@14
|
24 |
{ NULL }
|
|
ali@14
|
25 |
};
|
|
ali@14
|
26 |
|
|
ali@14
|
27 |
static struct WinHttpFuncs
|
|
ali@14
|
28 |
{
|
|
ali@14
|
29 |
WINBOOL (WINAPI *AddRequestHeaders)(HINTERNET,LPCWSTR,DWORD,DWORD);
|
|
ali@14
|
30 |
WINBOOL (WINAPI *DetectAutoProxyConfigUrl)(DWORD,LPWSTR*);
|
|
ali@14
|
31 |
WINBOOL (WINAPI *CheckPlatform)(void);
|
|
ali@14
|
32 |
WINBOOL (WINAPI *CloseHandle)(HINTERNET);
|
|
ali@14
|
33 |
HINTERNET (WINAPI *Connect)(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD);
|
|
ali@14
|
34 |
WINBOOL (WINAPI *CrackUrl)(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS);
|
|
ali@14
|
35 |
WINBOOL (WINAPI *CreateUrl)(LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD);
|
|
ali@14
|
36 |
WINBOOL (WINAPI *GetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*);
|
|
ali@14
|
37 |
WINBOOL (WINAPI *GetIEProxyConfigForCurrentUser)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*);
|
|
ali@14
|
38 |
WINBOOL (WINAPI *GetProxyForUrl)(HINTERNET,LPCWSTR,WINHTTP_AUTOPROXY_OPTIONS*,WINHTTP_PROXY_INFO*);
|
|
ali@14
|
39 |
HINTERNET (WINAPI *Open)(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD);
|
|
ali@14
|
40 |
HINTERNET (WINAPI *OpenRequest)(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD);
|
|
ali@14
|
41 |
WINBOOL (WINAPI *QueryAuthParams)(HINTERNET,DWORD,LPVOID*);
|
|
ali@14
|
42 |
WINBOOL (WINAPI *QueryAuthSchemes)(HINTERNET,LPDWORD,LPDWORD,LPDWORD);
|
|
ali@14
|
43 |
WINBOOL (WINAPI *QueryDataAvailable)(HINTERNET,LPDWORD);
|
|
ali@14
|
44 |
WINBOOL (WINAPI *QueryHeaders)(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD);
|
|
ali@14
|
45 |
WINBOOL (WINAPI *QueryOption)(HINTERNET,DWORD,LPVOID,LPDWORD);
|
|
ali@14
|
46 |
WINBOOL (WINAPI *ReadData)(HINTERNET,LPVOID,DWORD,LPDWORD);
|
|
ali@14
|
47 |
WINBOOL (WINAPI *ReceiveResponse)(HINTERNET,LPVOID);
|
|
ali@14
|
48 |
WINBOOL (WINAPI *SendRequest)(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR);
|
|
ali@14
|
49 |
WINBOOL (WINAPI *SetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*);
|
|
ali@14
|
50 |
WINBOOL (WINAPI *SetCredentials)(HINTERNET,DWORD,DWORD,LPCWSTR,LPCWSTR,LPVOID);
|
|
ali@14
|
51 |
WINBOOL (WINAPI *SetOption)(HINTERNET,DWORD,LPVOID,DWORD);
|
|
ali@14
|
52 |
WINHTTP_STATUS_CALLBACK (WINAPI *SetStatusCallback)(HINTERNET,WINHTTP_STATUS_CALLBACK,DWORD,DWORD_PTR);
|
|
ali@14
|
53 |
WINBOOL (WINAPI *SetTimeouts)(HINTERNET,int,int,int,int);
|
|
ali@14
|
54 |
WINBOOL (WINAPI *TimeFromSystemTime)(CONST SYSTEMTIME *,LPWSTR);
|
|
ali@14
|
55 |
WINBOOL (WINAPI *TimeToSystemTime)(LPCWSTR,SYSTEMTIME*);
|
|
ali@14
|
56 |
WINBOOL (WINAPI *WriteData)(HINTERNET,LPCVOID,DWORD,LPDWORD);
|
|
ali@14
|
57 |
} WinHttp;
|
|
ali@14
|
58 |
|
|
ali@14
|
59 |
static int plover_init_winhttp(void)
|
|
ali@14
|
60 |
{
|
|
ali@14
|
61 |
HMODULE module;
|
|
ali@14
|
62 |
if (WinHttp.Open)
|
|
ali@14
|
63 |
return 0;
|
|
ali@14
|
64 |
module=LoadLibraryA("winhttp.dll");
|
|
ali@14
|
65 |
if (!module)
|
|
ali@14
|
66 |
return -1;
|
|
ali@14
|
67 |
WinHttp.AddRequestHeaders=
|
|
ali@14
|
68 |
(WINBOOL (WINAPI *)(HINTERNET,LPCWSTR,DWORD,DWORD))
|
|
ali@14
|
69 |
GetProcAddress(module,"WinHttpAddRequestHeaders");
|
|
ali@14
|
70 |
WinHttp.DetectAutoProxyConfigUrl=
|
|
ali@14
|
71 |
(WINBOOL (WINAPI *)(DWORD,LPWSTR*))
|
|
ali@14
|
72 |
GetProcAddress(module,"WinHttpDetectAutoProxyConfigUrl");
|
|
ali@14
|
73 |
WinHttp.CheckPlatform=(WINBOOL (WINAPI *)(void))
|
|
ali@14
|
74 |
GetProcAddress(module,"WinHttpCheckPlatform");
|
|
ali@14
|
75 |
WinHttp.CloseHandle=(WINBOOL (WINAPI *)(HINTERNET))
|
|
ali@14
|
76 |
GetProcAddress(module,"WinHttpCloseHandle");
|
|
ali@14
|
77 |
WinHttp.Connect=
|
|
ali@14
|
78 |
(HINTERNET (WINAPI *)(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD))
|
|
ali@14
|
79 |
GetProcAddress(module,"WinHttpConnect");
|
|
ali@14
|
80 |
WinHttp.CrackUrl=(WINBOOL (WINAPI *)(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS))
|
|
ali@14
|
81 |
GetProcAddress(module,"WinHttpCrackUrl");
|
|
ali@14
|
82 |
WinHttp.CreateUrl=
|
|
ali@14
|
83 |
(WINBOOL (WINAPI *)(LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD))
|
|
ali@14
|
84 |
GetProcAddress(module,"WinHttpCreateUrl");
|
|
ali@14
|
85 |
WinHttp.GetDefaultProxyConfiguration=
|
|
ali@14
|
86 |
(WINBOOL (WINAPI *)(WINHTTP_PROXY_INFO*))
|
|
ali@14
|
87 |
GetProcAddress(module,"WinHttpGetDefaultProxyConfiguration");
|
|
ali@14
|
88 |
WinHttp.GetIEProxyConfigForCurrentUser=
|
|
ali@14
|
89 |
(WINBOOL (WINAPI *)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*))
|
|
ali@14
|
90 |
GetProcAddress(module,"WinHttpGetIEProxyConfigForCurrentUser");
|
|
ali@14
|
91 |
WinHttp.GetProxyForUrl=
|
|
ali@14
|
92 |
(WINBOOL (WINAPI *)(HINTERNET,LPCWSTR,WINHTTP_AUTOPROXY_OPTIONS*,WINHTTP_PROXY_INFO*))
|
|
ali@14
|
93 |
GetProcAddress(module,"WinHttpGetProxyForUrl");
|
|
ali@14
|
94 |
WinHttp.Open=(HINTERNET (WINAPI *)(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD))
|
|
ali@14
|
95 |
GetProcAddress(module,"WinHttpOpen");
|
|
ali@14
|
96 |
WinHttp.OpenRequest=
|
|
ali@14
|
97 |
(HINTERNET (WINAPI *)(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD))
|
|
ali@14
|
98 |
GetProcAddress(module,"WinHttpOpenRequest");
|
|
ali@14
|
99 |
WinHttp.QueryAuthParams=(WINBOOL (WINAPI *)(HINTERNET,DWORD,LPVOID*))
|
|
ali@14
|
100 |
GetProcAddress(module,"WinHttpQueryAuthParams");
|
|
ali@14
|
101 |
WinHttp.QueryAuthSchemes=
|
|
ali@14
|
102 |
(WINBOOL (WINAPI *)(HINTERNET,LPDWORD,LPDWORD,LPDWORD))
|
|
ali@14
|
103 |
GetProcAddress(module,"WinHttpQueryAuthSchemes");
|
|
ali@14
|
104 |
WinHttp.QueryDataAvailable=(WINBOOL (WINAPI *)(HINTERNET,LPDWORD))
|
|
ali@14
|
105 |
GetProcAddress(module,"WinHttpQueryDataAvailable");
|
|
ali@14
|
106 |
WinHttp.QueryHeaders=
|
|
ali@14
|
107 |
(WINBOOL (WINAPI *)(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD))
|
|
ali@14
|
108 |
GetProcAddress(module,"WinHttpQueryHeaders");
|
|
ali@14
|
109 |
WinHttp.QueryOption=(WINBOOL (WINAPI *)(HINTERNET,DWORD,LPVOID,LPDWORD))
|
|
ali@14
|
110 |
GetProcAddress(module,"WinHttpQueryOption");
|
|
ali@14
|
111 |
WinHttp.ReadData=(WINBOOL (WINAPI *)(HINTERNET,LPVOID,DWORD,LPDWORD))
|
|
ali@14
|
112 |
GetProcAddress(module,"WinHttpReadData");
|
|
ali@14
|
113 |
WinHttp.ReceiveResponse=(WINBOOL (WINAPI *)(HINTERNET,LPVOID))
|
|
ali@14
|
114 |
GetProcAddress(module,"WinHttpReceiveResponse");
|
|
ali@14
|
115 |
WinHttp.SendRequest=
|
|
ali@14
|
116 |
(WINBOOL (WINAPI *)(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR))
|
|
ali@14
|
117 |
GetProcAddress(module,"WinHttpSendRequest");
|
|
ali@14
|
118 |
WinHttp.SetDefaultProxyConfiguration=
|
|
ali@14
|
119 |
(WINBOOL (WINAPI *)(WINHTTP_PROXY_INFO*))
|
|
ali@14
|
120 |
GetProcAddress(module,"WinHttpSetDefaultProxyConfiguration");
|
|
ali@14
|
121 |
WinHttp.SetCredentials=
|
|
ali@14
|
122 |
(WINBOOL (WINAPI *)(HINTERNET,DWORD,DWORD,LPCWSTR,LPCWSTR,LPVOID))
|
|
ali@14
|
123 |
GetProcAddress(module,"WinHttpSetCredentials");
|
|
ali@14
|
124 |
WinHttp.SetOption=(WINBOOL (WINAPI *)(HINTERNET,DWORD,LPVOID,DWORD))
|
|
ali@14
|
125 |
GetProcAddress(module,"WinHttpSetOption");
|
|
ali@14
|
126 |
WinHttp.SetStatusCallback=
|
|
ali@14
|
127 |
(WINHTTP_STATUS_CALLBACK (WINAPI *)(HINTERNET,WINHTTP_STATUS_CALLBACK,DWORD,DWORD_PTR))
|
|
ali@14
|
128 |
GetProcAddress(module,"WinHttpSetStatusCallback");
|
|
ali@14
|
129 |
WinHttp.SetTimeouts=(WINBOOL (WINAPI *)(HINTERNET,int,int,int,int))
|
|
ali@14
|
130 |
GetProcAddress(module,"WinHttpSetTimeouts");
|
|
ali@14
|
131 |
WinHttp.TimeFromSystemTime=(WINBOOL (WINAPI *)(CONST SYSTEMTIME *,LPWSTR))
|
|
ali@14
|
132 |
GetProcAddress(module,"WinHttpTimeFromSystemTime");
|
|
ali@14
|
133 |
WinHttp.TimeToSystemTime=(WINBOOL (WINAPI *)(LPCWSTR,SYSTEMTIME*))
|
|
ali@14
|
134 |
GetProcAddress(module,"WinHttpTimeToSystemTime");
|
|
ali@14
|
135 |
WinHttp.WriteData=(WINBOOL (WINAPI *)(HINTERNET,LPCVOID,DWORD,LPDWORD))
|
|
ali@14
|
136 |
GetProcAddress(module,"WinHttpWriteData");
|
|
ali@14
|
137 |
if (!WinHttp.CrackUrl || !WinHttp.Open || !WinHttp.Connect ||
|
|
ali@14
|
138 |
!WinHttp.OpenRequest || !WinHttp.SendRequest ||
|
|
ali@14
|
139 |
!WinHttp.ReceiveResponse || !WinHttp.QueryDataAvailable ||
|
|
ali@14
|
140 |
!WinHttp.ReadData || !WinHttp.CloseHandle)
|
|
ali@14
|
141 |
{
|
|
ali@14
|
142 |
FreeLibrary(module);
|
|
ali@14
|
143 |
WinHttp.Open=NULL;
|
|
ali@14
|
144 |
return -1;
|
|
ali@14
|
145 |
}
|
|
ali@14
|
146 |
return 0;
|
|
ali@14
|
147 |
}
|
|
ali@14
|
148 |
|
|
ali@14
|
149 |
/*
|
|
ali@14
|
150 |
* This will find ${PREFIX}/${file} if it exists, but it may also
|
|
ali@14
|
151 |
* find ${PREFIX}/.../${file} if ${PREFIX}/${file} does not exist.
|
|
ali@14
|
152 |
* This seems unlikely and won't do any harm should it occur.
|
|
ali@14
|
153 |
*/
|
|
ali@14
|
154 |
|
|
ali@14
|
155 |
gchar *find_prefixed_file(const char *file)
|
|
ali@14
|
156 |
{
|
|
ali@14
|
157 |
int i,len;
|
|
ali@14
|
158 |
const char *name;
|
|
ali@14
|
159 |
char *install_root;
|
|
ali@14
|
160 |
struct razor_set *set;
|
|
ali@14
|
161 |
struct razor_atomic *atomic;
|
|
ali@14
|
162 |
struct razor_package *package;
|
|
ali@14
|
163 |
struct razor_package_iterator *pi;
|
|
ali@14
|
164 |
struct razor_file_iterator *fi;
|
|
ali@14
|
165 |
gchar *retval=NULL;
|
|
ali@14
|
166 |
len=strlen(file);
|
|
ali@14
|
167 |
install_root=getenv("RAZOR_ROOT");
|
|
ali@14
|
168 |
if (!install_root)
|
|
ali@14
|
169 |
install_root="";
|
|
ali@14
|
170 |
atomic=razor_atomic_open("Query packages");
|
|
ali@14
|
171 |
set=razor_root_open_read_only(install_root,atomic);
|
|
ali@14
|
172 |
if (set)
|
|
ali@14
|
173 |
{
|
|
ali@14
|
174 |
pi=razor_package_iterator_create(set);
|
|
ali@14
|
175 |
while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST))
|
|
ali@14
|
176 |
{
|
|
ali@14
|
177 |
fi=razor_file_iterator_create(set,package,0);
|
|
ali@14
|
178 |
while (!retval && razor_file_iterator_next(fi,&name))
|
|
ali@14
|
179 |
{
|
|
ali@14
|
180 |
i=strlen(name)-len;
|
|
ali@14
|
181 |
if (i>0 && name[i-1]=='/' && !strcmp(name+i,file))
|
|
ali@14
|
182 |
{
|
|
ali@14
|
183 |
if (!retval || strlen(retval)>strlen(name))
|
|
ali@14
|
184 |
{
|
|
ali@14
|
185 |
g_free(retval);
|
|
ali@14
|
186 |
retval=g_strdup(name);
|
|
ali@14
|
187 |
}
|
|
ali@14
|
188 |
}
|
|
ali@14
|
189 |
}
|
|
ali@14
|
190 |
razor_file_iterator_destroy(fi);
|
|
ali@14
|
191 |
}
|
|
ali@14
|
192 |
razor_package_iterator_destroy(pi);
|
|
ali@14
|
193 |
razor_set_unref(set);
|
|
ali@14
|
194 |
}
|
|
ali@14
|
195 |
razor_atomic_destroy(atomic);
|
|
ali@14
|
196 |
return retval;
|
|
ali@14
|
197 |
}
|
|
ali@14
|
198 |
|
|
ali@14
|
199 |
static HCERTSTORE plover_p12_import(const char *file,const wchar_t *password)
|
|
ali@14
|
200 |
{
|
|
ali@14
|
201 |
GError *error=NULL;
|
|
ali@14
|
202 |
gchar *p12,*path,*s;
|
|
ali@14
|
203 |
gsize len;
|
|
ali@14
|
204 |
CRYPT_DATA_BLOB pfx;
|
|
ali@14
|
205 |
HCERTSTORE store;
|
|
ali@14
|
206 |
s=g_build_path("/","etc","pki",file,NULL);
|
|
ali@14
|
207 |
path=find_prefixed_file(s);
|
|
ali@14
|
208 |
if (!path)
|
|
ali@14
|
209 |
{
|
|
ali@14
|
210 |
g_printerr("%s: Not installed\n",s);
|
|
ali@14
|
211 |
g_free(s);
|
|
ali@14
|
212 |
return NULL;
|
|
ali@14
|
213 |
}
|
|
ali@14
|
214 |
g_free(s);
|
|
ali@14
|
215 |
if (!g_file_get_contents(path,&p12,&len,&error))
|
|
ali@14
|
216 |
{
|
|
ali@14
|
217 |
g_printerr("%s: %s\n",path,error->message);
|
|
ali@14
|
218 |
g_free(path);
|
|
ali@14
|
219 |
g_error_free(error);
|
|
ali@14
|
220 |
return NULL;
|
|
ali@14
|
221 |
}
|
|
ali@14
|
222 |
g_free(path);
|
|
ali@14
|
223 |
pfx.pbData=(BYTE *)p12;
|
|
ali@14
|
224 |
pfx.cbData=len;
|
|
ali@14
|
225 |
store=PFXImportCertStore(&pfx,password,PKCS12_NO_PERSIST_KEY);
|
|
ali@14
|
226 |
if (!store)
|
|
ali@14
|
227 |
g_printerr("PFXImportCertStore failed. Err: %lu\n",GetLastError());
|
|
ali@14
|
228 |
g_free(p12);
|
|
ali@14
|
229 |
return store;
|
|
ali@14
|
230 |
}
|
|
ali@14
|
231 |
|
|
ali@14
|
232 |
static const CERT_CONTEXT *plover_get_client_certificate(HCERTSTORE store)
|
|
ali@14
|
233 |
{
|
|
ali@14
|
234 |
const CERT_CONTEXT *iter,*cert;
|
|
ali@14
|
235 |
cert=NULL;
|
|
ali@14
|
236 |
iter=CertEnumCertificatesInStore(store,NULL);
|
|
ali@14
|
237 |
while(iter)
|
|
ali@14
|
238 |
{
|
|
ali@14
|
239 |
if (!cert)
|
|
ali@14
|
240 |
cert=CertDuplicateCertificateContext(iter);
|
|
ali@14
|
241 |
iter=CertEnumCertificatesInStore(store,iter);
|
|
ali@14
|
242 |
}
|
|
ali@14
|
243 |
return cert;
|
|
ali@14
|
244 |
}
|
|
ali@14
|
245 |
|
|
ali@14
|
246 |
void CALLBACK plover_status_callback(HINTERNET handle,DWORD_PTR context,
|
|
ali@14
|
247 |
DWORD status,LPVOID status_information,DWORD status_information_length)
|
|
ali@14
|
248 |
{
|
|
ali@14
|
249 |
g_printerr("CB status 0x%lX",status);
|
|
ali@14
|
250 |
if (status==WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
|
|
ali@14
|
251 |
g_printerr(", flag 0x%lX",*(DWORD *)status_information);
|
|
ali@14
|
252 |
g_printerr("\n");
|
|
ali@14
|
253 |
}
|
|
ali@14
|
254 |
|
|
ali@14
|
255 |
int fetch(HINTERNET session,HCERTSTORE store,const char *url)
|
|
ali@14
|
256 |
{
|
|
ali@14
|
257 |
URL_COMPONENTS components={0};
|
|
ali@14
|
258 |
HINTERNET connection,request;
|
|
ali@14
|
259 |
DWORD len,nb,options;
|
|
ali@14
|
260 |
char *buffer;
|
|
ali@14
|
261 |
wchar_t *ws;
|
|
ali@14
|
262 |
glong ws_len;
|
|
ali@14
|
263 |
gchar *hostname,*path;
|
|
ali@14
|
264 |
const CERT_CONTEXT *client_cert;
|
|
ali@14
|
265 |
components.dwStructSize=sizeof(components);
|
|
ali@14
|
266 |
components.dwSchemeLength=(DWORD)-1;
|
|
ali@14
|
267 |
components.dwHostNameLength=(DWORD)-1;
|
|
ali@14
|
268 |
components.dwUserNameLength=(DWORD)-1;
|
|
ali@14
|
269 |
components.dwPasswordLength=(DWORD)-1;
|
|
ali@14
|
270 |
components.dwUrlPathLength=(DWORD)-1;
|
|
ali@14
|
271 |
ws=g_utf8_to_utf16(url,-1,NULL,&ws_len,NULL);
|
|
ali@14
|
272 |
if (!ws || !WinHttp.CrackUrl(ws,ws_len,0,&components))
|
|
ali@14
|
273 |
{
|
|
ali@14
|
274 |
g_printerr("%s: Invalid or unsupported URL\n",url);
|
|
ali@14
|
275 |
return -1;
|
|
ali@14
|
276 |
}
|
|
ali@14
|
277 |
/* ICU_REJECT_USERPWD is not supported under Windows XP */
|
|
ali@14
|
278 |
if (components.dwUserNameLength || components.dwPasswordLength)
|
|
ali@14
|
279 |
{
|
|
ali@14
|
280 |
g_printerr("%s: Credentials not supported\n",url);
|
|
ali@14
|
281 |
return -1;
|
|
ali@14
|
282 |
}
|
|
ali@14
|
283 |
hostname=g_utf16_to_utf8(components.lpszHostName,
|
|
ali@14
|
284 |
components.dwHostNameLength,NULL,NULL,NULL);
|
|
ali@14
|
285 |
path=g_utf16_to_utf8(components.lpszUrlPath,components.dwUrlPathLength,NULL,
|
|
ali@14
|
286 |
NULL,NULL);
|
|
ali@14
|
287 |
g_free(ws);
|
|
ali@14
|
288 |
ws=g_utf8_to_utf16(hostname,-1,NULL,NULL,NULL);
|
|
ali@14
|
289 |
connection=WinHttp.Connect(session,ws,
|
|
ali@14
|
290 |
components.nPort?components.nPort:INTERNET_DEFAULT_PORT,0);
|
|
ali@14
|
291 |
g_free(ws);
|
|
ali@14
|
292 |
if (connection)
|
|
ali@14
|
293 |
{
|
|
ali@14
|
294 |
ws=g_utf8_to_utf16(path,-1,NULL,NULL,NULL);
|
|
ali@14
|
295 |
request=WinHttp.OpenRequest(connection,L"GET",ws,NULL,
|
|
ali@14
|
296 |
WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,
|
|
ali@14
|
297 |
components.nScheme==INTERNET_SCHEME_HTTPS?WINHTTP_FLAG_SECURE:0);
|
|
ali@14
|
298 |
g_free(ws);
|
|
ali@14
|
299 |
if (request)
|
|
ali@14
|
300 |
{
|
|
ali@14
|
301 |
if (debug)
|
|
ali@14
|
302 |
(void)WinHttp.SetStatusCallback(request,plover_status_callback,
|
|
ali@14
|
303 |
WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS,0);
|
|
ali@14
|
304 |
if (components.nScheme==INTERNET_SCHEME_HTTPS && WinHttp.SetOption)
|
|
ali@14
|
305 |
{
|
|
ali@14
|
306 |
options=SECURITY_FLAG_IGNORE_UNKNOWN_CA;
|
|
ali@14
|
307 |
(void)WinHttp.SetOption(request,WINHTTP_OPTION_SECURITY_FLAGS,
|
|
ali@14
|
308 |
&options,sizeof(options));
|
|
ali@14
|
309 |
client_cert=plover_get_client_certificate(store);
|
|
ali@14
|
310 |
if (client_cert)
|
|
ali@14
|
311 |
{
|
|
ali@14
|
312 |
if (!WinHttp.SetOption(request,
|
|
ali@14
|
313 |
WINHTTP_OPTION_CLIENT_CERT_CONTEXT,(void *)client_cert,
|
|
ali@14
|
314 |
sizeof(*client_cert)))
|
|
ali@14
|
315 |
g_printerr("Failed to set client certificate (%lu)\n",
|
|
ali@14
|
316 |
GetLastError());
|
|
ali@14
|
317 |
}
|
|
ali@14
|
318 |
else
|
|
ali@14
|
319 |
g_printerr("No client certificate found\n");
|
|
ali@14
|
320 |
}
|
|
ali@14
|
321 |
if (!WinHttp.SendRequest(request,WINHTTP_NO_ADDITIONAL_HEADERS,
|
|
ali@14
|
322 |
0,WINHTTP_NO_REQUEST_DATA,0,0,0))
|
|
ali@14
|
323 |
g_printerr("Failed to send request (%lu)\n",GetLastError());
|
|
ali@14
|
324 |
else if (!WinHttp.ReceiveResponse(request,NULL))
|
|
ali@14
|
325 |
g_printerr("Failed to receive response (%lu)\n",GetLastError());
|
|
ali@14
|
326 |
else
|
|
ali@14
|
327 |
{
|
|
ali@14
|
328 |
do
|
|
ali@14
|
329 |
{
|
|
ali@14
|
330 |
len=0;
|
|
ali@14
|
331 |
if (!WinHttp.QueryDataAvailable(request,&len))
|
|
ali@14
|
332 |
g_printerr(
|
|
ali@14
|
333 |
"Error %lu in WinHttpQueryDataAvailable.\n",
|
|
ali@14
|
334 |
(unsigned long)GetLastError());
|
|
ali@14
|
335 |
buffer=calloc(len+1,1);
|
|
ali@14
|
336 |
if (!buffer)
|
|
ali@14
|
337 |
break;
|
|
ali@14
|
338 |
else
|
|
ali@14
|
339 |
{
|
|
ali@14
|
340 |
if (!WinHttp.ReadData(request,(void *)buffer,len,&nb))
|
|
ali@14
|
341 |
g_printerr("Error %lu in WinHttpReadData.\n",
|
|
ali@14
|
342 |
(unsigned long)GetLastError());
|
|
ali@14
|
343 |
else
|
|
ali@14
|
344 |
printf("%s\n",buffer);
|
|
ali@14
|
345 |
free(buffer);
|
|
ali@14
|
346 |
}
|
|
ali@14
|
347 |
} while (len>0);
|
|
ali@14
|
348 |
}
|
|
ali@14
|
349 |
WinHttp.CloseHandle(request);
|
|
ali@14
|
350 |
}
|
|
ali@14
|
351 |
else
|
|
ali@14
|
352 |
g_printerr("Failed to open request for %s (%lu)\n",path,
|
|
ali@14
|
353 |
GetLastError());
|
|
ali@14
|
354 |
WinHttp.CloseHandle(connection);
|
|
ali@14
|
355 |
}
|
|
ali@14
|
356 |
else
|
|
ali@14
|
357 |
g_printerr("Failed to open connection to %s\n",hostname);
|
|
ali@14
|
358 |
g_free(hostname);
|
|
ali@14
|
359 |
g_free(path);
|
|
ali@14
|
360 |
return 0;
|
|
ali@14
|
361 |
}
|
|
ali@14
|
362 |
|
|
ali@14
|
363 |
int main(int argc,char **argv)
|
|
ali@14
|
364 |
{
|
|
ali@14
|
365 |
GError *error=NULL;
|
|
ali@14
|
366 |
GOptionContext *context;
|
|
ali@14
|
367 |
HCERTSTORE store;
|
|
ali@14
|
368 |
HINTERNET session;
|
|
ali@14
|
369 |
wchar_t *ws;
|
|
ali@14
|
370 |
context=g_option_context_new("URL - fetch a URL");
|
|
ali@14
|
371 |
g_option_context_add_main_entries(context,entries,NULL);
|
|
ali@14
|
372 |
if (!g_option_context_parse(context,&argc,&argv,&error))
|
|
ali@14
|
373 |
{
|
|
ali@14
|
374 |
g_printerr("Option parsing failed: %s\n",error->message);
|
|
ali@14
|
375 |
exit(1);
|
|
ali@14
|
376 |
}
|
|
ali@14
|
377 |
if (argc!=2)
|
|
ali@14
|
378 |
{
|
|
ali@14
|
379 |
g_printerr("%s\n",g_option_context_get_help(context,TRUE,NULL));
|
|
ali@14
|
380 |
exit(1);
|
|
ali@14
|
381 |
}
|
|
ali@14
|
382 |
if (plover_init_winhttp())
|
|
ali@14
|
383 |
{
|
|
ali@14
|
384 |
g_printerr("HTTP is not supported on this machine\n");
|
|
ali@14
|
385 |
exit(1);
|
|
ali@14
|
386 |
}
|
|
ali@14
|
387 |
store=plover_p12_import("system.p12",L"xyzzy-ylem");
|
|
ali@14
|
388 |
if (!store)
|
|
ali@14
|
389 |
exit(1);
|
|
ali@14
|
390 |
ws=g_utf8_to_utf16(PACKAGE_NAME "/" PACKAGE_VERSION,-1,NULL,NULL,NULL);
|
|
ali@14
|
391 |
session=WinHttp.Open(ws,WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
|
ali@14
|
392 |
WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);
|
|
ali@14
|
393 |
free(ws);
|
|
ali@14
|
394 |
if (!session)
|
|
ali@14
|
395 |
{
|
|
ali@14
|
396 |
g_printerr("Failed to open WinHttp session\n");
|
|
ali@14
|
397 |
exit(1);
|
|
ali@14
|
398 |
}
|
|
ali@14
|
399 |
if (fetch(session,store,argv[1]))
|
|
ali@14
|
400 |
exit(1);
|
|
ali@14
|
401 |
WinHttp.CloseHandle(session);
|
|
ali@14
|
402 |
CertCloseStore(store,CERT_CLOSE_STORE_FORCE_FLAG);
|
|
ali@14
|
403 |
exit(0);
|
|
ali@14
|
404 |
}
|
|
ali@14
|
405 |
#else /* !HAVE_WINHTTP_H */
|
|
ali@14
|
406 |
main()
|
|
ali@14
|
407 |
{
|
|
ali@14
|
408 |
g_printerr("HTTP is not supported on this machine\n");
|
|
ali@14
|
409 |
exit(1);
|
|
ali@14
|
410 |
}
|
|
ali@14
|
411 |
#endif /* HAVE_WINHTTP_H */
|