Blame


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