"peer has used new key","auxiliary key",LOG_SEC);
return 0;
}
- if (problem==transform_apply_seqrange)
- goto skew;
+ if (transform_apply_return_badseq(problem))
+ goto badseq;
buffer_copy(msg0, &st->scratch);
problem = call_transform_reverse(st,st->auxiliary_key.transform,
}
return 0;
}
- if (problem==transform_apply_seqrange)
- goto skew;
+ if (transform_apply_return_badseq(problem))
+ goto badseq;
if (st->state==SITE_SENTMSG5) {
buffer_copy(msg0, &st->scratch);
activate_new_key(st);
return 0; /* do process the data in this packet */
}
- if (problem==transform_apply_seqrange)
- goto skew;
+ if (transform_apply_return_badseq(problem))
+ goto badseq;
}
slog(st,LOG_SEC,"transform: %s (aux: %s, new: %s)",
assert(problem);
return problem;
- skew:
- slog(st,LOG_DROP,"transform: %s (merely skew)",transform_err);
+ badseq:
+ slog(st,LOG_DROP,"transform: %s (bad seq.)",transform_err);
assert(problem);
return problem;
}
transform_apply_return problem;
problem = decrypt_msg0(st,msg0,src);
+ if (problem==transform_apply_seqdupe) {
+ /* We recently received another copy of this packet, maybe due
+ * to polypath. That's not a problem; indeed, for the
+ * purposes of transport address management it is a success.
+ * But we don't want to process the packet. */
+ transport_data_msgok(st,src);
+ return False;
+ }
if (problem)
return False;
return st->our_name_later;
}
+static bool_t setup_late_msg_ok(struct site *st,
+ const struct buffer_if *buf_in,
+ uint32_t msgtype,
+ const struct comm_addr *source) {
+ /* For setup packets which seem from their type like they are
+ * 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. */
+ struct msg m;
+ if (!named_for_us(st,buf_in,msgtype,&m))
+ /* named_for_us calls unpick_msg which gets the nonces */
+ return False;
+ if (!consttime_memeq(m.nR,st->remoteN,NONCELEN) ||
+ !consttime_memeq(m.nL,st->localN, NONCELEN))
+ /* spoof ? from stale run ? who knows */
+ return False;
+ transport_setup_msgok(st,source);
+ return True;
+}
+
/* This function is called by the communication device to deliver
packets from our peers.
It should return True if the packet is recognised as being for
BUF_FREE(buf);
return True;
}
+ } else if (st->state==SITE_SENTMSG2 ||
+ st->state==SITE_SENTMSG4) {
+ if (consttime_memeq(named_msg.nR,st->remoteN,NONCELEN)) {
+ /* We are ahead in the protocol, but that msg1 had the
+ * peer's nonce so presumably it is from this key
+ * exchange run, via a slower route */
+ transport_setup_msgok(st,source);
+ } else {
+ slog(st,LOG_UNEXPECTED,"competing incoming message 1");
+ }
+ BUF_FREE(buf);
+ return True;
}
/* The message 1 was received at an unexpected stage of the
- key setup. XXX POLICY - what do we do? */
+ key setup. Well, they lost the race. */
slog(st,LOG_UNEXPECTED,"unexpected incoming message 1");
BUF_FREE(buf);
return True;
case LABEL_MSG2:
/* Setup packet: expected only in state SENTMSG1 */
if (st->state!=SITE_SENTMSG1) {
+ if ((st->state==SITE_SENTMSG3 ||
+ st->state==SITE_SENTMSG5) &&
+ setup_late_msg_ok(st,buf,msgtype,source))
+ break;
slog(st,LOG_UNEXPECTED,"unexpected MSG2");
} else if (process_msg2(st,buf,source)) {
transport_setup_msgok(st,source);
case LABEL_MSG3BIS:
/* Setup packet: expected only in state SENTMSG2 */
if (st->state!=SITE_SENTMSG2) {
+ if ((st->state==SITE_SENTMSG4) &&
+ setup_late_msg_ok(st,buf,msgtype,source))
+ break;
slog(st,LOG_UNEXPECTED,"unexpected MSG3");
} else if (process_msg3(st,buf,source,msgtype)) {
transport_setup_msgok(st,source);
case LABEL_MSG4:
/* Setup packet: expected only in state SENTMSG3 */
if (st->state!=SITE_SENTMSG3) {
+ if ((st->state==SITE_SENTMSG5) &&
+ setup_late_msg_ok(st,buf,msgtype,source))
+ break;
slog(st,LOG_UNEXPECTED,"unexpected MSG4");
} else if (process_msg4(st,buf,source)) {
transport_setup_msgok(st,source);