chiark / gitweb /
doc: Extend dirmngr's --allow-version-check description
[gnupg2.git] / g13 / suspend.c
1 /* suspend.c - Suspend/Resume a crypto container
2  * Copyright (C) 2016 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 <https://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 <unistd.h>
26 #include <sys/stat.h>
27 #include <assert.h>
28
29 #include "g13.h"
30 #include "i18n.h"
31 #include "suspend.h"
32
33 #include "keyblob.h"
34 #include "backend.h"
35 #include "g13tuple.h"
36 #include "server.h"  /*(g13_keyblob_decrypt)*/
37
38
39
40 /* Suspend the container with name FILENAME.  */
41 gpg_error_t
42 g13_suspend_container (ctrl_t ctrl, const char *filename)
43 {
44   gpg_error_t err;
45   int needs_syshelp;
46
47   /* A quick check to see whether the container exists.  */
48   if (access (filename, R_OK))
49     return gpg_error_from_syserror ();
50
51   /* Decide whether we need to use the g13-syshelp because we can't
52      use lock files for them.  This is most likely the case for device
53      files; thus we test for this.  FIXME: The correct solution would
54      be to call g13-syshelp to match the file against the g13tab.  */
55   needs_syshelp = !strncmp (filename, "/dev/", 5);
56
57   if (!needs_syshelp)
58     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
59   else
60     err = be_suspend_container (ctrl, CONTTYPE_DM_CRYPT, filename);
61
62   return err;
63 }
64
65
66 /* Resume the container with name FILENAME.  */
67 gpg_error_t
68 g13_resume_container (ctrl_t ctrl, const char *filename)
69 {
70   gpg_error_t err;
71   int needs_syshelp;
72   void *enckeyblob = NULL;
73   size_t enckeybloblen;
74   void *keyblob = NULL;
75   size_t keybloblen;
76   tupledesc_t tuples = NULL;
77   size_t n;
78   const unsigned char *value;
79   int conttype;
80   char *mountpoint_buffer = NULL;
81
82   /* A quick check to see whether the container exists.  */
83   if (access (filename, R_OK))
84     return gpg_error_from_syserror ();
85
86   /* Decide whether we need to use the g13-syshelp because we can't
87      use lock files for them.  This is most likely the case for device
88      files; thus we test for this.  FIXME: The correct solution would
89      be to call g13-syshelp to match the file against the g13tab.  */
90   needs_syshelp = !strncmp (filename, "/dev/", 5);
91
92   if (!needs_syshelp)
93     {
94       err = gpg_error (GPG_ERR_NOT_SUPPORTED);
95       goto leave;
96     }
97
98   /* Read the encrypted keyblob.  */
99   /* Fixme: Should we move this to syshelp for dm-crypt or do we
100      assume that the encrypted device is world readable?  */
101   err = g13_keyblob_read (filename, &enckeyblob, &enckeybloblen);
102   if (err)
103     goto leave;
104
105   /* Decrypt that keyblob and store it in a tuple descriptor.  */
106   err = g13_keyblob_decrypt (ctrl, enckeyblob, enckeybloblen,
107                              &keyblob, &keybloblen);
108   if (err)
109     goto leave;
110   xfree (enckeyblob);
111   enckeyblob = NULL;
112
113   err = create_tupledesc (&tuples, keyblob, keybloblen);
114   if (!err)
115     keyblob = NULL;
116   else
117     {
118       if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
119         log_error ("unknown keyblob version\n");
120       goto leave;
121     }
122   if (opt.verbose)
123     dump_tupledesc (tuples);
124
125   value = find_tuple (tuples, KEYBLOB_TAG_CONTTYPE, &n);
126   if (!value || n != 2)
127     conttype = 0;
128   else
129     conttype = (value[0] << 8 | value[1]);
130   if (!be_is_supported_conttype (conttype))
131     {
132       log_error ("content type %d is not supported\n", conttype);
133       err = gpg_error (GPG_ERR_NOT_SUPPORTED);
134       goto leave;
135     }
136   err = be_resume_container (ctrl, conttype, filename, tuples);
137
138  leave:
139   destroy_tupledesc (tuples);
140   xfree (keyblob);
141   xfree (enckeyblob);
142   xfree (mountpoint_buffer);
143   return err;
144 }