/[winpt]/trunk/Src/wptGPGUtil.cpp
ViewVC logotype

Annotation of /trunk/Src/wptGPGUtil.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 175 - (hide annotations)
Tue Feb 7 08:58:04 2006 UTC (19 years ago) by twoaday
File size: 19059 byte(s)
2006-02-04  Timo Schulz  <ts@g10code.de>
                                                                                                                            
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Check for
        at least one ultimately trusted key.
        * wptKeyManager.cpp (km_refresh_key_from_keyserver):
        Only check inet connection if we refresh all keys.
        * wptGPGUtil.cpp (gpg_extract_keys): New.
        * wptClipEncryptDlg.cpp (clip_encrypt_dlg_proc): Use textmode.
        * wptClipSignEncDlg.cpp (clip_signenc_dlg_proc): Likewise.
        * wptClipSignDlg.cpp (get_selected_key): New.
        (one_key_proc): Use it here.
        (count_useable_seckeys): New.
        * wptSigTreeDlg.cpp (sigtree_dlg_proc): New.
        * wptKeyEditDlgs.cpp (diff_time): Removed.
        (w32_mktime): New.
        (keyedit_addsubkey_dlg_proc): Use it here.
                                                                                                                            
2006-02-02  Timo Schulz  <ts@g10code.de>
                                                                                                                            
        * wptW32API.cpp (get_temp_name): New.
        * wptKeyserver.cpp (ldap_recvkey): Use it here.
        * wptKeyPropsDlg.cpp (get_photo_tmpname): Likewise.
        * wptGPGUtil.cpp (create_tempfile): Likewise.
        * wptImportList.cpp (implist_load): Likewise.
        * wptKeyCache.cpp (parse_attr_data): Likewise.
        (w32_tempfile): Removed.
        * wptGPGME.cpp (check_ultimate_trusted_key): New.
                                                                                                                            

