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
add = xmalloc(sizeof(*add));
add->peer.name = 0;
add->peer.tag = 0;
+ add->peer.privtag = 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; })
+ OPTARG("-priv", arg, {
+ if (add->peer.privtag)
+ xfree(add->peer.privtag);
+ add->peer.privtag = xstrdup(arg);
+ })
});
/* --- Make sure someone's not got there already --- */
fail:
if (add->peer.name) xfree(add->peer.name);
if (add->peer.tag) xfree(add->peer.tag);
+ if (add->peer.privtag) xfree(add->peer.privtag);
xfree(add);
return;
}
static void acmd_algs(admin *a, unsigned ac, char *av[])
{
+ peer *p;
+ const kdata *kd;
+ const group *g;
+ const algswitch *algs;
+
+ if (!ac)
+ kd = master;
+ else {
+ if ((p = a_findpeer(a, av[0])) == 0) return;
+ kd = p->kx.kpriv;
+ }
+ g = kd->g;
+ algs = &kd->algs;
+
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,
+ "kx-group=%s", g->ops->name,
+ "kx-group-order-bits=%lu", (unsigned long)mp_bits(g->r),
+ "kx-group-elt-bits=%lu", (unsigned long)g->nbits,
A_END);
a_info(a,
- "hash=%s", algs.h->name,
- "mgf=%s", algs.mgf->name,
- "hash-sz=%lu", (unsigned long)algs.h->hashsz,
+ "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,
+ "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,
+ "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,
+ "mac=%s", algs->m->name,
+ "mac-keysz=%lu", (unsigned long)algs->mksz,
+ "mac-tagsz=%lu", (unsigned long)algs->tagsz,
A_END);
a_ok(a);
}
{
peer *p;
const peerspec *ps;
+ const char *ptag;
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, "key=%s", p_tag(p),
+ "current-key=%s", p->kx.kpub->tag, A_END);
+ if ((ptag = p_privtag(p)) == 0) ptag = "(default)";
+ a_info(a, "private-key=%s", ptag,
+ "current-private-key=%s", p->kx.kpriv->tag, 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 },
+ { "algs", "[PEER]", 0, 1, 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;
close(fd);
goto again;
}
- if (chmod(sun.sun_path, 0600)) {
- die(EXIT_FAILURE, "failed to set socket permissions: %s",
- strerror(errno));
- }
if (chown(sun.sun_path, u, g)) {
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))