app-manager/fetch.c
author J. Ali Harlow <ali@juiblex.co.uk>
Tue Jun 14 12:39:53 2016 +0100 (2016-06-14)
changeset 41 bd50a4b7ab68
parent 14 29d8bb64056c
permissions -rw-r--r--
First tentative step in using razor_file_set_vtable
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@24
   161
    struct razor_error *error=NULL;
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@24
   170
    set=razor_root_open_read_only(install_root,&error);
ali@14
   171
    if (set)
ali@14
   172
    {
ali@14
   173
	pi=razor_package_iterator_create(set);
ali@14
   174
	while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST))
ali@14
   175
	{
ali@14
   176
	    fi=razor_file_iterator_create(set,package,0);
ali@14
   177
	    while (!retval && razor_file_iterator_next(fi,&name))
ali@14
   178
	    {
ali@14
   179
		i=strlen(name)-len;
ali@14
   180
		if (i>0 && name[i-1]=='/' && !strcmp(name+i,file))
ali@14
   181
		{
ali@14
   182
		    if (!retval || strlen(retval)>strlen(name))
ali@14
   183
		    {
ali@14
   184
			g_free(retval);
ali@14
   185
			retval=g_strdup(name);
ali@14
   186
		    }
ali@14
   187
		}
ali@14
   188
	    }
ali@14
   189
	    razor_file_iterator_destroy(fi);
ali@14
   190
	}
ali@14
   191
	razor_package_iterator_destroy(pi);
ali@14
   192
	razor_set_unref(set);
ali@14
   193
    }
ali@24
   194
    if (error)
ali@24
   195
	razor_error_free(error);
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 */