Blame


1 4d5ee956 2022-07-02 jrick /*
2 4d5ee956 2022-07-02 jrick * Copyright (c) 2022 Josh Rickmar <jrick@zettaport.com>
3 4d5ee956 2022-07-02 jrick *
4 4d5ee956 2022-07-02 jrick * Permission to use, copy, modify, and distribute this software for any
5 4d5ee956 2022-07-02 jrick * purpose with or without fee is hereby granted, provided that the above
6 4d5ee956 2022-07-02 jrick * copyright notice and this permission notice appear in all copies.
7 4d5ee956 2022-07-02 jrick *
8 4d5ee956 2022-07-02 jrick * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 4d5ee956 2022-07-02 jrick * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 4d5ee956 2022-07-02 jrick * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 4d5ee956 2022-07-02 jrick * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 4d5ee956 2022-07-02 jrick * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 4d5ee956 2022-07-02 jrick * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 4d5ee956 2022-07-02 jrick * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 4d5ee956 2022-07-02 jrick */
16 4d5ee956 2022-07-02 jrick
17 4d5ee956 2022-07-02 jrick #include <sys/types.h>
18 4d5ee956 2022-07-02 jrick #include <sys/stat.h>
19 4d5ee956 2022-07-02 jrick #include <sys/socket.h>
20 4d5ee956 2022-07-02 jrick #include <sys/queue.h>
21 4d5ee956 2022-07-02 jrick #include <sys/wait.h>
22 4d5ee956 2022-07-02 jrick
23 4d5ee956 2022-07-02 jrick #include <stdlib.h>
24 4d5ee956 2022-07-02 jrick #include <stdio.h>
25 4d5ee956 2022-07-02 jrick #include <fcntl.h>
26 4d5ee956 2022-07-02 jrick #include <unistd.h>
27 4d5ee956 2022-07-02 jrick #include <string.h>
28 4d5ee956 2022-07-02 jrick #include <err.h>
29 4d5ee956 2022-07-02 jrick #include <assert.h>
30 4d5ee956 2022-07-02 jrick #include <sha1.h>
31 4d5ee956 2022-07-02 jrick
32 4d5ee956 2022-07-02 jrick #include "got_error.h"
33 4d5ee956 2022-07-02 jrick #include "got_date.h"
34 4d5ee956 2022-07-02 jrick #include "got_object.h"
35 4d5ee956 2022-07-02 jrick #include "got_opentemp.h"
36 4d5ee956 2022-07-02 jrick
37 4d5ee956 2022-07-02 jrick #include "got_sigs.h"
38 4d5ee956 2022-07-02 jrick
39 4d5ee956 2022-07-02 jrick #include "buf.h"
40 4d5ee956 2022-07-02 jrick
41 4d5ee956 2022-07-02 jrick #ifndef MIN
42 4d5ee956 2022-07-02 jrick #define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
43 4d5ee956 2022-07-02 jrick #endif
44 4d5ee956 2022-07-02 jrick
45 4d5ee956 2022-07-02 jrick #ifndef nitems
46 4d5ee956 2022-07-02 jrick #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
47 4d5ee956 2022-07-02 jrick #endif
48 4d5ee956 2022-07-02 jrick
49 4d5ee956 2022-07-02 jrick #ifndef GOT_TAG_PATH_SSH_KEYGEN
50 4d5ee956 2022-07-02 jrick #define GOT_TAG_PATH_SSH_KEYGEN "/usr/bin/ssh-keygen"
51 4d5ee956 2022-07-02 jrick #endif
52 4d5ee956 2022-07-02 jrick
53 4d5ee956 2022-07-02 jrick #ifndef GOT_TAG_PATH_SIGNIFY
54 4d5ee956 2022-07-02 jrick #define GOT_TAG_PATH_SIGNIFY "/usr/bin/signify"
55 4d5ee956 2022-07-02 jrick #endif
56 4d5ee956 2022-07-02 jrick
57 4d5ee956 2022-07-02 jrick const struct got_error *
58 4d5ee956 2022-07-02 jrick got_sigs_apply_unveil()
59 4d5ee956 2022-07-02 jrick {
60 4d5ee956 2022-07-02 jrick if (unveil(GOT_TAG_PATH_SSH_KEYGEN, "x") != 0) {
61 4d5ee956 2022-07-02 jrick return got_error_from_errno2("unveil",
62 4d5ee956 2022-07-02 jrick GOT_TAG_PATH_SSH_KEYGEN);
63 4d5ee956 2022-07-02 jrick }
64 4d5ee956 2022-07-02 jrick if (unveil(GOT_TAG_PATH_SIGNIFY, "x") != 0) {
65 4d5ee956 2022-07-02 jrick return got_error_from_errno2("unveil",
66 4d5ee956 2022-07-02 jrick GOT_TAG_PATH_SIGNIFY);
67 4d5ee956 2022-07-02 jrick }
68 4d5ee956 2022-07-02 jrick
69 4d5ee956 2022-07-02 jrick return NULL;
70 4d5ee956 2022-07-02 jrick }
71 4d5ee956 2022-07-02 jrick
72 4d5ee956 2022-07-02 jrick const struct got_error *
73 4d5ee956 2022-07-02 jrick got_sigs_sign_tag_ssh(pid_t *newpid, int *in_fd, int *out_fd,
74 4d5ee956 2022-07-02 jrick const char* key_file, int verbosity)
75 4d5ee956 2022-07-02 jrick {
76 4d5ee956 2022-07-02 jrick const struct got_error *error = NULL;
77 4d5ee956 2022-07-02 jrick int pid, in_pfd[2], out_pfd[2];
78 4d5ee956 2022-07-02 jrick const char* argv[11];
79 4d5ee956 2022-07-02 jrick int i = 0, j;
80 4d5ee956 2022-07-02 jrick
81 4d5ee956 2022-07-02 jrick *newpid = -1;
82 4d5ee956 2022-07-02 jrick *in_fd = -1;
83 4d5ee956 2022-07-02 jrick *out_fd = -1;
84 4d5ee956 2022-07-02 jrick
85 4d5ee956 2022-07-02 jrick argv[i++] = GOT_TAG_PATH_SSH_KEYGEN;
86 4d5ee956 2022-07-02 jrick argv[i++] = "-Y";
87 4d5ee956 2022-07-02 jrick argv[i++] = "sign";
88 4d5ee956 2022-07-02 jrick argv[i++] = "-f";
89 4d5ee956 2022-07-02 jrick argv[i++] = key_file;
90 4d5ee956 2022-07-02 jrick argv[i++] = "-n";
91 4d5ee956 2022-07-02 jrick argv[i++] = "git";
92 4d5ee956 2022-07-02 jrick if (verbosity <= 0) {
93 4d5ee956 2022-07-02 jrick argv[i++] = "-q";
94 4d5ee956 2022-07-02 jrick } else {
95 4d5ee956 2022-07-02 jrick /* ssh(1) allows up to 3 "-v" options. */
96 4d5ee956 2022-07-02 jrick for (j = 0; j < MIN(3, verbosity); j++)
97 4d5ee956 2022-07-02 jrick argv[i++] = "-v";
98 4d5ee956 2022-07-02 jrick }
99 4d5ee956 2022-07-02 jrick argv[i++] = NULL;
100 4d5ee956 2022-07-02 jrick assert(i <= nitems(argv));
101 4d5ee956 2022-07-02 jrick
102 c632297d 2022-07-03 jrick if (pipe(in_pfd) == -1)
103 c632297d 2022-07-03 jrick return got_error_from_errno("pipe");
104 c632297d 2022-07-03 jrick if (pipe(out_pfd) == -1)
105 c632297d 2022-07-03 jrick return got_error_from_errno("pipe");
106 4d5ee956 2022-07-02 jrick
107 4d5ee956 2022-07-02 jrick pid = fork();
108 4d5ee956 2022-07-02 jrick if (pid == -1) {
109 4d5ee956 2022-07-02 jrick error = got_error_from_errno("fork");
110 4d5ee956 2022-07-02 jrick close(in_pfd[0]);
111 4d5ee956 2022-07-02 jrick close(in_pfd[1]);
112 4d5ee956 2022-07-02 jrick close(out_pfd[0]);
113 4d5ee956 2022-07-02 jrick close(out_pfd[1]);
114 4d5ee956 2022-07-02 jrick return error;
115 4d5ee956 2022-07-02 jrick } else if (pid == 0) {
116 4d5ee956 2022-07-02 jrick if (close(in_pfd[1]) == -1)
117 4d5ee956 2022-07-02 jrick err(1, "close");
118 4d5ee956 2022-07-02 jrick if (close(out_pfd[1]) == -1)
119 4d5ee956 2022-07-02 jrick err(1, "close");
120 4d5ee956 2022-07-02 jrick if (dup2(in_pfd[0], 0) == -1)
121 4d5ee956 2022-07-02 jrick err(1, "dup2");
122 4d5ee956 2022-07-02 jrick if (dup2(out_pfd[0], 1) == -1)
123 4d5ee956 2022-07-02 jrick err(1, "dup2");
124 4d5ee956 2022-07-02 jrick if (execv(GOT_TAG_PATH_SSH_KEYGEN, (char **const)argv) == -1)
125 4d5ee956 2022-07-02 jrick err(1, "execv");
126 4d5ee956 2022-07-02 jrick abort(); /* not reached */
127 4d5ee956 2022-07-02 jrick }
128 4d5ee956 2022-07-02 jrick if (close(in_pfd[0]) == -1)
129 4d5ee956 2022-07-02 jrick return got_error_from_errno("close");
130 4d5ee956 2022-07-02 jrick if (close(out_pfd[0]) == -1)
131 4d5ee956 2022-07-02 jrick return got_error_from_errno("close");
132 4d5ee956 2022-07-02 jrick *newpid = pid;
133 4d5ee956 2022-07-02 jrick *in_fd = in_pfd[1];
134 4d5ee956 2022-07-02 jrick *out_fd = out_pfd[1];
135 4d5ee956 2022-07-02 jrick return NULL;
136 4d5ee956 2022-07-02 jrick }
137 4d5ee956 2022-07-02 jrick
138 4d5ee956 2022-07-02 jrick static char *
139 4d5ee956 2022-07-02 jrick signer_identity(const char *tagger)
140 4d5ee956 2022-07-02 jrick {
141 4d5ee956 2022-07-02 jrick char *lt, *gt;
142 4d5ee956 2022-07-02 jrick
143 4d5ee956 2022-07-02 jrick lt = strstr(tagger, " <");
144 4d5ee956 2022-07-02 jrick gt = strrchr(tagger, '>');
145 4d5ee956 2022-07-02 jrick if (lt && gt && lt+1 < gt)
146 4d5ee956 2022-07-02 jrick return strndup(lt+2, gt-lt-2);
147 4d5ee956 2022-07-02 jrick return NULL;
148 4d5ee956 2022-07-02 jrick }
149 4d5ee956 2022-07-02 jrick
150 4d5ee956 2022-07-02 jrick static const char* BEGIN_SSH_SIG = "-----BEGIN SSH SIGNATURE-----\n";
151 4d5ee956 2022-07-02 jrick static const char* END_SSH_SIG = "-----END SSH SIGNATURE-----\n";
152 4d5ee956 2022-07-02 jrick
153 4d5ee956 2022-07-02 jrick const char *
154 4d5ee956 2022-07-02 jrick got_sigs_get_tagmsg_ssh_signature(const char *tagmsg)
155 4d5ee956 2022-07-02 jrick {
156 4d5ee956 2022-07-02 jrick const char *s = tagmsg, *begin = NULL, *end = NULL;
157 4d5ee956 2022-07-02 jrick
158 4d5ee956 2022-07-02 jrick while ((s = strstr(s, BEGIN_SSH_SIG)) != NULL) {
159 4d5ee956 2022-07-02 jrick begin = s;
160 4d5ee956 2022-07-02 jrick s += strlen(BEGIN_SSH_SIG);
161 4d5ee956 2022-07-02 jrick }
162 4d5ee956 2022-07-02 jrick if (begin)
163 4d5ee956 2022-07-02 jrick end = strstr(begin+strlen(BEGIN_SSH_SIG), END_SSH_SIG);
164 4d5ee956 2022-07-02 jrick if (end == NULL)
165 4d5ee956 2022-07-02 jrick return NULL;
166 4d5ee956 2022-07-02 jrick return (end[strlen(END_SSH_SIG)] == '\0') ? begin : NULL;
167 4d5ee956 2022-07-02 jrick }
168 4d5ee956 2022-07-02 jrick
169 4d5ee956 2022-07-02 jrick static const struct got_error *
170 4d5ee956 2022-07-02 jrick got_tag_write_signed_data(BUF *buf, struct got_tag_object *tag,
171 4d5ee956 2022-07-02 jrick const char *start_sig)
172 4d5ee956 2022-07-02 jrick {
173 4d5ee956 2022-07-02 jrick const struct got_error *err = NULL;
174 4d5ee956 2022-07-02 jrick struct got_object_id *id;
175 4d5ee956 2022-07-02 jrick char *id_str = NULL;
176 4d5ee956 2022-07-02 jrick char *tagger = NULL;
177 4d5ee956 2022-07-02 jrick const char *tagmsg;
178 4d5ee956 2022-07-02 jrick char gmtoff[6];
179 4d5ee956 2022-07-02 jrick size_t len;
180 4d5ee956 2022-07-02 jrick
181 4d5ee956 2022-07-02 jrick id = got_object_tag_get_object_id(tag);
182 4d5ee956 2022-07-02 jrick err = got_object_id_str(&id_str, id);
183 4d5ee956 2022-07-02 jrick if (err)
184 4d5ee956 2022-07-02 jrick goto done;
185 4d5ee956 2022-07-02 jrick
186 4d5ee956 2022-07-02 jrick const char *type_label = NULL;
187 4d5ee956 2022-07-02 jrick switch (got_object_tag_get_object_type(tag)) {
188 4d5ee956 2022-07-02 jrick case GOT_OBJ_TYPE_BLOB:
189 4d5ee956 2022-07-02 jrick type_label = GOT_OBJ_LABEL_BLOB;
190 4d5ee956 2022-07-02 jrick break;
191 4d5ee956 2022-07-02 jrick case GOT_OBJ_TYPE_TREE:
192 4d5ee956 2022-07-02 jrick type_label = GOT_OBJ_LABEL_TREE;
193 4d5ee956 2022-07-02 jrick break;
194 4d5ee956 2022-07-02 jrick case GOT_OBJ_TYPE_COMMIT:
195 4d5ee956 2022-07-02 jrick type_label = GOT_OBJ_LABEL_COMMIT;
196 4d5ee956 2022-07-02 jrick break;
197 4d5ee956 2022-07-02 jrick case GOT_OBJ_TYPE_TAG:
198 4d5ee956 2022-07-02 jrick type_label = GOT_OBJ_LABEL_TAG;
199 4d5ee956 2022-07-02 jrick break;
200 4d5ee956 2022-07-02 jrick default:
201 4d5ee956 2022-07-02 jrick break;
202 4d5ee956 2022-07-02 jrick }
203 4d5ee956 2022-07-02 jrick got_date_format_gmtoff(gmtoff, sizeof(gmtoff),
204 4d5ee956 2022-07-02 jrick got_object_tag_get_tagger_gmtoff(tag));
205 4d5ee956 2022-07-02 jrick if (asprintf(&tagger, "%s %lld %s", got_object_tag_get_tagger(tag),
206 4d5ee956 2022-07-02 jrick got_object_tag_get_tagger_time(tag), gmtoff) == -1) {
207 4d5ee956 2022-07-02 jrick err = got_error_from_errno("asprintf");
208 4d5ee956 2022-07-02 jrick goto done;
209 4d5ee956 2022-07-02 jrick }
210 4d5ee956 2022-07-02 jrick
211 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, GOT_TAG_LABEL_OBJECT);
212 4d5ee956 2022-07-02 jrick if (err)
213 4d5ee956 2022-07-02 jrick goto done;
214 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, id_str);
215 4d5ee956 2022-07-02 jrick if (err)
216 4d5ee956 2022-07-02 jrick goto done;
217 4d5ee956 2022-07-02 jrick err = buf_putc(buf, '\n');
218 4d5ee956 2022-07-02 jrick if (err)
219 4d5ee956 2022-07-02 jrick goto done;
220 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, GOT_TAG_LABEL_TYPE);
221 4d5ee956 2022-07-02 jrick if (err)
222 4d5ee956 2022-07-02 jrick goto done;
223 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, type_label);
224 4d5ee956 2022-07-02 jrick if (err)
225 4d5ee956 2022-07-02 jrick goto done;
226 4d5ee956 2022-07-02 jrick err = buf_putc(buf, '\n');
227 4d5ee956 2022-07-02 jrick if (err)
228 4d5ee956 2022-07-02 jrick goto done;
229 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, GOT_TAG_LABEL_TAG);
230 4d5ee956 2022-07-02 jrick if (err)
231 4d5ee956 2022-07-02 jrick goto done;
232 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, got_object_tag_get_name(tag));
233 4d5ee956 2022-07-02 jrick if (err)
234 4d5ee956 2022-07-02 jrick goto done;
235 4d5ee956 2022-07-02 jrick err = buf_putc(buf, '\n');
236 4d5ee956 2022-07-02 jrick if (err)
237 4d5ee956 2022-07-02 jrick goto done;
238 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, GOT_TAG_LABEL_TAGGER);
239 4d5ee956 2022-07-02 jrick if (err)
240 4d5ee956 2022-07-02 jrick goto done;
241 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, tagger);
242 4d5ee956 2022-07-02 jrick if (err)
243 4d5ee956 2022-07-02 jrick goto done;
244 4d5ee956 2022-07-02 jrick err = buf_puts(&len, buf, "\n");
245 4d5ee956 2022-07-02 jrick if (err)
246 4d5ee956 2022-07-02 jrick goto done;
247 4d5ee956 2022-07-02 jrick tagmsg = got_object_tag_get_message(tag);
248 4d5ee956 2022-07-02 jrick err = buf_append(&len, buf, tagmsg, start_sig-tagmsg);
249 4d5ee956 2022-07-02 jrick if (err)
250 4d5ee956 2022-07-02 jrick goto done;
251 4d5ee956 2022-07-02 jrick
252 4d5ee956 2022-07-02 jrick done:
253 4d5ee956 2022-07-02 jrick free(id_str);
254 4d5ee956 2022-07-02 jrick free(tagger);
255 4d5ee956 2022-07-02 jrick return err;
256 4d5ee956 2022-07-02 jrick }
257 4d5ee956 2022-07-02 jrick
258 4d5ee956 2022-07-02 jrick const struct got_error *
259 4d5ee956 2022-07-02 jrick got_sigs_verify_tag_ssh(char **msg, struct got_tag_object *tag,
260 4d5ee956 2022-07-02 jrick const char *start_sig, const char* allowed_signers, const char* revoked,
261 4d5ee956 2022-07-02 jrick int verbosity)
262 4d5ee956 2022-07-02 jrick {
263 4d5ee956 2022-07-02 jrick const struct got_error *error = NULL;
264 4d5ee956 2022-07-02 jrick const char* argv[17];
265 4d5ee956 2022-07-02 jrick int pid, status, in_pfd[2], out_pfd[2];
266 4d5ee956 2022-07-02 jrick char* parsed_identity = NULL;
267 4d5ee956 2022-07-02 jrick const char *identity;
268 4d5ee956 2022-07-02 jrick char* tmppath = NULL;
269 4d5ee956 2022-07-02 jrick FILE *tmpsig, *out = NULL;
270 4d5ee956 2022-07-02 jrick BUF *buf;
271 4d5ee956 2022-07-02 jrick int i = 0, j;
272 4d5ee956 2022-07-02 jrick
273 4d5ee956 2022-07-02 jrick *msg = NULL;
274 4d5ee956 2022-07-02 jrick
275 4d5ee956 2022-07-02 jrick error = got_opentemp_named(&tmppath, &tmpsig,
276 4d5ee956 2022-07-02 jrick GOT_TMPDIR_STR "/got-tagsig");
277 4d5ee956 2022-07-02 jrick if (error)
278 4d5ee956 2022-07-02 jrick goto done;
279 4d5ee956 2022-07-02 jrick
280 4d5ee956 2022-07-02 jrick identity = got_object_tag_get_tagger(tag);
281 4d5ee956 2022-07-02 jrick parsed_identity = signer_identity(identity);
282 4d5ee956 2022-07-02 jrick if (parsed_identity != NULL)
283 4d5ee956 2022-07-02 jrick identity = parsed_identity;
284 4d5ee956 2022-07-02 jrick
285 4d5ee956 2022-07-02 jrick if (fputs(start_sig, tmpsig) == EOF) {
286 4d5ee956 2022-07-02 jrick error = got_error_from_errno("fputs");
287 4d5ee956 2022-07-02 jrick goto done;
288 4d5ee956 2022-07-02 jrick }
289 4d5ee956 2022-07-02 jrick if (fflush(tmpsig) == EOF) {
290 4d5ee956 2022-07-02 jrick error = got_error_from_errno("fflush");
291 4d5ee956 2022-07-02 jrick goto done;
292 4d5ee956 2022-07-02 jrick }
293 4d5ee956 2022-07-02 jrick
294 4d5ee956 2022-07-02 jrick error = buf_alloc(&buf, 0);
295 4d5ee956 2022-07-02 jrick if (error)
296 4d5ee956 2022-07-02 jrick goto done;
297 4d5ee956 2022-07-02 jrick error = got_tag_write_signed_data(buf, tag, start_sig);
298 4d5ee956 2022-07-02 jrick if (error)
299 4d5ee956 2022-07-02 jrick goto done;
300 4d5ee956 2022-07-02 jrick
301 4d5ee956 2022-07-02 jrick argv[i++] = GOT_TAG_PATH_SSH_KEYGEN;
302 4d5ee956 2022-07-02 jrick argv[i++] = "-Y";
303 4d5ee956 2022-07-02 jrick argv[i++] = "verify";
304 4d5ee956 2022-07-02 jrick argv[i++] = "-f";
305 4d5ee956 2022-07-02 jrick argv[i++] = allowed_signers;
306 4d5ee956 2022-07-02 jrick argv[i++] = "-I";
307 4d5ee956 2022-07-02 jrick argv[i++] = identity;
308 4d5ee956 2022-07-02 jrick argv[i++] = "-n";
309 4d5ee956 2022-07-02 jrick argv[i++] = "git";
310 4d5ee956 2022-07-02 jrick argv[i++] = "-s";
311 4d5ee956 2022-07-02 jrick argv[i++] = tmppath;
312 4d5ee956 2022-07-02 jrick if (revoked) {
313 4d5ee956 2022-07-02 jrick argv[i++] = "-r";
314 4d5ee956 2022-07-02 jrick argv[i++] = revoked;
315 4d5ee956 2022-07-02 jrick }
316 4d5ee956 2022-07-02 jrick if (verbosity > 0) {
317 4d5ee956 2022-07-02 jrick /* ssh(1) allows up to 3 "-v" options. */
318 4d5ee956 2022-07-02 jrick for (j = 0; j < MIN(3, verbosity); j++)
319 4d5ee956 2022-07-02 jrick argv[i++] = "-v";
320 4d5ee956 2022-07-02 jrick }
321 4d5ee956 2022-07-02 jrick argv[i++] = NULL;
322 4d5ee956 2022-07-02 jrick assert(i <= nitems(argv));
323 4d5ee956 2022-07-02 jrick
324 c632297d 2022-07-03 jrick if (pipe(in_pfd) == -1) {
325 c632297d 2022-07-03 jrick error = got_error_from_errno("pipe");
326 4d5ee956 2022-07-02 jrick goto done;
327 4d5ee956 2022-07-02 jrick }
328 c632297d 2022-07-03 jrick if (pipe(out_pfd) == -1) {
329 c632297d 2022-07-03 jrick error = got_error_from_errno("pipe");
330 4d5ee956 2022-07-02 jrick goto done;
331 4d5ee956 2022-07-02 jrick }
332 4d5ee956 2022-07-02 jrick
333 4d5ee956 2022-07-02 jrick pid = fork();
334 4d5ee956 2022-07-02 jrick if (pid == -1) {
335 4d5ee956 2022-07-02 jrick error = got_error_from_errno("fork");
336 4d5ee956 2022-07-02 jrick close(in_pfd[0]);
337 4d5ee956 2022-07-02 jrick close(in_pfd[1]);
338 4d5ee956 2022-07-02 jrick close(out_pfd[0]);
339 4d5ee956 2022-07-02 jrick close(out_pfd[1]);
340 4d5ee956 2022-07-02 jrick return error;
341 4d5ee956 2022-07-02 jrick } else if (pid == 0) {
342 4d5ee956 2022-07-02 jrick if (close(in_pfd[1]) == -1)
343 4d5ee956 2022-07-02 jrick err(1, "close");
344 4d5ee956 2022-07-02 jrick if (close(out_pfd[1]) == -1)
345 4d5ee956 2022-07-02 jrick err(1, "close");
346 4d5ee956 2022-07-02 jrick if (dup2(in_pfd[0], 0) == -1)
347 4d5ee956 2022-07-02 jrick err(1, "dup2");
348 4d5ee956 2022-07-02 jrick if (dup2(out_pfd[0], 1) == -1)
349 4d5ee956 2022-07-02 jrick err(1, "dup2");
350 4d5ee956 2022-07-02 jrick if (execv(GOT_TAG_PATH_SSH_KEYGEN, (char **const)argv) == -1)
351 4d5ee956 2022-07-02 jrick err(1, "execv");
352 4d5ee956 2022-07-02 jrick abort(); /* not reached */
353 4d5ee956 2022-07-02 jrick }
354 4d5ee956 2022-07-02 jrick if (close(in_pfd[0]) == -1) {
355 4d5ee956 2022-07-02 jrick error = got_error_from_errno("close");
356 4d5ee956 2022-07-02 jrick goto done;
357 4d5ee956 2022-07-02 jrick }
358 4d5ee956 2022-07-02 jrick if (close(out_pfd[0]) == -1) {
359 4d5ee956 2022-07-02 jrick error = got_error_from_errno("close");
360 4d5ee956 2022-07-02 jrick goto done;
361 4d5ee956 2022-07-02 jrick }
362 4d5ee956 2022-07-02 jrick if (buf_write_fd(buf, in_pfd[1]) == -1) {
363 4d5ee956 2022-07-02 jrick error = got_error_from_errno("write");
364 4d5ee956 2022-07-02 jrick goto done;
365 4d5ee956 2022-07-02 jrick }
366 4d5ee956 2022-07-02 jrick if (close(in_pfd[1]) == -1) {
367 4d5ee956 2022-07-02 jrick error = got_error_from_errno("close");
368 4d5ee956 2022-07-02 jrick goto done;
369 4d5ee956 2022-07-02 jrick }
370 4d5ee956 2022-07-02 jrick if (waitpid(pid, &status, 0) == -1) {
371 4d5ee956 2022-07-02 jrick error = got_error_from_errno("waitpid");
372 4d5ee956 2022-07-02 jrick goto done;
373 4d5ee956 2022-07-02 jrick }
374 4d5ee956 2022-07-02 jrick if (!WIFEXITED(status)) {
375 4d5ee956 2022-07-02 jrick error = got_error(GOT_ERR_BAD_TAG_SIGNATURE);
376 4d5ee956 2022-07-02 jrick goto done;
377 4d5ee956 2022-07-02 jrick }
378 4d5ee956 2022-07-02 jrick
379 4d5ee956 2022-07-02 jrick out = fdopen(out_pfd[1], "r");
380 4d5ee956 2022-07-02 jrick if (out == NULL) {
381 4d5ee956 2022-07-02 jrick error = got_error_from_errno("fdopen");
382 4d5ee956 2022-07-02 jrick goto done;
383 4d5ee956 2022-07-02 jrick }
384 4d5ee956 2022-07-02 jrick error = buf_load(&buf, out);
385 4d5ee956 2022-07-02 jrick if (error)
386 4d5ee956 2022-07-02 jrick goto done;
387 4d5ee956 2022-07-02 jrick error = buf_putc(buf, '\0');
388 4d5ee956 2022-07-02 jrick if (error)
389 4d5ee956 2022-07-02 jrick goto done;
390 4d5ee956 2022-07-02 jrick if (close(out_pfd[1]) == -1) {
391 4d5ee956 2022-07-02 jrick error = got_error_from_errno("close");
392 4d5ee956 2022-07-02 jrick goto done;
393 4d5ee956 2022-07-02 jrick }
394 4d5ee956 2022-07-02 jrick out = NULL;
395 4d5ee956 2022-07-02 jrick *msg = buf_get(buf);
396 4d5ee956 2022-07-02 jrick if (WEXITSTATUS(status) != 0)
397 4d5ee956 2022-07-02 jrick error = got_error(GOT_ERR_BAD_TAG_SIGNATURE);
398 4d5ee956 2022-07-02 jrick
399 4d5ee956 2022-07-02 jrick done:
400 4d5ee956 2022-07-02 jrick free(parsed_identity);
401 4d5ee956 2022-07-02 jrick free(tmppath);
402 4d5ee956 2022-07-02 jrick if (tmpsig && fclose(tmpsig) == EOF && error == NULL)
403 4d5ee956 2022-07-02 jrick error = got_error_from_errno("fclose");
404 4d5ee956 2022-07-02 jrick if (out && fclose(out) == EOF && error == NULL)
405 4d5ee956 2022-07-02 jrick error = got_error_from_errno("fclose");
406 4d5ee956 2022-07-02 jrick return error;
407 4d5ee956 2022-07-02 jrick }