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

Annotation of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26