{ 'x', T_KEYEXCH, "key exchange" },
{ 'm', T_KEYMGMT, "key management" },
{ 'l', T_CHAL, "challenge management" },
+ { 'v', T_PRIVSEP, "privilege separation" },
{ 'p', T_PACKET, "packet contents" },
{ 'c', T_CRYPTO, "crypto details" },
{ 'A', T_ALL, "all of the above" },
while (fmt) {
if (*fmt == '*') {
- dstr_putc(d, ' ');
+ if (d->len) dstr_putc(d, ' ');
dstr_vputf(d, fmt + 1, &ap);
} else if (*fmt == '?') {
if (strcmp(fmt, "?ADDR") == 0) {
dstr_destroy(&dd);
}
+/* --- @a_format@ --- *
+ *
+ * Arguments: @dstr *d@ = where to leave the formatted message
+ * @const char *fmt@ = pointer to format string
+ *
+ * Returns: ---
+ *
+ * Use: Writes a tokenized message into a string, for later
+ * presentation.
+ */
+
+void a_format(dstr *d, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ a_vformat(d, fmt, ap);
+ va_end(ap);
+}
+
/* --- @a_write@, @a_vwrite@ --- *
*
* Arguments: @admin *a@ = admin connection to write to
close(sock.fd);
unlink(sockname);
FOREACH_PEER(p, { p_destroy(p); });
+ ps_quit();
exit(0);
}
a_bgok(&add->r.bg);
}
+ if (add->peer.tag) xfree(add->peer.tag);
xfree(add->peer.name);
}
add = xmalloc(sizeof(*add));
add->peer.name = 0;
+ add->peer.tag = 0;
add->peer.t_ka = 0;
add->peer.tops = tun_default;
- add->peer.kxf = 0;
+ add->peer.f = 0;
/* --- Parse options --- */
}
})
OPTTIME("-keepalive", t, { add->peer.t_ka = t; })
- OPT("-cork", { add->peer.kxf |= KXF_CORK; })
+ OPT("-cork", { add->peer.f |= KXF_CORK; })
+ OPTARG("-key", arg, {
+ if (add->peer.tag)
+ xfree(add->peer.tag);
+ add->peer.tag = xstrdup(arg);
+ })
+ OPT("-mobile", { add->peer.f |= PSF_MOBILE; })
});
/* --- Make sure someone's not got there already --- */
a_fail(a, "bad-syntax", "add", "[OPTIONS] PEER ADDR ...", A_END);
fail:
if (add->peer.name) xfree(add->peer.name);
+ if (add->peer.tag) xfree(add->peer.tag);
xfree(add);
return;
}
}
}
+static void acmd_algs(admin *a, unsigned ac, char *av[])
+{
+ a_info(a,
+ "kx-group=%s", gg->ops->name,
+ "kx-group-order-bits=%lu", (unsigned long)mp_bits(gg->r),
+ "kx-group-elt-bits=%lu", (unsigned long)gg->nbits,
+ A_END);
+ a_info(a,
+ "hash=%s", algs.h->name,
+ "mgf=%s", algs.mgf->name,
+ "hash-sz=%lu", (unsigned long)algs.h->hashsz,
+ A_END);
+ a_info(a,
+ "cipher=%s", algs.c->name,
+ "cipher-keysz=%lu", (unsigned long)algs.cksz,
+ "cipher-blksz=%lu", (unsigned long)algs.c->blksz,
+ A_END);
+ a_info(a,
+ "cipher-data-limit=%lu", (unsigned long)algs.expsz,
+ A_END);
+ a_info(a,
+ "mac=%s", algs.m->name,
+ "mac-keysz=%lu", (unsigned long)algs.mksz,
+ "mac-tagsz=%lu", (unsigned long)algs.tagsz,
+ A_END);
+ a_ok(a);
+}
+
static void acmd_list(admin *a, unsigned ac, char *av[])
{
FOREACH_PEER(p, { a_info(a, "%s", p_name(p), A_END); });
if ((p = a_findpeer(a, av[0])) != 0) {
ps = p_spec(p);
a_info(a, "tunnel=%s", ps->tops->name, A_END);
+ a_info(a, "key=%s", p_tag(p), A_END);
a_info(a, "keepalive=%lu", ps->t_ka, A_END);
a_ok(a);
}
static const acmd acmdtab[] = {
{ "add", "[OPTIONS] PEER ADDR ...", 2, 0xffff, acmd_add },
{ "addr", "PEER", 1, 1, acmd_addr },
+ { "algs", 0, 0, 0, acmd_algs },
{ "bgcancel", "TAG", 1, 1, acmd_bgcancel },
{ "checkchal", "CHAL", 1, 1, acmd_checkchal },
{ "daemon", 0, 0, 0, acmd_daemon },
* Arguments: @const char *name@ = socket name to create
* @uid_t u@ = user to own the socket
* @gid_t g@ = group to own the socket
+ * @mode_t m@ = permissions to set on the socket
*
* Returns: ---
*
* Use: Creates the admin listening socket.
*/
-void a_init(const char *name, uid_t u, gid_t g)
+void a_init(const char *name, uid_t u, gid_t g, mode_t m)
{
int fd;
int n = 5;
struct sockaddr_un sun;
struct sigaction sa;
size_t sz;
+ mode_t omask;
/* --- Create services table --- */
/* --- Attempt to bind to the socket --- */
- umask(0077);
+ omask = umask(0077);
again:
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
die(EXIT_FAILURE, "couldn't create socket: %s", strerror(errno));
close(fd);
goto again;
}
- chmod(sun.sun_path, 0600);
if (chown(sun.sun_path, u, g)) {
- T( trace(T_ADMIN,
- "admin: failed to give away socket: %s",
- strerror(errno)); )
+ die(EXIT_FAILURE, "failed to set socket owner: %s",
+ strerror(errno));
+ }
+ if (chmod(sun.sun_path, m)) {
+ die(EXIT_FAILURE, "failed to set socket permissions: %s",
+ strerror(errno));
}
+ umask(omask);
fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
if (listen(fd, 5))
die(EXIT_FAILURE, "couldn't listen on socket: %s", strerror(errno));