1 twoaday 121 /* wptGPGUtil.cpp - GPG util functions
2 twoaday 133 * Copyright (C) 2005, 2006 Timo Schulz
3 werner 36 * Copyright (C) 2005 g10 Code GmbH
4     *
5     * This file is part of WinPT.
6     *
7     * WinPT is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * WinPT is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with WinPT; if not, write to the Free Software Foundation,
19     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20     */
21 twoaday 121
22 werner 36 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24     #endif
25    
26     #include <windows.h>
27     #include <sys/stat.h>
28    
29 twoaday 121 #include "gpgme.h"
30     #include "wptTypes.h"
31 twoaday 73 #include "wptErrors.h"
32 twoaday 175 #include "wptW32API.h"
33 werner 36
34 twoaday 175
35 werner 36 #define NROFHEXDIGITS 2
36     /* Convert two hexadecimal digits from STR to the value they
37     represent. Returns -1 if one of the characters is not a
38     hexadecimal digit. */
39     static int
40     hextobyte (const unsigned char *str)
41     {
42     int val = 0;
43     int i;
44    
45     for (i = 0; i < NROFHEXDIGITS; i++) {
46     if (*str >= '0' && *str <= '9')
47     val += *str - '0';
48     else if (*str >= 'A' && *str <= 'F')
49     val += 10 + *str - 'A';
50     else if (*str >= 'a' && *str <= 'f')
51     val += 10 + *str - 'a';
52     else
53     return -1;
54     if (i < NROFHEXDIGITS - 1)
55     val *= 16;
56     str++;
57     }
58     return val;
59     }
60    
61     /* Decode the C formatted string @src and store the result in the
62     buffer @destp which is @len bytes long. If @len is zero, then a
63     large enough buffer is allocated with malloc and @destp is set to
64     the result. Currently, @len is only used to specify if allocation
65     is desired or not, the caller is expected to make sure that @destp
66     is large enough if @len is not zero. */
67     gpgme_error_t
68     gpg_decode_c_string (const char *src, char **destp, size_t len)
69     {
70     char *dest;
71    
72     /* Set up the destination buffer. */
73     if (len) {
74     if (len < strlen (src) + 1)
75     return gpg_error (GPG_ERR_TOO_SHORT);
76     dest = *destp;
77     }
78     else {
79     /* The converted string will never be larger than the original string. */
80     dest = (char*)malloc (strlen (src) + 1);
81     if (!dest)
82     return gpg_error (GPG_ERR_ENOMEM);
83     *destp = dest;
84     }
85    
86     /* Convert the string. */
87     while (*src) {
88     if (*src != '\\') {
89     *(dest++) = *(src++);
90     continue;
91     }
92    
93     switch (src[1]) {
94     #define DECODE_ONE(match,result) \
95     case match: \
96     src += 2; \
97     *(dest++) = result; \
98     break;
99    
100     DECODE_ONE ('\'', '\'');
101     DECODE_ONE ('\"', '\"');
102     DECODE_ONE ('\?', '\?');
103     DECODE_ONE ('\\', '\\');
104     DECODE_ONE ('a', '\a');
105     DECODE_ONE ('b', '\b');
106     DECODE_ONE ('f', '\f');
107     DECODE_ONE ('n', '\n');
108     DECODE_ONE ('r', '\r');
109     DECODE_ONE ('t', '\t');
110     DECODE_ONE ('v', '\v');
111    
112     case 'x': {
113     int val = hextobyte ((unsigned char*)&src[2]);
114     if (val == -1) { /* Should not happen. */
115     *(dest++) = *(src++);
116     *(dest++) = *(src++);
117     if (*src)
118     *(dest++) = *(src++);
119     if (*src)
120     *(dest++) = *(src++);
121     }
122     else {
123     if (!val) {
124     /* A binary zero is not representable in a C string. */
125     *(dest++) = '\\';
126     *(dest++) = '0';
127     }
128     else
129     *((unsigned char *) dest++) = val;
130     src += 4;
131     }
132     }
133    
134     default: /* Should not happen. */
135     {
136     *(dest++) = *(src++);
137     *(dest++) = *(src++);
138     }
139     }
140     }
141     *(dest++) = 0;
142     return 0;
143     }
144    
145     /* Replace %foo% entries with its real values.
146     Return value: expanded path or NULL on error. */
147     static char *
148     expand_path (const char *path)
149     {
150     DWORD len;
151     char *p;
152    
153     len = ExpandEnvironmentStrings (path, NULL, 0);
154     if (!len)
155     return NULL;
156     len += 1;
157     p = (char*)calloc (1, len+1);
158     if (!p)
159 twoaday 121 BUG (NULL);
160 werner 36 len = ExpandEnvironmentStrings (path, p, len);
161     if (!len) {
162     free (p);
163     return NULL;
164     }
165     return p;
166     }
167    
168    
169     /* Read a string from the W32 registry. The directory is given
170     in @dir and the name of the value in @name, */
171     static char *
172     read_w32_registry (HKEY root_key, const char *dir, const char *name)
173     {
174     HKEY key_handle;
175     DWORD n1, nbytes;
176     DWORD type;
177     char *result = NULL;
178    
179     if (RegOpenKeyEx (root_key, dir, 0, KEY_READ, &key_handle))
180     return NULL; /* no need for a RegClose, so return direct */
181    
182     nbytes = 1;
183     if (RegQueryValueEx (key_handle, name, 0, NULL, NULL, &nbytes))
184     goto leave;
185     result = (char*)calloc (1, (n1=nbytes+1));
186     if (!result)
187 twoaday 121 BUG (NULL);
188 werner 36 if (RegQueryValueEx (key_handle, name, 0, &type, (BYTE*)result, &n1)) {
189     free (result);
190     result = NULL;
191     goto leave;
192     }
193     if (type == REG_EXPAND_SZ && strchr (result, '%')) {
194     char *p = expand_path (result);
195     free (result);
196     result = p;
197     }
198    
199     leave:
200     RegCloseKey (key_handle);
201     return result;
202     }
203    
204 twoaday 133 static char*
205     read_gpg_program (void)
206     {
207     return read_w32_registry (HKEY_CURRENT_USER,
208     "Software\\GNU\\GnuPG", "gpgProgram");
209     }
210 werner 36
211 twoaday 133
212 werner 36 /* Create a temp file based on the name of @name.
213     Return value: handle to the file in case of success. */
214     static HANDLE
215     create_tmpfile (const char *name)
216     {
217     HANDLE out;
218 twoaday 121 SECURITY_ATTRIBUTES sec_attr;
219 werner 36 char tmp[300];
220    
221 twoaday 121 memset (&sec_attr, 0, sizeof sec_attr);
222     sec_attr.bInheritHandle = TRUE;
223     sec_attr.lpSecurityDescriptor = NULL;
224     sec_attr.nLength = sizeof sec_attr;
225 werner 36
226 twoaday 175 get_temp_name (tmp, DIM (tmp)-1, name);
227 werner 36 out = CreateFile (tmp, GENERIC_READ|GENERIC_WRITE,
228 twoaday 121 FILE_SHARE_WRITE, &sec_attr,
229 werner 36 OPEN_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
230 twoaday 121 if (out == INVALID_HANDLE_VALUE)
231     log_debug ("create_tmpfile: CreateFile failed ec=%d\r\n",
232     (int)GetLastError ());
233 werner 36 return out;
234     }
235    
236    
237     /* Create a pipe with a readable remote end and
238     write the data from @dat to the local end.
239     Return value: read handle on success. */
240     static HANDLE
241     create_in_pipe (const char *dat)
242     {
243     HANDLE r, w;
244     SECURITY_ATTRIBUTES sec_attr;
245     DWORD n;
246    
247     memset (&sec_attr, 0, sizeof sec_attr);
248     sec_attr.bInheritHandle = TRUE;
249     sec_attr.nLength = sizeof sec_attr;
250    
251 twoaday 121 if (!CreatePipe (&r, &w, &sec_attr, 4096)) {
252     log_debug ("create_in_pipe: CreatePipeFailed ec=%d\r\n",
253     (int)GetLastError ());
254 werner 36 return NULL;
255 twoaday 121 }
256 werner 36
257     WriteFile (w, dat, strlen (dat), &n, NULL);
258     CloseHandle (w);
259    
260     return r;
261     }
262    
263    
264     /* Map the contents of the file handle @out to
265     a buffer and return it. */
266     static char*
267 twoaday 133 map_tmpfile (HANDLE out, DWORD *nread)
268 werner 36 {
269     DWORD n;
270     char *p;
271    
272     FlushFileBuffers (out);
273     SetFilePointer (out, 0, NULL, FILE_BEGIN);
274     n = GetFileSize (out, NULL);
275     p = (char*)calloc (1, n+1);
276     if (!p)
277 twoaday 121 BUG (NULL);
278 werner 36 ReadFile (out, p, n, &n, NULL);
279     p[n] = 0;
280 twoaday 133 if (nread)
281     *nread = n;
282 werner 36 return p;
283     }
284    
285    
286     /* Create a process from the command line in @cmd.
287     If @out is != NULL, the output of the process will
288     be redirected to @out. If @in is != NULL the input
289     will be read from @in.
290     Return value: 0 on success. */
291     static int
292 twoaday 133 create_process (const char *cmd, HANDLE in, HANDLE out, HANDLE err)
293 werner 36 {
294     STARTUPINFO si;
295     PROCESS_INFORMATION pi;
296    
297     memset (&si, 0, sizeof (si));
298     si.cb = sizeof si;
299 twoaday 133 if (in || out || err)
300 twoaday 121 si.dwFlags = STARTF_USESTDHANDLES;
301 werner 36 if (out)
302     si.hStdOutput = out;
303     if (in)
304     si.hStdInput = in;
305 twoaday 133 if (err)
306     si.hStdError = err;
307 twoaday 121 si.dwFlags |= STARTF_USESHOWWINDOW;
308 werner 36 si.wShowWindow = SW_HIDE;
309     if (!CreateProcess (NULL, (char*)cmd, NULL, NULL, TRUE, 0,
310 twoaday 121 NULL, NULL, &si, &pi)) {
311     log_debug ("create_process: CreateProcess failed ec=%d\r\n",
312 twoaday 73 (int)GetLastError ());
313 werner 36 return -1;
314 twoaday 73 }
315 werner 36 WaitForSingleObject (pi.hProcess, INFINITE);
316     CloseHandle (pi.hProcess);
317     return 0;
318     }
319    
320    
321     /* Export a GPG secret key given by @keyid into the file @outfile.
322     Return value: 0 on success. */
323     gpgme_error_t
324     gpg_export_seckey (const char *keyid, const char *outfile)
325     {
326     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
327     struct stat st;
328     char *p;
329     char *cmd;
330    
331 twoaday 133 p = read_gpg_program ();
332 werner 36 if (!p)
333     return gpg_error (GPG_ERR_INV_ARG);
334     cmd = (char*)calloc (1, strlen (p) + strlen (keyid)
335     + strlen (outfile) + 64 + 2);
336     if (!cmd)
337 twoaday 121 BUG (NULL);
338 werner 36 sprintf (cmd, "%s --yes --output \"%s\" --export-secret-key %s",
339     p, outfile, keyid);
340 twoaday 133 if (create_process (cmd, NULL, NULL, NULL))
341 werner 36 err = gpg_error (GPG_ERR_INTERNAL);
342    
343     if (stat (outfile, &st) == -1 || st.st_size == 0)
344     err = gpg_error (GPG_ERR_NO_DATA);
345    
346     free (p);
347     free (cmd);
348     return err;
349     }
350    
351    
352 twoaday 121 /* If @export is 1, export the ownertrust data to the
353     buffer @data. Otherwise import the ownertrust data from @data.
354 werner 36 Return value: 0 on success. */
355     gpgme_error_t
356 twoaday 121 gpg_manage_ownertrust (char **data, int do_export)
357 werner 36 {
358     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
359     HANDLE out = NULL, in = NULL;
360     char *p;
361     char *cmd;
362    
363 twoaday 133 p = read_gpg_program ();
364 werner 36 if (!p)
365     return gpg_error (GPG_ERR_INV_ARG);
366    
367     cmd = (char*)calloc (1, strlen (p) + 64 + 1);
368     if (!cmd)
369 twoaday 121 BUG (NULL);
370 werner 36 sprintf (cmd, "%s %s", p,
371 twoaday 121 do_export? "--export-ownertrust" : "--import-ownertrust");
372 werner 36
373 twoaday 121 if (do_export)
374 werner 36 out = create_tmpfile ("gpg_ot_out");
375     else {
376     DWORD nw;
377     in = create_tmpfile ("gpg_ot_in");
378     WriteFile (in, *data, strlen (*data), &nw, NULL);
379     FlushFileBuffers (in);
380     /* XXX: need a rewind? */
381     }
382 twoaday 133 if (create_process (cmd, in, out, NULL))
383 werner 36 err = gpg_error (GPG_ERR_INTERNAL);
384    
385     free (p);
386     free (cmd);
387    
388     if (in)
389     CloseHandle (in);
390     if (out) {
391 twoaday 133 *data = map_tmpfile (out, NULL);
392 werner 36 CloseHandle (out);
393     }
394 twoaday 129
395 werner 36 return err;
396     }
397    
398    
399     /* Call gpg --rebuild-keydb-caches to speed up signature listings. */
400     gpgme_error_t
401     gpg_rebuild_cache (char **r_inf)
402     {
403     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
404     HANDLE out = NULL;
405     char *p;
406     char *cmd;
407    
408 twoaday 133 p = read_gpg_program ();
409 werner 36 if (!p)
410     return gpg_error (GPG_ERR_INV_ARG);
411     cmd = (char*)calloc (1, strlen (p) + 64);
412     if (!cmd)
413 twoaday 121 BUG (NULL);
414 werner 36 sprintf (cmd, "%s --logger-fd=1 --rebuild-keydb-caches", p);
415    
416     if (r_inf)
417     out = create_tmpfile ("gpg_rebuild_cache");
418    
419 twoaday 133 if (create_process (cmd, NULL, out, NULL))
420 werner 36 err = gpg_error (GPG_ERR_INTERNAL);
421    
422     if (r_inf)
423 twoaday 133 *r_inf = map_tmpfile (out, NULL);
424 werner 36 if (out)
425     CloseHandle (out);
426     free (p);
427     free (cmd);
428     return 0;
429     }
430    
431    
432     /* Call gpg --version to retrieve the 'about' information. */
433     gpgme_error_t
434     gpg_get_version (char **r_inf)
435     {
436     gpgme_error_t err= gpg_error (GPG_ERR_NO_ERROR);
437     HANDLE out;
438     char *p, *cmd;
439    
440 twoaday 133 p = read_gpg_program ();
441 werner 36 if (!p)
442     return gpg_error (GPG_ERR_INV_ARG);
443     cmd = (char*)calloc (1, strlen (p) + 32);
444     if (!cmd)
445 twoaday 121 BUG (NULL);
446 werner 36 sprintf (cmd, "%s --version", p);
447    
448     out = create_tmpfile ("gpg_out");
449 twoaday 133 if (create_process (cmd, NULL, out, NULL))
450 werner 36 err = gpg_error (GPG_ERR_INTERNAL);
451    
452     free (p);
453     free (cmd);
454    
455 twoaday 133 *r_inf = map_tmpfile (out, NULL);
456 werner 36 CloseHandle (out);
457     return err;
458     }
459    
460    
461     /* Return the colon file output of the given file @fname in @r_out.
462     Return value: 0 on success. */
463     gpgme_error_t
464     gpg_import_key_list (const char *fname, char **r_out)
465     {
466     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
467     char *cmd, *p;
468     HANDLE out;
469    
470 twoaday 133 p = read_gpg_program ();
471 werner 36 if (!p)
472     return gpg_error (GPG_ERR_INV_ARG);
473    
474     cmd = (char*)calloc (1, strlen (p) + strlen (fname) + 2+2 + 64);
475     if (!cmd)
476 twoaday 121 BUG (NULL);
477 werner 36 sprintf (cmd, "%s --fixed-list-mode --with-colons \"%s\"", p, fname);
478    
479     out = create_tmpfile ("gpg_keys");
480 twoaday 133 if (create_process (cmd, NULL, out, NULL))
481 werner 36 err = gpg_error (GPG_ERR_INTERNAL);
482    
483     free (p);
484     free (cmd);
485    
486 twoaday 133 *r_out = map_tmpfile (out, NULL);
487 werner 36 CloseHandle (out);
488     return err;
489     }
490    
491 twoaday 129
492 werner 36 char*
493 twoaday 129 generate_revoke_input (int code, const char *cmt, const char *pass)
494 werner 36 {
495     const char *fmt;
496     char *p;
497     size_t n;
498    
499     fmt = "Y\n" /* gen_revoke.okay */
500     "%d\n" /* ask_revocation_reason.code */
501     "%s\n" /* ask_revocation_reason.text */
502     "%s" /* text != NULL '\n' otherwise '' */
503     "Y\n" /* ask_revocation_reason.okay */
504     "%s\n"; /* passphrase.enter. */
505     n = strlen (fmt) + 32;
506     if (pass)
507     n += strlen (pass) + 1;
508     if (cmt)
509     n += strlen (cmt) + 1;
510     p = (char*)calloc (1, n+1);
511     if (!p)
512 twoaday 121 BUG (NULL);
513 werner 36 sprintf (p, fmt, code, cmt? cmt : "", cmt? "\n" : "", pass? pass : "");
514     return p;
515     }
516    
517    
518     /* Generate a revocation certificate for the key with the keyid @keyid.
519     @inp_data contains all needed data to answer the questions of the
520     command handler. Each separate with a '\n'.
521     @r_revcert contains the revocation cert on success.
522     Return value: 0 on success. */
523     gpgme_error_t
524 twoaday 129 gpg_revoke_cert (const char *inp_data, const char *keyid, char **r_revcert)
525 werner 36 {
526     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
527     char *rcrt;
528     char *cmd, *p;
529     HANDLE in, out;
530    
531 twoaday 133 p = read_gpg_program ();
532 werner 36 if (!p)
533     return gpg_error (GPG_ERR_INV_ARG);
534    
535     cmd = (char*)calloc (1, strlen (p) + strlen (keyid)+1 + 128);
536     if (!cmd)
537 twoaday 121 BUG (NULL);
538 werner 36 sprintf (cmd, "%s --pgp7 --command-fd=0 --status-fd=2 --gen-revoke %s",
539     p, keyid);
540    
541     in = create_in_pipe (inp_data);
542     out = create_tmpfile ("gpg_revcert");
543 twoaday 133 if (create_process (cmd, in, out, NULL)) {
544 werner 36 *r_revcert = NULL;
545     err = gpg_error (GPG_ERR_INTERNAL);
546     }
547     else {
548 twoaday 133 rcrt = map_tmpfile (out, NULL);
549 werner 36 *r_revcert = rcrt;
550 twoaday 129 if (rcrt && strlen (rcrt) == 0)
551     err = gpg_error (GPG_ERR_BAD_PASSPHRASE);
552 werner 36 }
553    
554     free (p);
555     free (cmd);
556    
557     CloseHandle (in);
558     CloseHandle (out);
559     return err;
560     }
561    
562    
563 twoaday 133 /* Return the raw photo-id data combined with the status-fd
564     entry in @r_data. If @keyid is set, only the data for this
565     key will be returned.
566     Return value: 0 on success. */
567     gpgme_error_t
568     gpg_get_photoid_data (const char *keyid, char **r_status_data,
569     unsigned char **r_data, unsigned long *ndata)
570     {
571     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
572     HANDLE herr, hdat;
573     char *p, *cmd;
574     DWORD n;
575    
576 twoaday 164 if (ndata)
577     *ndata = 0;
578 twoaday 133 p = read_gpg_program ();
579     if (!p)
580     return gpg_error (GPG_ERR_INV_ARG);
581     n = strlen (p) + 128;
582     if (keyid)
583     n += strlen (keyid) + 1;
584     cmd = (char*)calloc (1, n+1);
585     if (!cmd)
586     BUG (NULL);
587     hdat = create_tmpfile ("gpg_uat_data");
588     herr = create_tmpfile ("gpg_uat_status");
589     /* XXX: add --list-options show-unsuable-uid to display
590     revoked attribute IDs */
591     sprintf (cmd, "%s --attribute-fd=%d --status-fd=2 --list-keys %s",
592     p, (int)hdat, keyid? keyid : "");
593     if (create_process (cmd, NULL, NULL, herr))
594     err = gpg_error (GPG_ERR_INTERNAL);
595    
596     free (p);
597     free (cmd);
598    
599     *r_data = (BYTE*)map_tmpfile (hdat, ndata);
600     *r_status_data = map_tmpfile (herr, NULL);
601     CloseHandle (hdat);
602     CloseHandle (herr);
603    
604     return err;
605     }
606    
607    
608 twoaday 175 /* Extract one or more keys from the key file @keyfile.
609     The keys to extract are give in @keys and the size of it is @nkeys.
610     @new_keyfile is a file with the extract keys.
611     Return value: 0 on success. */
612     gpgme_error_t
613     gpg_extract_keys (const char *keyfile, const char **keys, DWORD nkeys,
614     char **new_keyfile)
615     {
616     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
617     const char *fmt;
618     char *p, *cmd;
619     char tmpnam[MAX_PATH], tmpdir[MAX_PATH];
620     int i, n;
621    
622     /* copy key file to temp dir. */
623     GetTempPath (MAX_PATH-1, tmpdir);
624     get_temp_name (tmpnam, MAX_PATH-1, NULL);
625     CopyFile (keyfile, tmpnam, FALSE);
626    
627     /* create temp file for output. */
628     *new_keyfile = new char[MAX_PATH];
629     if (!*new_keyfile)
630     BUG (NULL);
631     get_temp_name (*new_keyfile, MAX_PATH-1, "sel_keys");
632    
633     p = read_gpg_program ();
634     if (!p)
635     return gpg_error (GPG_ERR_INV_ARG);
636    
637     /* Use the temp key file as a keyring and export the selected
638     keys from it. */
639     fmt = "%s --yes --output %s --no-options --homedir %s --keyring %s --export ";
640     n = strlen (fmt) + strlen (p)+1 + strlen (tmpdir)+1 + strlen (tmpnam) + 1;
641     n += strlen (*new_keyfile)+1;
642     for (i=0; i < (int)nkeys; i++)
643     n += strlen (keys[i])+1+2;
644     cmd = (char*)calloc (1, n+1);
645     sprintf (cmd, fmt, p, *new_keyfile, tmpdir, tmpnam);
646     for (i=0; i < (int)nkeys; i++) {
647     strcat (cmd, keys[i]);
648     strcat (cmd, " " );
649     }
650    
651     if (create_process (cmd, NULL, NULL, NULL))
652     err = gpgme_error (GPG_ERR_INTERNAL);
653    
654     DeleteFile (tmpnam);
655     safe_free (cmd);
656     safe_free (p);
657     return err;
658     }
659    
660    
661 werner 36 /* Return the validity of the user attribute, informerly known
662     as photo-ID. If no uat was found, return 0 for unknown. */
663     gpgme_error_t
664     get_uat_validity (const char *keyid, gpgme_validity_t *r_valid)
665     {
666     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
667     HANDLE out;
668     char *p, *cmd;
669     char *uat;
670    
671     *r_valid = GPGME_VALIDITY_UNKNOWN;
672 twoaday 133 p = read_gpg_program ();
673 werner 36 if (!p)
674     return gpg_error (GPG_ERR_INV_ARG);
675    
676     cmd = (char*)calloc (1, strlen (p) + strlen (keyid)+1 + 128);
677     if (!cmd)
678 twoaday 121 BUG (NULL);
679 werner 36 sprintf (cmd, "%s --with-colons --fixed-list-mode --list-keys \"%s\"",
680     p, keyid);
681    
682     out = create_tmpfile ("gpg_keys");
683 twoaday 133 if (create_process (cmd, NULL, out, NULL))
684 werner 36 err = gpg_error (GPG_ERR_INTERNAL);
685    
686 twoaday 175 safe_free (p);
687     safe_free (cmd);
688 werner 36
689 twoaday 133 p = map_tmpfile (out, NULL);
690 werner 36 if ((uat = strstr (p, "uat:"))) {
691     switch (*(uat+4)) {
692     case 'm': *r_valid = GPGME_VALIDITY_MARGINAL; break;
693     case 'f':
694     case 'u': *r_valid = GPGME_VALIDITY_FULL; break;
695     default: *r_valid = GPGME_VALIDITY_UNDEFINED; break;
696     }
697     }
698    
699     free (p);
700     CloseHandle (out);
701     return err;
702     }
703    
704    
705     #if 0
706     /* Extract all recipients from the file @file.
707     Return value: 0 on success. */
708     static int
709     do_get_recipients (const char *file, gpgme_recipient_t *r_list)
710     {
711     gpgme_recipient_t l;
712     PACKET *pkt;
713     gpg_iobuf_t inp = NULL;
714     armor_filter_context_t afx;
715     int rc = 0, quit=0;
716    
717     if (!file || !r_list) {
718     log_debug ("do_list_packets: !r_list || !file");
719     return -1;
720     }
721    
722     *r_list=NULL;
723     inp = gpg_iobuf_open (file);
724     if (!inp)
725     return WPTERR_FILE_OPEN;
726     gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */
727     if (gpg_use_armor_filter (inp)) {
728     memset (&afx, 0, sizeof (afx));
729     gpg_iobuf_push_filter (inp, gpg_armor_filter, &afx);
730     }
731     pkt = (PACKET *)calloc(1, sizeof *pkt);
732     gpg_init_packet (pkt);
733     while (!quit && (rc = gpg_parse_packet (inp, pkt)) != -1) {
734     switch (pkt->pkttype) {
735     case PKT_PUBKEY_ENC:
736     {PKT_pubkey_enc *enc = pkt->pkt.pubkey_enc;
737     if (!enc)
738     break;
739     l = calloc (1, sizeof *l);
740     l->keyid = calloc (1, 16+1);
741     _snprintf (l->keyid, 16, "%08lX%08lX", enc->keyid[0], enc->keyid[1]);
742     l->pubkey_algo = enc->pubkey_algo;
743     l->status = 0;
744     l->next = (*r_list);
745     *r_list = l;
746     break;}
747    
748     case PKT_ENCRYPTED:
749     case PKT_ENCRYPTED_MDC:
750     case PKT_COMPRESSED:
751     case PKT_PUBLIC_KEY:
752     case PKT_SECRET_KEY:
753     quit = 1;
754     break;
755     }
756     gpg_free_packet (pkt);
757     gpg_init_packet (pkt);
758     }
759     gpg_iobuf_close (inp);
760     safe_free (pkt);
761     return 0;
762     }
763     #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26