}
}
+static uint32_t slog_start(struct site *st, uint32_t event)
+{
+ uint32_t class=event_log_priority(st, event);
+ if (class) {
+ slilog_part(st->log,class,"%s: ",st->tunname);
+ }
+ return class;
+}
+
static void vslog(struct site *st, uint32_t event, cstring_t msg, va_list ap)
FORMAT(printf,3,0);
static void vslog(struct site *st, uint32_t event, cstring_t msg, va_list ap)
{
uint32_t class;
- class=event_log_priority(st, event);
+ class=slog_start(st,event);
if (class) {
- slilog_part(st->log,class,"%s: ",st->tunname);
vslilog_part(st->log,class,msg,ap);
slilog_part(st->log,class,"\n");
}
/* Build any of msg1 to msg4. msg5 and msg6 are built from the inside
out using a transform of config data supplied by netlink */
-static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what)
+static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what,
+ const struct msg *prompt
+ /* may be 0 for MSG1 */)
{
string_t dhpub;
unsigned minor;
return False;
}
-static bool_t generate_msg1(struct site *st)
+static bool_t kex_init(struct site *st)
{
st->random->generate(st->random->st,NONCELEN,st->localN);
- return generate_msg(st,LABEL_MSG1,"site:MSG1");
+ return True;
+}
+
+static bool_t generate_msg1(struct site *st, const struct msg *prompt_maybe_0)
+{
+ return
+ generate_msg(st,LABEL_MSG1,"site:MSG1",prompt_maybe_0);
}
static bool_t process_msg1(struct site *st, struct buffer_if *msg1,
return True;
}
-static bool_t generate_msg2(struct site *st)
+static bool_t generate_msg2(struct site *st,
+ const struct msg *prompt_may_be_null)
{
- st->random->generate(st->random->st,NONCELEN,st->localN);
- return generate_msg(st,LABEL_MSG2,"site:MSG2");
+ return
+ generate_msg(st,LABEL_MSG2,"site:MSG2",prompt_may_be_null);
}
static bool_t process_msg2(struct site *st, struct buffer_if *msg2,
return True;
}
-static bool_t generate_msg3(struct site *st)
+static bool_t generate_msg3(struct site *st, const struct msg *prompt)
{
/* Now we have our nonce and their nonce. Think of a secret key,
and create message number 3. */
(st->remote_capabilities & CAPAB_TRANSFORM_MASK)
? LABEL_MSG3BIS
: LABEL_MSG3,
- "site:MSG3");
+ "site:MSG3",prompt);
}
static bool_t process_msg3_msg4(struct site *st, struct msg *m)
return True;
}
-static bool_t generate_msg4(struct site *st)
+static bool_t generate_msg4(struct site *st, const struct msg *prompt)
{
/* We have both nonces, their public key and our private key. Generate
our public key, sign it and send it to them. */
- return generate_msg(st,LABEL_MSG4,"site:MSG4");
+ return generate_msg(st,LABEL_MSG4,"site:MSG4",prompt);
}
static bool_t process_msg4(struct site *st, struct buffer_if *msg4,
/* Leaves transformed part of buffer untouched */
}
-static bool_t generate_msg5(struct site *st)
+static bool_t generate_msg5(struct site *st, const struct msg *prompt)
{
cstring_t transform_err;
buf_prepend_uint32(&st->buffer,session_id);
}
-static bool_t generate_msg6(struct site *st)
+static bool_t generate_msg6(struct site *st, const struct msg *prompt)
{
if (!is_transform_valid(st->new_transform))
return False;
const struct msg *prompt
/* may be 0 for SENTMSG1 */)
{
- bool_t (*gen)(struct site *st, struct msg *prompt);
+ bool_t (*gen)(struct site *st, const struct msg *prompt);
int r;
slog(st,LOG_STATE,"entering state %s",state_name(next));
switch(next) {
case SITE_SENTMSG1:
state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE);
+ if (!kex_init(st)) return False;
gen=generate_msg1;
st->msg1_crossed_logged = False;
break;
case SITE_SENTMSG2:
state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE ||
st->state==SITE_SENTMSG1 || st->state==SITE_WAIT);
+ if (!kex_init(st)) return False;
gen=generate_msg2;
break;
case SITE_SENTMSG3:
if (hacky_par_start_failnow()) return False;
- r= gen(st) && send_msg(st);
+ r= gen(st,prompt) && send_msg(st);
hacky_par_end(&r,
st->setup_retries, st->setup_retry_interval,
}
static bool_t named_for_us(struct site *st, const struct buffer_if *buf_in,
- uint32_t type, struct msg *m)
+ uint32_t type, struct msg *m,
+ struct priomsg *whynot)
/* For packets which are identified by the local and remote names.
* If it has our name and our peer's name in it it's for us. */
{
struct buffer_if buf[1];
buffer_readonly_clone(buf,buf_in);
- return unpick_msg(st,type,buf,m)
- && name_matches(&m->remote,st->remotename)
- && name_matches(&m->local,st->localname);
+
+ if (!unpick_msg(st,type,buf,m)) {
+ priomsg_update_fixed(whynot, comm_notify_whynot_unpick, "malformed");
+ return False;
+ }
+#define NAME_MATCHES(lr) \
+ if (!name_matches(&m->lr, st->lr##name)) { \
+ if (priomsg_update_fixed(whynot, comm_notify_whynot_name_##lr, \
+ "unknown " #lr " name: ")) { \
+ truncmsg_add_packet_string(&whynot->m, m->lr.len, m->lr.name); \
+ } \
+ return False; \
+ }
+ NAME_MATCHES(remote);
+ NAME_MATCHES(local );
+#undef NAME_MATCHES
+
+ return True;
}
static bool_t we_have_priority(struct site *st, const struct msg *m) {
* late. Maybe they came via a different path. All we do is make
* a note of the sending address, iff they look like they are part
* of the current key setup attempt. */
- if (!named_for_us(st,buf_in,msgtype,m))
+ if (!named_for_us(st,buf_in,msgtype,m,0))
/* named_for_us calls unpick_msg which gets the nonces */
return False;
if (!consttime_memeq(m->nR,st->remoteN,NONCELEN) ||
this current site instance (and should therefore not be processed
by other sites), even if the packet was otherwise ignored. */
static bool_t site_incoming(void *sst, struct buffer_if *buf,
- const struct comm_addr *source)
+ const struct comm_addr *source,
+ struct priomsg *whynot)
{
struct site *st=sst;
/* initialised by named_for_us, or process_msgN for N!=1 */
if (msgtype==LABEL_MSG1) {
- if (!named_for_us(st,buf,msgtype,&msg))
+ if (!named_for_us(st,buf,msgtype,&msg,whynot))
return False;
/* It's a MSG1 addressed to us. Decide what to do about it. */
dump_packet(st,buf,source,True,True);
return True;
}
if (msgtype==LABEL_PROD) {
- if (!named_for_us(st,buf,msgtype,&msg))
+ if (!named_for_us(st,buf,msgtype,&msg,whynot))
return False;
dump_packet(st,buf,source,True,True);
if (st->state!=SITE_RUN) {
return True;
}
+ priomsg_update_fixed(whynot, comm_notify_whynot_general,
+ "not MSG1 or PROD; unknown dest index");
return False;
}