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

Contents of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Thu Apr 14 12:56:25 2005 UTC (19 years, 10 months ago) by twoaday
File size: 25431 byte(s)
2005-04-11  Timo Schulz  <twoaday@freakmail.de>
 
        * wptClipSignEncDlg.cpp (clip_signenc_dlg_proc): Reset
        'enable' flag always at the begin.
        * wptClipDecryptDlg.cpp (clip_decrypt_dlg): Show correct
        key trust. Noted by a friendly user.
        * wptListView.cpp (listview_add_item_pos): New.
        * wptKeyEditDlgs.cpp (get_subkey_fingerprint): Due to
        the fact that GPG does not return the fingerprint of
        the generated subkey any longer, we need to get it manually.
        Thanks to Maxime Brandt.
        (keyedit_addsubkey_dlg_proc): If key size too large, ask
        if this was a mistake.
        (keyedit_add_subkey): Use it here.
        (do_add_new_subkey): Fix list contrl insertion.
        * wptTypes.h (DEFAULT_KEYSIZE): Define new default keysize constant.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26