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

Annotation of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 25744 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26