Line data Source code
1 : /* migrate.c - Migrate from earlier GnupG versions.
2 : * Copyright (C) 2014 Werner Koch
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * GnuPG is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * GnuPG 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
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <config.h>
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 : #include <string.h>
24 : #include <errno.h>
25 : #include <assert.h>
26 :
27 : #include "gpg.h"
28 : #include "options.h"
29 : #include "keydb.h"
30 : #include "util.h"
31 : #include "main.h"
32 : #include "call-agent.h"
33 :
34 :
35 : #ifdef HAVE_DOSISH_SYSTEM
36 : # define V21_MIGRATION_FNAME "gpg-v21-migrated"
37 : #else
38 : # define V21_MIGRATION_FNAME ".gpg-v21-migrated"
39 : #endif
40 :
41 :
42 : /* Check whether a default secring.gpg from GnuPG < 2.1 exists and
43 : import it if not yet done. */
44 : void
45 136 : migrate_secring (ctrl_t ctrl)
46 : {
47 136 : dotlock_t lockhd = NULL;
48 136 : char *secring = NULL;
49 136 : char *flagfile = NULL;
50 136 : char *agent_version = NULL;
51 :
52 136 : secring = make_filename (opt.homedir, "secring" EXTSEP_S "gpg", NULL);
53 136 : if (access (secring, F_OK))
54 136 : goto leave; /* Does not exist or is not readable. */
55 0 : flagfile = make_filename (opt.homedir, V21_MIGRATION_FNAME, NULL);
56 0 : if (!access (flagfile, F_OK))
57 0 : goto leave; /* Does exist - fine. */
58 :
59 0 : log_info ("starting migration from earlier GnuPG versions\n");
60 :
61 0 : lockhd = dotlock_create (flagfile, 0);
62 0 : if (!lockhd)
63 : {
64 0 : log_error ("can't allocate lock for '%s': %s\n",
65 : flagfile, gpg_strerror (gpg_error_from_syserror ()));
66 0 : goto leave;
67 : }
68 0 : if (dotlock_take (lockhd, -1))
69 : {
70 0 : log_error ("can't lock '%s': %s\n",
71 : flagfile, gpg_strerror (gpg_error_from_syserror ()));
72 0 : dotlock_destroy (lockhd);
73 0 : lockhd = NULL;
74 0 : goto leave;
75 : }
76 :
77 0 : if (!agent_get_version (ctrl, &agent_version))
78 : {
79 0 : if (!gnupg_compare_version (agent_version, "2.1.0"))
80 : {
81 0 : log_error ("error: GnuPG agent version \"%s\" is too old. ",
82 : agent_version);
83 0 : log_info ("Please make sure that a recent gpg-agent is running.\n");
84 0 : log_info ("(restarting the user session may achieve this.)\n");
85 0 : log_info ("migration aborted\n");
86 0 : xfree (agent_version);
87 0 : goto leave;
88 : }
89 0 : xfree (agent_version);
90 : }
91 : else
92 : {
93 0 : log_error ("error: GnuPG agent unusable. "
94 : "Please check that a GnuPG agent can be started.\n");
95 0 : log_error ("migration aborted\n");
96 0 : goto leave;
97 : }
98 :
99 0 : log_info ("porting secret keys from '%s' to gpg-agent\n", secring);
100 0 : if (!import_old_secring (ctrl, secring))
101 : {
102 0 : FILE *fp = fopen (flagfile, "w");
103 0 : if (!fp || fclose (fp))
104 0 : log_error ("error creating flag file '%s': %s\n",
105 : flagfile, gpg_strerror (gpg_error_from_syserror ()));
106 : else
107 0 : log_info ("migration succeeded\n");
108 : }
109 :
110 : leave:
111 136 : if (lockhd)
112 : {
113 0 : dotlock_release (lockhd);
114 0 : dotlock_destroy (lockhd);
115 : }
116 136 : xfree (flagfile);
117 136 : xfree (secring);
118 136 : }
|