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

Contents of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (show annotations)
Wed Oct 12 10:04:26 2005 UTC (19 years, 4 months ago) by twoaday
File size: 25774 byte(s)
First testing phase finished.
Provide bug fixes for a lot of (minor) problems.

1 /* 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 /* MSDN: buf must be at least MAX_PATH=256 bytes */
63 memset (buf, 0, sizeof (buf));
64 ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);
65 if (ec != 1)
66 return NULL;
67 strcat (buf, "\\gnupg");
68 if (access (buf, 00))
69 return NULL;
70 return m_strdup (buf);
71 }
72
73 /*
74 * Return the full path of the GnuPG application. First the registry is scanned
75 * for the entry 'HomeDir'. If it wasn't set, the default dir C:\GNUPG is used.
76 */
77 char*
78 get_gnupg_path (void)
79 {
80 char *p = NULL, *path = NULL;
81
82 p = get_reg_entry_gpg ("HomeDir");
83 if (p) {
84 path = m_strdup (p);
85 free_if_alloc (p);
86 return path;
87 }
88 else
89 return multi_gnupg_path ();
90 return m_strdup ("c:\\gnupg");
91 } /* get_gnupg_path */
92
93
94 char*
95 get_gnupg_cfgfile (void)
96 {
97 char *p = NULL, *optfile = NULL, *path = NULL;
98 size_t nlen = 0;
99
100 path = get_gnupg_path ();
101 if (path == NULL)
102 return NULL;
103 p = get_reg_entry_gpg ("OptFile");
104 if (p && !strcmp (p, ""))
105 {
106 nlen = strlen (path) + 64;
107 optfile = new char[nlen + 1];
108 if (optfile == NULL)
109 BUG (0);
110 _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);
111 }
112 else if( p ) {
113 nlen = strlen( p ) + 4;
114 optfile = new char[nlen + 1];
115 if( optfile == NULL )
116 BUG( NULL );
117 _snprintf( optfile, nlen, "%s", p );
118 }
119 else {
120 nlen = strlen( path ) + 64;
121 optfile = new char[nlen + 1];
122 if( optfile == NULL )
123 BUG( NULL );
124 _snprintf( optfile, nlen, "%s\\"GPG_CONF, path );
125 }
126 free_if_alloc (path);
127 free_if_alloc (p);
128
129 return optfile;
130 } /* get_gnupg_cfgfile */
131
132
133 char *
134 get_gnupg_keyring (int pub, int strict)
135 {
136 char * optfile = NULL, * path = NULL;
137 char * keyring = NULL;
138
139 path = get_gnupg_path ();
140 if (!path)
141 return NULL;
142 keyring = make_filename (path, pub? "pubring" : "secring", "gpg");
143 if (!strict && !file_exist_check (keyring)) {
144 free_if_alloc (path);
145 return keyring;
146 }
147 if (file_exist_check (keyring) || get_file_size (keyring) == 0) {
148 free_if_alloc (keyring);
149 optfile = make_filename (path, GPG_CONF, NULL);
150 keyring = get_gnupg_keyring_from_options (optfile, pub);
151 }
152 free_if_alloc (path);
153 free_if_alloc (optfile);
154 return keyring;
155 } /* get_gnupg_keyring */
156
157
158 /*
159 * Return the full path (with the gpg exe name). First the registry is scanned
160 * for the entry 'gpgProgram'. If it wasn't set, the default path is the
161 * appended string 'gpg.exe' is used.
162 */
163 char*
164 get_gnupg_prog (void)
165 {
166 char *p, *path, *pgm = NULL;
167 size_t nlen = 0;
168
169 path = get_gnupg_path ();
170 if (path == NULL)
171 return NULL;
172
173 p = get_reg_entry_gpg ("gpgProgram");
174 if (p == NULL)
175 pgm = make_filename (path, "gpg", "exe");
176 else {
177 pgm = m_strdup (p);
178 free_if_alloc (p);
179 }
180 free_if_alloc (path);
181 return pgm;
182 } /* get_gnupg_prog */
183
184
185 static char *
186 default_key_from_cache (int *ret_no_useable)
187 {
188 const char * s;
189 char * keyid = NULL;
190 gpgme_key_t key;
191 gpg_keycache_t sec = keycache_get_ctx (0);
192
193 if (!sec)
194 BUG (0);
195 gpg_keycache_rewind (sec);
196 while (!gpg_keycache_next_key (sec, 1, &key)) {
197 if (key_is_useable (key)) {
198 s = key->subkeys->keyid;
199 if (s)
200 keyid = m_strdup (s+8);
201 break;
202 }
203 }
204 if (!keyid) {
205 *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 int
252 check_gnupg_prog (void)
253 {
254 char *pgm = NULL;
255 int rc = 0;
256
257 pgm = get_gnupg_prog ();
258 if (!pgm)
259 rc = WPTERR_GPG_EXEFILE;
260 if (file_exist_check (pgm))
261 rc = WPTERR_GPG_EXEFILE;
262 free_if_alloc (pgm);
263 return rc;
264 }
265
266
267 static int
268 parse_version_nr (const char * buf, int *major, int *minor, int *patch)
269 {
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 /* 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 int
296 check_gnupg_engine (int *r_major, int *r_minor, int *r_patch)
297 {
298 gpgme_ctx_t ctx;
299 gpgme_engine_info_t inf;
300 char * eng = NULL;
301 int major=0, minor=0, patch=0;
302 int rc;
303
304 gpgme_new (&ctx);
305 inf = gpgme_ctx_get_engine_info (ctx);
306 if (!inf) {
307 gpgme_release (ctx);
308 return -1;
309 }
310 /* 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 idea_available = 1;
315 free (eng);
316 rc = parse_version_nr( inf->version, &major, &minor, &patch );
317 if( rc ) {
318 gpgme_release (ctx);
319 return rc;
320 }
321 if (major < *r_major || minor < *r_minor)
322 rc = 1;
323 else {
324 if (patch < *r_patch)
325 rc = 1;
326 rc = 0;
327 }
328 *r_major = major;
329 *r_minor = minor;
330 *r_patch = patch;
331 return rc;
332 }
333
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 get_gnupg_config (void)
440 {
441 FILE * fp;
442 char * p = NULL, * optfile = NULL;
443 int fsize, rc = 0;
444
445 optfile = get_gnupg_cfgfile ();
446 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 const char *
655 gnupg_check_file_ext (const char * fname)
656 {
657 char file_ext[5];
658
659 if (!strchr( fname, '.' ))
660 return "UNKNOWN";
661
662 strncpy (file_ext, fname + strlen (fname) - 4, 4);
663 file_ext[4] = '\0';
664 if (!stricmp (file_ext, ".asc"))
665 return "ARMORED";
666 else if (!stricmp (file_ext, ".sig"))
667 return "SIGNED";
668 else if (!stricmp (file_ext, ".gpg")
669 || !stricmp (file_ext, ".pgp"))
670 return "ENCRYPTED";
671 else
672 return "UNKNOWN";
673
674 return "UNKNOWN";
675 } /* gnupg_check_file_ext */
676
677
678 char *
679 get_gnupg_keyring_from_options (const char * fname, int pub)
680 {
681 gpg_optfile_t opt;
682 gpg_option_t e;
683 char * kring = NULL;
684 int rc = 0;
685
686 rc = parse_gpg_options (fname, &opt);
687 if (rc)
688 return NULL;
689 if (pub)
690 e = find_option (opt, "keyring");
691 else
692 e = find_option (opt, "secret-keyring");
693 if (e)
694 kring = m_strdup (e->val);
695 release_gpg_options (opt);
696
697 return kring;
698 } /* get_gnupg_keyring_from_options */
699
700
701
702 /* XXX: does not work with write-protected floppies */
703 static int
704 my_access (const char * fname)
705 {
706 HANDLE hd;
707 hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
708 if (hd == INVALID_HANDLE_VALUE)
709 return -1;
710 CloseHandle (hd);
711 return 0;
712 } /* my_access */
713
714
715 int
716 gpg_check_permissions (int showmsg)
717 {
718 char * p, * name = NULL;
719 int failed = 0, ans=0, attrs=0;
720
721 p = get_gnupg_path ();
722 check_keyring (&p);
723 if (p) {
724 name = make_filename (p, "pubring", "gpg");
725 free_if_alloc (p);
726 if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
727 ans = msg_box (NULL,
728 _("The selected keyring has the read-only file\n"
729 "attribute. In this state you do not have write\n"
730 "access. Do you want to remove the attribute?"),
731 _("GPG Information"), MB_YESNO);
732 if (ans == IDYES) {
733 attrs &= ~FILE_ATTRIBUTE_READONLY;
734 if (!SetFileAttributes (name, attrs)) {
735 msg_box (NULL, _("Could not reset read-only state."),
736 _("GPG Error"), MB_ERR);
737 failed = 1;
738 }
739 }
740 else if (ans == IDNO) {
741 /*
742 msg_box (NULL, _("All commands with write access to the keyring\n"
743 "will be disabled."), _("GPG Information"), MB_INFO);
744 */
745 failed = 1;
746 }
747 }
748 if (my_access (name)) {
749 if (showmsg)
750 msg_box (NULL,
751 _("You do not have file access to modify the contents of\n"
752 "one or both of the selected keyrings.\n"
753 "\n"
754 "The keyrings are in a read-only state which is propably\n"
755 "caused by another program which already opened the files.\n"),
756 _("GPG Warning"), MB_WARN);
757 failed = 2;
758 }
759 }
760 free_if_alloc (name);
761 return failed;
762 } /* gpg_check_permissions */
763
764
765 static int
766 check_homedir (void)
767 {
768 char * homedir = NULL;
769 int yes = 0;
770
771 homedir = get_reg_entry_gpg ("HomeDir");
772 if (!homedir)
773 homedir = multi_gnupg_path ();
774 if (!homedir)
775 homedir = m_strdup ("c:\\gnupg");
776 if (homedir) {
777 if (GetFileAttributes (homedir) == 0xFFFFFFFF) {
778 yes = log_box (_("Preferences"), MB_YESNO,
779 _("%s does not exit.\n"
780 "Do you want to create this directory?"), homedir);
781 if (yes == IDYES) {
782 if (CreateDirectory (homedir, NULL) == FALSE) {
783 free_if_alloc (homedir);
784 return WPTERR_DIR_CREAT;
785 }
786 }
787 return WPTERR_DIR_OPEN;
788 }
789 free_if_alloc (homedir);
790 }
791 return 0;
792 } /* check_homedir */
793
794
795 int
796 gnupg_check_homedir (void)
797 {
798 char *homedir = NULL, *prog = NULL;
799 int rc = 0, ec = 0;
800
801 rc = check_homedir ();
802 if (rc)
803 return rc;
804 if ((homedir = get_reg_entry_gpg ("HomeDir")) &&
805 !(prog = get_reg_entry_gpg ("gpgProgram" ))) {
806 prog = make_filename (homedir, "gpg", "exe");
807 if (file_exist_check (prog) == 0) {
808 rc = set_reg_entry_gpg ("gpgProgram", prog);
809 if (rc)
810 goto fail;
811 }
812 free_if_alloc (homedir);
813 free_if_alloc (prog);
814 return rc;
815 }
816 if ((prog = get_reg_entry_gpg ("gpgProgram"))
817 && file_exist_check (prog)) {
818 free_if_alloc (prog);
819 homedir = get_reg_entry_gpg ("HomeDir");
820 if (!homedir) {
821 rc = WPTERR_GENERAL;
822 goto fail;
823 }
824 prog = make_filename (homedir, "gpg", "exe");
825 if (file_exist_check (prog) == 0) {
826 rc = set_reg_entry_gpg ("gpgProgram", prog);
827 if (rc)
828 goto fail;
829 free_if_alloc (prog);
830 return rc;
831 }
832 }
833
834 /* Change the return code if homedir doesn't exist or if the program
835 doesn't exist. Note that exist_checks return 0 to suggest existance. */
836 if ((!homedir || dir_exist_check (homedir)))
837 rc = WPTERR_GENERAL;
838
839 fail:
840 free_if_alloc (homedir);
841 free_if_alloc (prog);
842 return rc;
843 } /* gnupg_check_homedir */
844
845
846 int
847 gnupg_copy_keyrings (void)
848 {
849 const char * pring, * sring;
850 char * file = NULL, * path = NULL;
851 int id = 0, rc = 0;
852 HWND hwnd;
853
854 path = get_gnupg_path ();
855 if (!path)
856 return WPTERR_GENERAL;
857 hwnd = GetDesktopWindow ();
858
859 pring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your public keyring"),
860 _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);
861 if (!pring) {
862 msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);
863 free_if_alloc (path);
864 return WPTERR_GENERAL;
865 }
866 file = make_filename (path, "pubring", "gpg");
867 if (file_exist_check (file) == 0) {
868 id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);
869 if (id == IDNO)
870 goto fail;
871 }
872 if (!CopyFile (pring, file, FALSE)) {
873 msg_box (hwnd, _("Could not copy file."), _("WinPT Error"), MB_ERR);
874 rc = WPTERR_FILE_READ;
875 goto fail;
876 }
877 free_if_alloc (file);
878
879 sring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your secret keyring"),
880 _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);
881 if (!sring) {
882 msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );
883 return WPTERR_GENERAL;
884 }
885 file = make_filename (path, "secring", "gpg");
886 if (file_exist_check (file) == 0) {
887 id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);
888 if( id == IDNO )
889 goto fail;
890 }
891 if (!CopyFile (sring, file, FALSE)) {
892 msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
893 rc = WPTERR_FILE_READ;
894 }
895
896 fail:
897 free_if_alloc (file);
898 free_if_alloc (path);
899 return rc;
900 } /* gnupg_import_keyrings */
901
902
903 void
904 gnupg_backup_options (void)
905 {
906 char *cfgfile = NULL;
907 char bak[512];
908
909 cfgfile = get_gnupg_cfgfile ();
910 if (cfgfile == NULL)
911 return;
912 _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);
913 CopyFile (cfgfile, bak, FALSE);
914 free_if_alloc (cfgfile);
915 } /* gnupg_backup_options */
916
917
918
919 static int
920 backup_one_file (const char * srcpath, const char * srcn,
921 const char * dstpath, const char * dstn)
922 {
923 char * src, * dst;
924 BOOL rc;
925
926 src = make_filename (srcpath, srcn, "gpg");
927 if (!src)
928 BUG (NULL);
929 dst = make_filename (dstpath, dstn, "gpg");
930 if (!dst)
931 BUG (NULL);
932 rc = CopyFile (src, dst, FALSE);
933 free_if_alloc (src);
934 free_if_alloc (dst);
935 if (!rc)
936 {
937 log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
938 return WPTERR_GENERAL;
939 }
940 return 0;
941 } /* backup_one_file */
942
943
944 static int
945 check_keyring (char ** r_path)
946 {
947 char * p;
948 char * opt, * name;
949
950 if (!*r_path)
951 return 0;
952 p = make_filename (*r_path, "pubring", "gpg");
953 if (!p || get_file_size (p) > 0)
954 return 0;
955
956 opt = get_gnupg_cfgfile ();
957 if (!opt)
958 BUG (0);
959 name = get_gnupg_keyring_from_options (opt, 1);
960 free_if_alloc (opt);
961 free_if_alloc (p);
962 if (!name)
963 return 0;
964 p = strrchr (name, '\\');
965 if (!p)
966 {
967 free_if_alloc (name);
968 return 0;
969 }
970 free_if_alloc (*r_path);
971 *r_path = new char [strlen (name)+1];
972 memset (*r_path, 0, strlen (name));
973 strncpy (*r_path, name, (p-name));
974 free_if_alloc (name);
975 return 1;
976 }
977
978
979 static char*
980 get_backup_name (const char *templ)
981 {
982 struct tm *tm;
983 char *p;
984
985 time_t t = time (NULL);
986 tm = localtime (&t);
987 p = new char [strlen (templ) + 8 + 1];
988 if (!p)
989 BUG (0);
990 sprintf (p, "%s-%d", templ, tm->tm_wday % 3);
991 return p;
992 }
993
994
995 void
996 gnupg_backup_keyrings (void)
997 {
998 char *srcpath = NULL, *dstpath = NULL;
999 char *name=NULL;
1000 int rc, bakmode=0;
1001
1002 if (!reg_prefs.auto_backup)
1003 return;
1004 bakmode = reg_prefs.backup.mode;
1005 srcpath = get_gnupg_path ();
1006 check_keyring (&srcpath);
1007 if (bakmode == 1) {
1008 dstpath = get_gnupg_path ();
1009 check_keyring (&dstpath);
1010 }
1011 else if (bakmode == 2) {
1012 char * tmpfile;
1013 FILE * fp;
1014
1015 dstpath = m_strdup (reg_prefs.backup.path);
1016 if (!dstpath)
1017 BUG (0);
1018 tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1019 fp = fopen (tmpfile, "wb");
1020 if (!fp)
1021 rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL, _("The backup drive '%s' does not seems to accessable.\n"
1022 "Please insert/check the drive to continue."), dstpath);
1023 else {
1024 rc = 0;
1025 fclose (fp);
1026 unlink (tmpfile);
1027 }
1028 free_if_alloc (tmpfile);
1029 if (!fp || rc == IDCANCEL)
1030 return;
1031 }
1032 else {
1033 log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);
1034 return;
1035 }
1036 name = get_backup_name ("pubring-bak");
1037 rc = backup_one_file (srcpath, "pubring", dstpath, name);
1038 if (!rc)
1039 rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1040 free_if_alloc (name);
1041 free_if_alloc (srcpath);
1042 free_if_alloc (dstpath);
1043 } /* gnupg_backup_keyrings */
1044
1045
1046 void
1047 gnupg_display_error (void)
1048 {
1049 char tmpath[512], * errstr;
1050 size_t size = 0;
1051 FILE * fp;
1052
1053 GetTempPath (sizeof tmpath - 32, (tmpath));
1054 strcat (tmpath, "gpg_stderr");
1055 size = get_file_size (tmpath);
1056 if (file_exist_check (tmpath) || size <= 0)
1057 return;
1058 fp = fopen( tmpath, "rb" );
1059 if (!fp) {
1060 msg_box( NULL, _("No GPG error description available."), _("GPG Error"), MB_INFO );
1061 return;
1062 }
1063 errstr = new char[size+1];
1064 if (!errstr)
1065 BUG (0);
1066 fread (errstr, 1, size, fp);
1067 errstr[size] = '\0';
1068 fclose (fp);
1069 msg_box (NULL, errstr, _("GPG Error"), MB_INFO);
1070 free_if_alloc (errstr);
1071 } /* gnupg_display_error */
1072
1073
1074 int
1075 gnupg_access_keyring (int _pub)
1076 {
1077 int rc = 0;
1078 char * name = get_gnupg_keyring (_pub, 1);
1079 if (file_exist_check (name))
1080 rc = -1;
1081 free_if_alloc (name);
1082 return rc;
1083 }
1084

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26