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

Contents of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26