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

Annotation of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (hide annotations)
Mon Oct 24 08:03:48 2005 UTC (19 years, 4 months ago) by twoaday
File size: 25861 byte(s)
2005-10-23  Timo Schulz  <twoaday@g10code.com>
 
        * wptFileManager.cpp (fm_get_file_type): Detect detached sigs.
        * wptKeyList.cpp (keylist_cmp_cb): Take care of expired/revoked keys.
        (get_ext_validity): New.
        * wptFileVerifyDlg.cpp (file_verify_dlg_proc): Several cleanups.
        * wptClipEditDlg.cpp (load_clipboard): Factored out some code into
        this function.
        (load_clipboard_from_file): Likewise.
        (save_clipboard_to_file): New.
        * wptKeyManagerDlg.cpp (keyprops_dlg_proc): Fix stack overflow.

For complete details, see the ChangeLog files.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26