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

Annotation of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Thu Apr 14 12:56:25 2005 UTC (19 years, 10 months ago) by twoaday
File size: 25431 byte(s)
2005-04-11  Timo Schulz  <twoaday@freakmail.de>
 
        * wptClipSignEncDlg.cpp (clip_signenc_dlg_proc): Reset
        'enable' flag always at the begin.
        * wptClipDecryptDlg.cpp (clip_decrypt_dlg): Show correct
        key trust. Noted by a friendly user.
        * wptListView.cpp (listview_add_item_pos): New.
        * wptKeyEditDlgs.cpp (get_subkey_fingerprint): Due to
        the fact that GPG does not return the fingerprint of
        the generated subkey any longer, we need to get it manually.
        Thanks to Maxime Brandt.
        (keyedit_addsubkey_dlg_proc): If key size too large, ask
        if this was a mistake.
        (keyedit_add_subkey): Use it here.
        (do_add_new_subkey): Fix list contrl insertion.
        * wptTypes.h (DEFAULT_KEYSIZE): Define new default keysize constant.


1 twoaday 2 /* wptGPG.cpp - GnuPG configuration
2     * Copyright (C) 2001-2004 Timo Schulz
3     *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     * General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #include <string.h>
22     #include <stdio.h>
23     #include <windows.h>
24     #include <shlobj.h>
25     #include <ctype.h>
26     #include <io.h>
27    
28     #include "wptGPG.h"
29     #include "wptGPGCmds.h"
30     #include "wptGPGOptSkel.h"
31     #include "wptTypes.h"
32     #include "wptNLS.h"
33     #include "wptRegistry.h"
34     #include "wptErrors.h"
35     #include "wptW32API.h"
36    
37     #define GPG_CONF "gpg.conf"
38    
39     struct gpg_watcher_s {
40     FILETIME last_access;
41     FILETIME access;
42     char * object;
43     int modified;
44     };
45    
46     /* XXX need to watch for gpg.conf due to the fact keyring entries could be changed */
47     static const char * gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};
48     static gpg_watcher_s gpg_table[3];
49     static int gpg_table_count = DIM (gpg_table);
50    
51     int idea_available = 0;
52    
53     static int check_keyring (char ** r_path);
54    
55    
56     static char*
57     multi_gnupg_path (void)
58     {
59     static char buf[256+64];
60     BOOL ec;
61    
62 twoaday 12 /* MSDN: buf must be at least MAX_PATH=256 bytes */
63 twoaday 2 memset (buf, 0, sizeof (buf));
64     ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);
65     if (ec != 1)
66     return NULL;
67     strcat (buf, "\\gnupg");
68     if (access (buf, 00))
69     return NULL;
70     return buf;
71     }
72    
73     /*
74     * Return the full path of the GnuPG application. First the registry is scanned
75     * for the entry 'HomeDir'. If it wasn't set, the default dir C:\GNUPG is used.
76     */
77     char*
78     get_gnupg_path (void)
79     {
80     char *p = NULL, *path = NULL;
81    
82     p = get_reg_entry_gpg ("HomeDir");
83     if (p) {
84     path = m_strdup (p);
85     free_if_alloc (p);
86     return path;
87     }
88     else {
89     p = multi_gnupg_path ();
90     if (p)
91     return m_strdup (p);
92     }
93     return m_strdup ("c:\\gnupg");
94     } /* get_gnupg_path */
95    
96    
97     char*
98     get_gnupg_cfgfile (void)
99     {
100     char *p = NULL, *optfile = NULL, *path = NULL;
101     size_t nlen = 0;
102    
103     path = get_gnupg_path ();
104     if (path == NULL)
105     return NULL;
106     p = get_reg_entry_gpg ("OptFile");
107     if (p && !strcmp (p, ""))
108     {
109     nlen = strlen (path) + 64;
110     optfile = new char[nlen + 1];
111     if (optfile == NULL)
112     BUG (0);
113     _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);
114     }
115     else if( p ) {
116     nlen = strlen( p ) + 4;
117     optfile = new char[nlen + 1];
118     if( optfile == NULL )
119     BUG( NULL );
120     _snprintf( optfile, nlen, "%s", p );
121     }
122     else {
123     nlen = strlen( path ) + 64;
124     optfile = new char[nlen + 1];
125     if( optfile == NULL )
126     BUG( NULL );
127     _snprintf( optfile, nlen, "%s\\"GPG_CONF, path );
128     }
129     free_if_alloc (path);
130     free_if_alloc (p);
131    
132     return optfile;
133     } /* get_gnupg_cfgfile */
134    
135    
136     char *
137     get_gnupg_keyring (int pub, int strict)
138     {
139     char * optfile = NULL, * path = NULL;
140     char * keyring = NULL;
141    
142     path = get_gnupg_path ();
143     if (!path)
144     return NULL;
145     keyring = make_filename (path, pub? "pubring" : "secring", "gpg");
146     if (!strict && !file_exist_check (keyring)) {
147     free_if_alloc (path);
148     return keyring;
149     }
150     if (file_exist_check (keyring) || get_file_size (keyring) == 0) {
151     free_if_alloc (keyring);
152     optfile = make_filename (path, GPG_CONF, NULL);
153     keyring = get_gnupg_keyring_from_options (optfile, pub);
154     }
155     free_if_alloc (path);
156     free_if_alloc (optfile);
157     return keyring;
158     } /* get_gnupg_keyring */
159    
160    
161     /*
162     * Return the full path (with the gpg exe name). First the registry is scanned
163     * for the entry 'gpgProgram'. If it wasn't set, the default path is the
164     * appended string 'gpg.exe' is used.
165     */
166     char*
167     get_gnupg_prog( void )
168     {
169     char *p, *path, *pgm = NULL;
170     size_t nlen = 0;
171    
172     path = get_gnupg_path ();
173     if (path == NULL)
174     return NULL;
175    
176     p = get_reg_entry_gpg ("gpgProgram");
177     if (p == NULL)
178     pgm = make_filename (path, "gpg", "exe");
179     else {
180     pgm = m_strdup (p);
181     free_if_alloc (p);
182     }
183     free_if_alloc (path);
184     return pgm;
185     } /* get_gnupg_prog */
186    
187    
188     static char *
189     default_key_from_cache (int * ret_no_useable)
190     {
191     const char * s;
192     char * keyid = NULL;
193     gpgme_key_t key;
194     gpgme_keycache_t sec = keycache_get_ctx (0);
195    
196     if (!sec)
197     BUG (0);
198     gpgme_keycache_rewind (sec);
199     while (!gpgme_keycache_next_key (sec, 1, &key))
200     {
201     if (gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_USABLE, NULL, 0))
202     {
203     s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, 0);
204     if (s)
205     keyid = m_strdup (s+8);
206     break;
207     }
208     }
209     if (!keyid)
210     {
211     *ret_no_useable = 1;
212     msg_box( NULL, _("No useable secret key found."), _("GPG Error"), MB_ERR);
213     }
214     return keyid;
215     } /* default_key_from_cache */
216    
217    
218     char *
219     get_gnupg_default_key (void)
220     {
221     gpg_optfile_t opt = NULL;
222     gpg_option_t e;
223     char * keyid = NULL, * optfile = NULL;
224     int no_usable=0, rc = 0;
225    
226     optfile = get_gnupg_cfgfile ();
227     if (!optfile)
228     return default_key_from_cache( &no_usable );
229     rc = parse_gpg_options( optfile, &opt );
230     if( rc ) {
231     free_if_alloc( optfile );
232     return default_key_from_cache( &no_usable );
233     }
234     e = find_option( opt, "default-key" );
235     if ( e )
236     keyid = m_strdup( e->val );
237     if( !e ) {
238     e = find_option( opt, "local-user" );
239     if( e )
240     keyid = m_strdup( e->val );
241     }
242     if( !e ) {
243     e = find_option( opt, "encrypt-to" );
244     if( e )
245     keyid = m_strdup( e->val );
246     }
247     free_if_alloc( optfile );
248     release_gpg_options( opt );
249    
250     if( !keyid )
251     keyid = default_key_from_cache( &no_usable );
252     return keyid;
253     } /* get_gnupg_default_key */
254    
255     /*
256     * Check if the gpg application (exe file) is available.
257     */
258     int
259     check_gnupg_prog( void )
260     {
261     char *pgm = NULL;
262     int rc = 0;
263    
264     pgm = get_gnupg_prog( );
265     if( pgm == NULL )
266     rc = WPTERR_GPG_EXEFILE;
267     if( file_exist_check( pgm ) )
268     rc = WPTERR_GPG_EXEFILE;
269     free_if_alloc( pgm );
270     return rc;
271     } /* check_gpg_prog */
272    
273    
274     static int
275     parse_version_nr( const char * buf, int *major, int *minor, int *patch )
276     {
277     char tmp[8];
278     int i;
279    
280     if( strncmp( buf, "gpg ", 4 ) )
281     return -1;
282     buf += 4;
283     if( strncmp( buf, "(GnuPG) ", 8 ) )
284     return -1;
285     buf += 8;
286     i=0;
287     while( buf && *buf != '.' && i < 8 )
288     tmp[i++] = *buf++;
289     tmp[i] = 0; buf++;
290     *major = atol( tmp );
291     i=0;
292     while( buf && *buf != '.' && i < 8 )
293     tmp[i++] = *buf++;
294     tmp[i] = 0; buf++;
295     *minor = atol( tmp );
296     i=0;
297     while( buf && isdigit( *buf ) && i < 8 )
298     tmp[i++] = *buf++;
299     tmp[i] = 0;
300     *patch = atol( tmp );
301     return 0;
302     }
303    
304    
305     int
306     check_gnupg_engine (int * r_major, int * r_minor, int * r_patch)
307     {
308     gpgme_error_t err;
309     char * eng = NULL;
310     int major=0, minor=0, patch=0;
311     int rc;
312    
313     err = gpgme_op_version( &eng );
314     if( err )
315     return -1;
316     if( strstr( eng, "IDEA" ) )
317     idea_available = 1;
318     rc = parse_version_nr( eng, &major, &minor, &patch );
319     free( eng ); eng = NULL;
320     if( rc )
321     return rc;
322     if( major < *r_major
323     || minor < *r_minor)
324     rc = 1;
325     else {
326     if (patch < *r_patch )
327     rc = 1;
328     rc = 0;
329     }
330     *r_major = major;
331     *r_minor = minor;
332     *r_patch = patch;
333     return rc;
334     } /* check_gnupg_engine */
335    
336    
337     int
338     check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)
339     {
340     gpg_optfile_t opt;
341     gpg_option_t e;
342     int rc = 0;
343    
344     if( r_secrings )
345     *r_secrings = 0;
346     if( r_pubrings )
347     *r_pubrings = 0;
348     rc = parse_gpg_options( fname, &opt );
349     if( rc )
350     return WPTERR_FILE_OPEN;
351    
352     for( e = opt->list; e; e = e->next ) {
353     if( !strcmp( e->name, "secret-keyring" ) ) {
354     if( !file_exist_check( e->val ) )
355     r_secrings[0]++;
356     }
357     else if( !strcmp( e->name, "keyring" ) ) {
358     if( !file_exist_check( e->val ) )
359     r_pubrings[0]++;
360     }
361     }
362     release_gpg_options( opt );
363     return 0;
364     } /* check_gnupg_cfgfile */
365    
366     /*
367     * Check if both keyrings are located in the gnupg home directory.
368     */
369     int
370     gnupg_access_files (void)
371     {
372     int rc = 0;
373     int pubring_ok = 0, secring_ok = 0;
374     int secrings = 0, pubrings = 0;
375     char *optfile;
376    
377     if (gnupg_access_keyring (1))
378     rc = WPTERR_GPG_KEYRINGS;
379     else
380     pubring_ok = 1;
381    
382     if (gnupg_access_keyring (0))
383     rc = WPTERR_GPG_KEYRINGS;
384     else
385     secring_ok = 1;
386     if (!pubring_ok || !secring_ok) {
387     optfile = get_gnupg_cfgfile ();
388     if (!optfile)
389     return WPTERR_GPG_KEYRINGS;
390     rc = file_exist_check (optfile);
391     if (!rc && get_file_size(optfile) > 0) {
392     rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);
393     if (!rc && secrings && pubrings) {
394     free_if_alloc (optfile);
395     return 0; /* found two keyrings in the option file */
396     }
397     else if ((!rc && pubrings && secring_ok)
398     || (!rc && secrings && pubring_ok)) {
399     free_if_alloc (optfile);
400     return 0; /* found one keyring and one entry in the options file */
401     }
402     else
403     return WPTERR_GPG_OPT_KEYRINGS;
404     }
405     free_if_alloc (optfile);
406     rc = WPTERR_GPG_KEYRINGS;
407     }
408     return rc;
409     } /* gnupg_access_files */
410    
411    
412     static int
413     create_gpg_options( void )
414     {
415     FILE *fp;
416     char *s, *optfile;
417    
418     s = get_gnupg_path( );
419     if( s == NULL )
420     return WPTERR_FILE_CREAT;
421     optfile = make_filename( s, GPG_CONF, NULL );
422     fp = fopen( optfile, "wb" );
423     if( fp == NULL ) {
424     return WPTERR_FILE_CREAT;
425     goto fail;
426     }
427     fwrite( options_skel, 1, strlen( options_skel ), fp );
428     fclose( fp );
429    
430     fail:
431     free_if_alloc( s );
432     free_if_alloc( optfile );
433     return 0;
434     } /* create_gpg_options */
435    
436    
437     /*
438     * Return the contents of the options file as a char buf.
439     */
440     char *
441     get_gnupg_config( void )
442     {
443     FILE * fp;
444     char * p = NULL, * optfile = NULL;
445     int fsize, rc = 0;
446    
447     optfile = get_gnupg_cfgfile( );
448     if( optfile == NULL )
449     return NULL;
450     fsize = get_file_size( optfile );
451     if( !fsize ) {
452     rc = create_gpg_options( );
453     if ( rc )
454     return NULL;
455     fsize = get_file_size( optfile );
456     }
457     if( fsize > 100000 )
458     goto leave; /* too large */
459     p = new char[fsize+1];
460     if( p == NULL )
461     BUG( NULL );
462     fp = fopen( optfile, "rb" );
463     if( fp == NULL ) {
464     free_if_alloc( p );
465     return NULL;
466     }
467     fread( p, 1, fsize, fp );
468     fclose( fp );
469     p[fsize] = '\0';
470     free_if_alloc( optfile );
471    
472     leave:
473     return p;
474     } /* get_gnupg_config */
475    
476    
477     int
478     set_gnupg_default_key (const char * key)
479     {
480     gpg_optfile_t opt;
481     gpg_option_t e;
482     char *optfile = NULL;
483     int rc = 0;
484    
485     optfile = get_gnupg_cfgfile ();
486     if (!optfile)
487     return -1;
488     rc = parse_gpg_options (optfile, &opt);
489     if( rc ) {
490     free_if_alloc (optfile);
491     return -1;
492     }
493     e = find_option (opt, "default-key");
494     if (e) {
495     free_if_alloc (e->val);
496     e->val = m_strdup (key);
497     e->used = 1;
498     }
499     else
500     add_entry (opt, ENTRY_MULTI, "default-key", key);
501     rc = commit_gpg_options (optfile, opt);
502    
503     free_if_alloc (optfile);
504     release_gpg_options (opt);
505    
506     return rc;
507     } /* set_gnupg_default_key */
508    
509    
510     /*
511     * Set the contents of the options file.
512     */
513     int
514     set_gnupg_options( const char *buf, size_t buflen )
515     {
516     FILE *fp;
517     char *optfile = NULL;
518    
519     optfile = get_gnupg_cfgfile( );
520     if( optfile == NULL )
521     return WPTERR_FILE_CREAT;
522    
523     fp = fopen( optfile, "wb" );
524     if( fp == NULL ) {
525     free_if_alloc( optfile );
526     return WPTERR_FILE_CREAT;
527     }
528     fwrite( buf, 1, buflen, fp );
529     fclose( fp );
530     free_if_alloc( optfile );
531     return 0;
532     } /* set_gnupg_options */
533    
534     /*
535     * Check if the line contains a valid GPG argument.
536     */
537     static int
538     check_line( const char *buf )
539     {
540     int j, len;
541     int rc = 0;
542    
543     if( *buf == '#' || *buf == '\r' || *buf == '\n' )
544     return 1;
545     rc = 0;
546     for ( j = 0; valid_gpg_args[j]; j++ ) {
547     len = strlen( valid_gpg_args[j] );
548     if( !strncmp( valid_gpg_args[j], buf, len ) )
549     rc = 1;
550     }
551    
552     return rc;
553     } /* check_line */
554    
555    
556     int
557     check_gnupg_options( const char *buf )
558     {
559     char line[1024];
560     int nbytes = 0;
561     unsigned j;
562    
563     for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {
564     line[nbytes++] = buf[j];
565     if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {
566     line[nbytes] = '\0';
567     if( !check_line( line ) ) {
568     msg_box( NULL, line, "options", MB_OK );
569     return 1;
570     }
571     nbytes = 0;
572     }
573     }
574    
575     return 0;
576     } /* check_gnupg_options */
577    
578    
579     static int
580     get_last_gnupg_access (gpg_watcher_s * ctx)
581     {
582     HANDLE fd;
583     char *path = NULL, *file = NULL;
584    
585     path = get_gnupg_path ();
586     file = make_filename (path, ctx->object, NULL);
587     fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
588     if( fd == INVALID_HANDLE_VALUE ) {
589     free_if_alloc (path);
590     free_if_alloc (file);
591     return WPTERR_FILE_OPEN;
592     }
593     GetFileTime (fd, NULL, NULL, &ctx->access);
594     CloseHandle (fd);
595     free_if_alloc (path);
596     free_if_alloc (file);
597     return 0;
598     } /* get_last_gnupg_access */
599    
600    
601     static void
602     check_last_gnupg_access( gpg_watcher_s *ctx )
603     {
604     ctx->modified = 0;
605    
606     if( ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
607     ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime )
608     ctx->modified = 1;
609    
610     ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;
611     ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;
612     } /* check_last_gnupg_access */
613    
614    
615     void
616     init_gnupg_table (void)
617     {
618     int j;
619    
620     for (j = 0; j < gpg_table_count; j++) {
621     gpg_table[j].object = m_strdup (gpg_objs[j]);
622     memset (&gpg_table[j].access, 0, sizeof (FILETIME));
623     memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
624     gpg_table[j].modified = 0;
625     }
626     } /* init_gnupg_table */
627    
628    
629     void
630     free_gnupg_table (void)
631     {
632     int j;
633    
634     for (j=0; j < gpg_table_count; j++)
635     free_if_alloc (gpg_table[j].object);
636     } /* free_gnupg_table */
637    
638    
639     int
640     keyring_check_last_access (void)
641     {
642     int rc, j;
643    
644     rc = 0;
645     for (j = 0; j < gpg_table_count; j++) {
646     get_last_gnupg_access( &gpg_table[j] );
647     check_last_gnupg_access( &gpg_table[j] );
648     if ( gpg_table[j].modified )
649     rc++;
650     }
651    
652     return rc;
653     } /* keyring_check_last_access */
654    
655    
656     const char *
657     gnupg_check_file_ext (const char * fname)
658     {
659     char file_ext[5];
660    
661     if (!strchr( fname, '.' ))
662     return "UNKNOWN";
663    
664     strncpy (file_ext, fname + strlen (fname) - 4, 4);
665     file_ext[4] = '\0';
666     if (!stricmp (file_ext, ".asc"))
667     return "ARMORED";
668     else if (!stricmp (file_ext, ".sig"))
669     return "SIGNED";
670     else if (!stricmp (file_ext, ".gpg")
671     || !stricmp (file_ext, ".pgp"))
672     return "ENCRYPTED";
673     else
674     return "UNKNOWN";
675    
676     return "UNKNOWN";
677     } /* gnupg_check_file_ext */
678    
679    
680     char *
681     get_gnupg_keyring_from_options (const char * fname, int pub)
682     {
683     gpg_optfile_t opt;
684     gpg_option_t e;
685     char * kring = NULL;
686     int rc = 0;
687    
688     rc = parse_gpg_options (fname, &opt);
689     if (rc)
690     return NULL;
691     if (pub)
692     e = find_option (opt, "keyring");
693     else
694     e = find_option (opt, "secret-keyring");
695     if (e)
696     kring = m_strdup (e->val);
697     release_gpg_options (opt);
698    
699     return kring;
700     } /* get_gnupg_keyring_from_options */
701    
702    
703    
704     /* XXX: does not work with write-protected floppies */
705     static int
706     my_access (const char * fname)
707     {
708     HANDLE hd;
709     hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
710     if (hd == INVALID_HANDLE_VALUE)
711     return -1;
712     CloseHandle (hd);
713     return 0;
714     } /* my_access */
715    
716    
717     int
718     gpg_check_permissions (int showmsg)
719     {
720     char * p, * name = NULL;
721     int failed = 0, ans=0, attrs=0;
722    
723     p = get_gnupg_path ();
724     check_keyring (&p);
725     if (p) {
726     name = make_filename (p, "pubring", "gpg");
727     free_if_alloc (p);
728     if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
729     ans = msg_box (NULL,
730     _("The selected keyring has the read-only file\n"
731     "attribute. In this state you do not have write\n"
732     "access. Do you want to remove the attribute?"),
733     _("GPG Information"), MB_YESNO);
734     if (ans == IDYES) {
735     attrs &= ~FILE_ATTRIBUTE_READONLY;
736     if (!SetFileAttributes (name, attrs)) {
737     msg_box (NULL, _("Could not reset read-only state."),
738     _("GPG Error"), MB_ERR);
739     failed = 1;
740     }
741     }
742     else if (ans == IDNO) {
743     /*
744     msg_box (NULL, _("All commands with write access to the keyring\n"
745     "will be disabled."), _("GPG Information"), MB_INFO);
746     */
747     failed = 1;
748     }
749     }
750     if (my_access (name)) {
751     if (showmsg)
752     msg_box (NULL,
753     _("You do not have file access to modify the contents of\n"
754     "one or both of the selected keyrings.\n"
755     "\n"
756     "The keyrings are in a read-only state which is propably\n"
757     "caused by another program which already opened the files.\n"),
758     _("GPG Warning"), MB_WARN);
759     failed = 2;
760     }
761     }
762     free_if_alloc (name);
763     return failed;
764     } /* gpg_check_permissions */
765    
766    
767     static int
768     check_homedir (void)
769     {
770     char * homedir = NULL;
771     int yes = 0;
772    
773     homedir = get_reg_entry_gpg ("HomeDir");
774     if (!homedir)
775     homedir = multi_gnupg_path ();
776     if (!homedir)
777     homedir = m_strdup ("c:\\gnupg");
778     if (homedir) {
779     if (GetFileAttributes (homedir) == 0xFFFFFFFF) {
780     yes = log_box (_("Preferences"), MB_YESNO,
781     _("%s does not exit.\n"
782     "Do you want to create this directory?"), homedir);
783     if (yes == IDYES) {
784     if (CreateDirectory (homedir, NULL) == FALSE) {
785     free_if_alloc (homedir);
786     return WPTERR_DIR_CREAT;
787     }
788     }
789     return WPTERR_DIR_OPEN;
790     }
791     free_if_alloc (homedir);
792     }
793     return 0;
794     } /* check_homedir */
795    
796    
797     int
798     gnupg_check_homedir (void)
799     {
800     char *homedir = NULL, *prog = NULL;
801     int rc = 0, ec = 0;
802    
803     rc = check_homedir ();
804     if (rc)
805     return rc;
806     if ((homedir = get_reg_entry_gpg ("HomeDir")) &&
807     !(prog = get_reg_entry_gpg ("gpgProgram" ))) {
808     prog = make_filename (homedir, "gpg", "exe");
809     if (file_exist_check (prog) == 0) {
810     rc = set_reg_entry_gpg ("gpgProgram", prog);
811     if (rc)
812     goto fail;
813     }
814     free_if_alloc (homedir);
815     free_if_alloc (prog);
816     return rc;
817     }
818     if ((prog = get_reg_entry_gpg ("gpgProgram"))
819     && file_exist_check (prog)) {
820     free_if_alloc (prog);
821     homedir = get_reg_entry_gpg ("HomeDir");
822     if (!homedir) {
823     rc = WPTERR_GENERAL;
824     goto fail;
825     }
826     prog = make_filename (homedir, "gpg", "exe");
827     if (file_exist_check (prog) == 0) {
828     rc = set_reg_entry_gpg ("gpgProgram", prog);
829     if (rc)
830     goto fail;
831     free_if_alloc (prog);
832     return rc;
833     }
834     }
835    
836     /* Change the return code if homedir doesn't exist or if the program
837     doesn't exist. Note that exist_checks return 0 to suggest existance. */
838     if ((!homedir || dir_exist_check (homedir)))
839     rc = WPTERR_GENERAL;
840    
841     fail:
842     free_if_alloc (homedir);
843     free_if_alloc (prog);
844     return rc;
845     } /* gnupg_check_homedir */
846    
847    
848     int
849     gnupg_copy_keyrings (void)
850     {
851     const char * pring, * sring;
852     char * file = NULL, * path = NULL;
853     int id = 0, rc = 0;
854     HWND hwnd;
855    
856     path = get_gnupg_path ();
857     if (!path)
858     return WPTERR_GENERAL;
859     hwnd = GetDesktopWindow ();
860    
861     pring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your public keyring"),
862     _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);
863     if (!pring) {
864     msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);
865     free_if_alloc (path);
866     return WPTERR_GENERAL;
867     }
868     file = make_filename (path, "pubring", "gpg");
869     if (file_exist_check (file) == 0) {
870     id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);
871     if (id == IDNO)
872     goto fail;
873     }
874     if (!CopyFile (pring, file, FALSE)) {
875     msg_box (hwnd, _("Could not copy file."), _("WinPT Error"), MB_ERR);
876     rc = WPTERR_FILE_READ;
877     goto fail;
878     }
879     free_if_alloc (file);
880    
881     sring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your secret keyring"),
882     _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);
883     if (!sring) {
884     msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );
885     return WPTERR_GENERAL;
886     }
887     file = make_filename (path, "secring", "gpg");
888     if (file_exist_check (file) == 0) {
889     id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);
890     if( id == IDNO )
891     goto fail;
892     }
893     if (!CopyFile (sring, file, FALSE)) {
894     msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
895     rc = WPTERR_FILE_READ;
896     }
897    
898     fail:
899     free_if_alloc (file);
900     free_if_alloc (path);
901     return rc;
902     } /* gnupg_import_keyrings */
903    
904    
905     void
906     gnupg_backup_options (int keep)
907     {
908     char *optfile = NULL;
909     char bak[1024];
910    
911     optfile = get_gnupg_cfgfile ();
912     if (optfile == NULL)
913     return;
914     if (keep)
915     _snprintf (bak, DIM (bak)-1, "%s.old", optfile);
916     else
917     _snprintf (bak, DIM (bak)-1, "%s.O", optfile);
918     CopyFile (optfile, bak, keep);
919     free_if_alloc (optfile);
920     } /* gnupg_backup_options */
921    
922    
923    
924     static int
925     backup_one_file (const char * srcpath, const char * srcn,
926     const char * dstpath, const char * dstn)
927     {
928     char * src, * dst;
929     BOOL rc;
930    
931     src = make_filename (srcpath, srcn, "gpg");
932     if (!src)
933     BUG (NULL);
934     dst = make_filename (dstpath, dstn, "gpg");
935     if (!dst)
936     BUG (NULL);
937     rc = CopyFile (src, dst, FALSE);
938     free_if_alloc (src);
939     free_if_alloc (dst);
940     if (!rc)
941     {
942     log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
943     return WPTERR_GENERAL;
944     }
945     return 0;
946     } /* backup_one_file */
947    
948    
949     static int
950     check_keyring (char ** r_path)
951     {
952     char * p;
953     char * opt, * name;
954    
955     if (!*r_path)
956     return 0;
957     p = make_filename (*r_path, "pubring", "gpg");
958     if (!p || get_file_size (p) > 0)
959     return 0;
960    
961     opt = get_gnupg_cfgfile ();
962     if (!opt)
963     BUG (0);
964     name = get_gnupg_keyring_from_options (opt, 1);
965     free_if_alloc (opt);
966     free_if_alloc (p);
967     if (!name)
968     return 0;
969     p = strrchr (name, '\\');
970     if (!p)
971     {
972     free_if_alloc (name);
973     return 0;
974     }
975     free_if_alloc (*r_path);
976     *r_path = new char [strlen (name)+1];
977     memset (*r_path, 0, strlen (name));
978     strncpy (*r_path, name, (p-name));
979     free_if_alloc (name);
980     return 1;
981     }
982    
983    
984     void
985     gnupg_backup_keyrings (void)
986     {
987     char * srcpath = NULL, * dstpath = NULL;
988     int rc, bakmode=0;
989    
990     if (!reg_prefs.auto_backup)
991     return;
992     bakmode = reg_prefs.backup.mode;
993     srcpath = get_gnupg_path ();
994     check_keyring (&srcpath);
995     if (bakmode == 1)
996     {
997     dstpath = get_gnupg_path ();
998     check_keyring (&dstpath);
999     }
1000     else if (bakmode == 2)
1001     {
1002     char * tmpfile;
1003     FILE * fp;
1004    
1005     dstpath = m_strdup (reg_prefs.backup.path);
1006     if (!dstpath)
1007     BUG (0);
1008     tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1009     fp = fopen (tmpfile, "wb");
1010     if (!fp)
1011     rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL, _("The backup drive '%s' does not seems to accessable.\n"
1012     "Please insert/check the drive to continue."), dstpath);
1013     else
1014     {
1015     rc = 0;
1016     fclose (fp);
1017     unlink (tmpfile);
1018     }
1019     free_if_alloc (tmpfile);
1020     if (!fp || rc == IDCANCEL)
1021     return;
1022     }
1023     else
1024     {
1025     log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);
1026     return;
1027     }
1028     rc = backup_one_file (srcpath, "pubring", dstpath, "pubring-bak");
1029     if (!rc)
1030     rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1031     free_if_alloc (srcpath);
1032     free_if_alloc (dstpath);
1033     } /* gnupg_backup_keyrings */
1034    
1035    
1036     void
1037     gnupg_display_error (void)
1038     {
1039     char tmpath[512], * errstr;
1040     size_t size = 0;
1041     FILE * fp;
1042    
1043     GetTempPath (sizeof tmpath - 32, (tmpath));
1044     strcat (tmpath, "gpg_stderr");
1045     size = get_file_size (tmpath);
1046     if (file_exist_check (tmpath) || size <= 0)
1047     return;
1048     fp = fopen( tmpath, "rb" );
1049     if (!fp) {
1050     msg_box( NULL, _("No GPG error description available."), _("GPG Error"), MB_INFO );
1051     return;
1052     }
1053     errstr = new char[size+1];
1054     if (!errstr)
1055     BUG (0);
1056     fread (errstr, 1, size, fp);
1057     errstr[size] = '\0';
1058     fclose (fp);
1059     msg_box (NULL, errstr, _("GPG Error"), MB_INFO);
1060     free_if_alloc (errstr);
1061     } /* gnupg_display_error */
1062    
1063    
1064     int
1065     gnupg_access_keyring (int _pub)
1066     {
1067     int rc = 0;
1068     char * name = get_gnupg_keyring (_pub, 1);
1069     if (file_exist_check (name))
1070     rc = -1;
1071     free_if_alloc (name);
1072     return rc;
1073     }
1074    

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26