Add a `peertag' slot to the `peerspec' structure stating which private
key to use; a null pointer means to use the default `tag_priv'. Add a
`p_privtag' function to retrieve the private key tag to use.
The ADD command now has a `-priv' option which sets this slot
appropriately. The `connect' service fetches a `priv' key. from the
database to set this option.
Used by
.BR connect (8).
.TP
Used by
.BR connect (8).
.TP
+.B priv
+Tag of the private key to use when communicating with the peer.
+.TP
.B raddr
Remote address for the tunnel interface to the peer. Used by
.BR tripe-ifup (8).
.B raddr
Remote address for the tunnel interface to the peer. Used by
.BR tripe-ifup (8).
return _simple(me.command(bg = True,
*['ADD'] +
_kwopts(kw, ['tunnel', 'keepalive',
return _simple(me.command(bg = True,
*['ADD'] +
_kwopts(kw, ['tunnel', 'keepalive',
- 'key', 'cork', 'mobile']) +
+ 'key', 'priv', 'cork',
+ 'mobile']) +
[peer] +
list(addr)))
def addr(me, peer):
[peer] +
list(addr)))
def addr(me, peer):
add = xmalloc(sizeof(*add));
add->peer.name = 0;
add->peer.tag = 0;
add = xmalloc(sizeof(*add));
add->peer.name = 0;
add->peer.tag = 0;
add->peer.t_ka = 0;
add->peer.tops = tun_default;
add->peer.f = 0;
add->peer.t_ka = 0;
add->peer.tops = tun_default;
add->peer.f = 0;
add->peer.tag = xstrdup(arg);
})
OPT("-mobile", { add->peer.f |= PSF_MOBILE; })
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 --- */
});
/* --- 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);
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);
if ((p = a_findpeer(a, av[0])) != 0) {
ps = p_spec(p);
a_info(a, "tunnel=%s", ps->tops->name, 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, "key=%s", p_tag(p),
+ "current-key=%s", p->kx.kpub->tag, A_END);
+ a_info(a, "private-key=%s", p_privtag(p),
+ "current-private-key=%s", p->kx.kpriv->tag, A_END);
a_info(a, "keepalive=%lu", ps->t_ka, A_END);
a_ok(a);
}
a_info(a, "keepalive=%lu", ps->t_ka, A_END);
a_ok(a);
}
int kx_init(keyexch *kx, peer *p, keyset **ks, unsigned f)
{
int kx_init(keyexch *kx, peer *p, keyset **ks, unsigned f)
{
- if ((kx->kpriv = km_findpriv(tag_priv)) == 0) goto fail_0;
+ if ((kx->kpriv = km_findpriv(p_privtag(p))) == 0) goto fail_0;
if ((kx->kpub = km_findpub(p_tag(p))) == 0) goto fail_1;
if ((kx->kpub = km_findpub(p_tag(p))) == 0) goto fail_1;
- if (!km_samealgsp(kx->kpriv, kx->kpub)) {
- a_warn("KX", "?PEER", kx->p, "algorithms-mismatch",
- "local-private-key", "%s", tag_priv,
+ if (!group_samep(kx->kpriv->g, kx->kpub->g)) {
+ a_warn("KX", "?PEER", kx->p, "group-mismatch",
+ "local-private-key", "%s", p_privtag(p),
"peer-public-key", "%s", p_tag(p),
A_END);
goto fail_2;
"peer-public-key", "%s", p_tag(p),
A_END);
goto fail_2;
static void p_keepalive(struct timeval *now, void *pv)
{
peer *p = pv;
static void p_keepalive(struct timeval *now, void *pv)
{
peer *p = pv;
p_txstart(p, MSG_MISC | MISC_NOP); p_dotxend(p);
T( trace(T_PEER, "peer: sent keepalive to %s", p->spec.name); )
p_setkatimer(p);
p_txstart(p, MSG_MISC | MISC_NOP); p_dotxend(p);
T( trace(T_PEER, "peer: sent keepalive to %s", p->spec.name); )
p_setkatimer(p);
T( trace(T_PEER, "peer: creating new peer `%s'", spec->name); )
p->spec = *spec;
p->spec.name = (/*unconst*/ char *)SYM_NAME(p->byname);
T( trace(T_PEER, "peer: creating new peer `%s'", spec->name); )
p->spec = *spec;
p->spec.name = (/*unconst*/ char *)SYM_NAME(p->byname);
- if (spec->tag)
- p->spec.tag = xstrdup(spec->tag);
+ if (spec->tag) p->spec.tag = xstrdup(spec->tag);
+ if (spec->privtag) p->spec.privtag = xstrdup(spec->privtag);
p->ks = 0;
p->pings = 0;
p->ifname = 0;
p->ks = 0;
p->pings = 0;
p->ifname = 0;
- if (spec->t_ka)
- sel_rmtimer(&p->tka);
+ if (spec->t_ka) sel_rmtimer(&p->tka);
xfree(p->ifname);
p->t->ops->destroy(p->t);
tidy_3:
xfree(p->ifname);
p->t->ops->destroy(p->t);
tidy_3:
tidy_2:
am_remove(&byaddr, p->byaddr);
if (p->spec.tag) xfree(p->spec.tag);
tidy_2:
am_remove(&byaddr, p->byaddr);
if (p->spec.tag) xfree(p->spec.tag);
+ if (p->spec.privtag) xfree(p->spec.privtag);
tidy_1:
sym_remove(&byname, p->byname);
tidy_0:
tidy_1:
sym_remove(&byname, p->byname);
tidy_0:
const char *p_tag(peer *p)
{ return (p->spec.tag ? p->spec.tag : p->spec.name); }
const char *p_tag(peer *p)
{ return (p->spec.tag ? p->spec.tag : p->spec.name); }
+/* --- @p_privtag@ --- *
+ *
+ * Arguments: @peer *p@ = pointer to a peer block
+ *
+ * Returns: A pointer to the peer's private key tag.
+ */
+
+const char *p_privtag(peer *p)
+ { return (p->spec.privtag ? p->spec.privtag : tag_priv); }
+
/* --- @p_spec@ --- *
*
* Arguments: @peer *p@ = pointer to a peer block
/* --- @p_spec@ --- *
*
* Arguments: @peer *p@ = pointer to a peer block
a_notify("KILL", "%s", p->spec.name, A_END);
ksl_free(&p->ks);
kx_free(&p->kx);
a_notify("KILL", "%s", p->spec.name, A_END);
ksl_free(&p->ks);
kx_free(&p->kx);
- if (p->spec.f & PSF_MOBILE)
- nmobile--;
- if (p->ifname)
- xfree(p->ifname);
- if (p->spec.tag)
- xfree(p->spec.tag);
+ if (p->spec.f & PSF_MOBILE) nmobile--;
+ if (p->ifname) xfree(p->ifname);
+ if (p->spec.tag) xfree(p->spec.tag);
+ if (p->spec.privtag) xfree(p->spec.privtag);
p->t->ops->destroy(p->t);
p->t->ops->destroy(p->t);
- if (p->spec.t_ka)
- sel_rmtimer(&p->tka);
+ if (p->spec.t_ka) sel_rmtimer(&p->tka);
for (pg = p->pings; pg; pg = ppg) {
ppg = pg->next;
p_pingdone(pg, PING_PEERDIED);
for (pg = p->pings; pg; pg = ppg) {
ppg = pg->next;
p_pingdone(pg, PING_PEERDIED);
-The key tag being used for the peer, as passed to the
+The (short) key tag being used for the peer, as passed to the
-command. (You don't get a full key-id, since that might change while
-the daemon's running.)
+command.
+.TP
+.B current-key
+The full key tag of the peer's public key currently being used. This
+may change during the life of the association.
+.TP
+.B private-key
+The private key tag being used for the peer, as passed to the
+.B ADD
+command.
+.TP
+.B current-private-key
+The full key tag of the private key currently being used for this
+association. This may change during the life of the association.
.RE
.SP
.BI "PING \fR[" options "\fR] " peer
.RE
.SP
.BI "PING \fR[" options "\fR] " peer
typedef struct peerspec {
char *name; /* Peer's name */
typedef struct peerspec {
char *name; /* Peer's name */
+ char *privtag; /* Private key tag */
char *tag; /* Public key tag */
const tunnel_ops *tops; /* Tunnel operations */
unsigned long t_ka; /* Keep alive interval */
char *tag; /* Public key tag */
const tunnel_ops *tops; /* Tunnel operations */
unsigned long t_ka; /* Keep alive interval */
extern const char *p_tag(peer */*p*/);
extern const char *p_tag(peer */*p*/);
+/* --- @p_privtag@ --- *
+ *
+ * Arguments: @peer *p@ = pointer to a peer block
+ *
+ * Returns: A pointer to the peer's private key tag.
+ */
+
+extern const char *p_privtag(peer */*p*/);
+
/* --- @p_spec@ --- *
*
* Arguments: @peer *p@ = pointer to a peer block
/* --- @p_spec@ --- *
*
* Arguments: @peer *p@ = pointer to a peer block
tunnel = peer.get('tunnel', None),
keepalive = peer.get('keepalive', None),
key = peer.get('key', None),
tunnel = peer.get('tunnel', None),
keepalive = peer.get('keepalive', None),
key = peer.get('key', None),
+ priv = peer.get('priv', None),
mobile = peer.get('mobile', 'nil') in booltrue,
cork = peer.get('cork', 'nil') in booltrue,
*addr)
mobile = peer.get('mobile', 'nil') in booltrue,
cork = peer.get('cork', 'nil') in booltrue,
*addr)