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

Contents of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69 - (show annotations)
Sat Nov 5 12:28:12 2005 UTC (19 years, 3 months ago) by twoaday
File size: 25988 byte(s)
More minor fixes...

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26