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

Annotation of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (hide annotations)
Sat Oct 8 10:43:08 2005 UTC (19 years, 4 months ago) by twoaday
File size: 25655 byte(s)
Bug fixes to correct some problems introduced by
the MyGPGME to GPGME port.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26