/* $Id: chngproc.c,v 1.12 2017/01/24 13:32:55 jsing Exp $ */ /* * Copyright (c) 2016 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #include "extern.h" #ifdef __VMS #include "wcme_config.h" #include "vms.h" #endif int chngproc(int netsock, const char *root) { char *tok = NULL, *th = NULL, *fmt = NULL, **fs = NULL; size_t i, fsz = 0; int rc = 0, fd = -1, cc; long lval; enum chngop op; void *pp; #ifdef WCME_DBG_CHNGPROC doddbg ("(%d) %d %s", __LINE__, netsock, root); #endif #ifndef WCME_IDIOM if (chroot(root) == -1) { warn("chroot"); goto out; } if (chdir("/") == -1) { warn("chdir"); goto out; } #endif if (pledge("stdio cpath wpath", NULL) == -1) { warn("pledge"); goto out; } /* * Loop while we wait to get a thumbprint and token. * We'll get this for each SAN request. */ for (;;) { op = CHNG__MAX; if ((lval = readop(netsock, COMM_CHNG_OP)) == 0) op = CHNG_STOP; else if (lval == CHNG_SYN) op = lval; if (op == CHNG__MAX) { warnx("unknown operation from netproc"); goto out; } else if (op == CHNG_STOP) break; assert(op == CHNG_SYN); /* * Read the thumbprint and token. * The token is the filename, so store that in a vector * of tokens that we'll later clean up. */ if ((th = readstr(netsock, COMM_THUMB)) == NULL) goto out; else if ((tok = readstr(netsock, COMM_TOK)) == NULL) goto out; /* Vector appending... */ #ifndef __VMS pp = reallocarray(fs, (fsz + 1), sizeof(char *)); #else pp = (void*)reallocarray(fs, (fsz + 1), sizeof(char *)); #endif if (pp == NULL) { warn("realloc"); goto out; } fs = pp; fs[fsz] = tok; tok = NULL; fsz++; if (asprintf(&fmt, "%s.%s", fs[fsz - 1], th) == -1) { warn("asprintf"); goto out; } /* * Create and write to our challenge file. * Note: we use file descriptors instead of FILE * because we want to minimise our pledges. */ #ifndef WCME_IDIOM fd = open(fs[fsz - 1], O_WRONLY|O_EXCL|O_CREAT, 0444); #else { char *sptr; /* WCME confines to ODS-2 semantics */ fd = open((sptr = UtilOds2FileName((char*)root,fs[fsz-1],NULL)), /* use 0777 to propagate protections */ O_WRONLY|O_TRUNC|O_CREAT, 0777); free (sptr); #ifdef WCME_DBG_CHNGPROC doddbg ("(%d) %d %%X%08.08x %d %s", __LINE__, fd, vaxc$errno, errno, strerror(errno)); #endif } #endif if (fd == -1) { warn("%s", fs[fsz - 1]); goto out; } if (write(fd, fmt, strlen(fmt)) == -1) { warn("%s", fs[fsz - 1]); goto out; } else if (close(fd) == -1) { warn("%s", fs[fsz - 1]); goto out; } fd = -1; free(th); free(fmt); th = fmt = NULL; dodbg("%s/%s: created", root, fs[fsz - 1]); /* * Write our acknowledgement. * Ignore reader failure. */ cc = writeop(netsock, COMM_CHNG_ACK, CHNG_ACK); if (cc == 0) break; if (cc < 0) goto out; } rc = 1; out: close(netsock); if (fd != -1) close(fd); for (i = 0; i < fsz; i++) { if (unlink(fs[i]) == -1 && errno != ENOENT) warn("%s", fs[i]); free(fs[i]); } free(fs); free(fmt); free(th); free(tok); return rc; }