chiark / gitweb /
Makefiles: Use Final.sd.mk to implementing RECHECK_RM
[secnet.git] / site.c
diff --git a/site.c b/site.c
index ea85e0e223441ad754e75f311121a269066c9626..191c36463da7cf7bd1d6186a1a1f51ebb0484877 100644 (file)
--- a/site.c
+++ b/site.c
@@ -257,6 +257,7 @@ typedef struct {
 } transport_peers;
 
 /* Basic operations on transport peer address sets */
+static void transport_peers_init(struct site *st, transport_peers *peers);
 static void transport_peers_clear(struct site *st, transport_peers *peers);
 static int transport_peers_valid(transport_peers *peers);
 static void transport_peers_copy(struct site *st, transport_peers *dst,
@@ -318,7 +319,6 @@ struct site {
     int ncomms;
     struct resolver_if *resolver;
     struct log_if *log;
-    struct hash_if *defhash;
     struct random_if *random;
     struct privcache_if *privkeys;
     struct sigprivkey_if *privkey_fixed;
@@ -663,10 +663,7 @@ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what,
 
     struct xinfoadd xia;
     append_string_xinfo_start(&st->buffer,&xia,st->localname);
-    if ((st->local_capabilities & st->early_capabilities) ||
-       (type != LABEL_MSG1)) {
-       buf_append_uint32(&st->buffer,st->local_capabilities);
-    }
+    buf_append_uint32(&st->buffer,st->local_capabilities);
     if (type_is_msg34(type)) {
        buf_append_uint16(&st->buffer,st->mtu_target);
     }
@@ -711,6 +708,8 @@ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what,
        return False;
 
     privkey_found:
+       slog(st,LOG_SIGKEYS,"using private key #%d " SIGKEYID_PR_FMT,
+            ki, SIGKEYID_PR_VAL(prompt->pubkeys_accepted[ki]));
        buf_append_uint8(&st->buffer,ki);
     }
 
@@ -903,7 +902,7 @@ static void peerkeys_maybe_incorporate(struct site *st, const char *file,
                                       int logcl_enoent)
 {
     struct peer_keyset *atsuffix=
-       keyset_load(file,&st->scratch,st->log,logcl_enoent,st->defhash);
+       keyset_load(file,&st->scratch,st->log,logcl_enoent);
     if (!atsuffix) return;
 
     if (st->peerkeys_current &&
@@ -1088,9 +1087,14 @@ static bool_t process_msg3_msg4(struct site *st, struct msg *m)
     if (!pubkey->check(pubkey->st,
                       m->hashstart,m->hashlen,
                       &m->sig)) {
-       slog(st,LOG_SEC,"msg3/msg4 signature failed check!");
+       slog(st,LOG_SEC,"msg3/msg4 signature failed check!"
+            " (key #%d " SIGKEYID_PR_FMT ")",
+            ki, SIGKEYID_PR_VAL(&st->peerkeys_kex->keys[ki].id));
        return False;
     }
+    slog(st,LOG_SIGKEYS,"verified peer signature with key #%d "
+        SIGKEYID_PR_FMT, ki,
+        SIGKEYID_PR_VAL(&st->peerkeys_kex->keys[ki].id));
 
     st->remote_adv_mtu=m->remote_mtu;
 
@@ -1708,8 +1712,9 @@ static void set_link_quality(struct site *st)
 
 static void enter_state_run(struct site *st)
 {
-    slog(st,LOG_STATE,"entering state RUN%s",
-        current_valid(st) ? " (keyed)" : " (unkeyed)");
+    if (st->state!=SITE_STOP)
+       slog(st,LOG_STATE,"entering state RUN%s",
+            current_valid(st) ? " (keyed)" : " (unkeyed)");
     st->state=SITE_RUN;
     st->timeout=0;
 
@@ -2279,14 +2284,13 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
     return False;
 }
 
-static void site_control(void *vst, bool_t run)
+static void site_startup(void *vst)
 {
     struct site *st=vst;
-    if (run) enter_state_run(st);
-    else enter_state_stop(st);
+    enter_state_run(st);
 }
 
-static void site_phase_hook(void *sst, uint32_t newphase)
+static void site_phase_shutdown_hook(void *sst, uint32_t newphase)
 {
     struct site *st=sst;
 
@@ -2294,6 +2298,13 @@ static void site_phase_hook(void *sst, uint32_t newphase)
     send_msg7(st,"shutting down");
 }
 
+static void site_phase_run_hook(void *sst, uint32_t newphase)
+{
+    struct site *st=sst;
+    slog(st,LOG_STATE,"entering phase RUN in state %s",
+        state_name(st->state));
+}
+
 static void site_childpersist_clearkeys(void *sst, uint32_t newphase)
 {
     struct site *st=sst;
@@ -2311,18 +2322,6 @@ static void site_childpersist_clearkeys(void *sst, uint32_t newphase)
        crypto operations, but that's a task for another day. */
 }
 
-static void setup_sethash(struct site *st, dict_t *dict,
-                         struct cloc loc,
-                         sig_sethash_fn *sethash, void *sigkey_st) {
-    if (!st->defhash)
-       cfgfatal(loc,"site","other settings imply `hash' key is needed");
-    sethash(sigkey_st,st->defhash);
-}
-#define SETUP_SETHASH(k) do{                                           \
-    if ((k)->sethash)                                                  \
-        setup_sethash(st,dict,loc, (k)->sethash,(k)->st);      \
-}while(0)
-
 static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
                          list_t *args)
 {
@@ -2339,7 +2338,7 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->cl.apply=NULL;
     st->cl.interface=&st->ops;
     st->ops.st=st;
-    st->ops.control=site_control;
+    st->ops.startup=site_startup;
     st->ops.status=site_status;
     st->peerkeys_path=0;
     st->peerkeys_tmpl.buffer=0;
@@ -2351,9 +2350,19 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
        cfgfatal(loc,"site","parameter must be a dictionary\n");
     
     dict=item->data.dict;
+    st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
+    st->log_events=string_list_to_word(dict_lookup(dict,"log-events"),
+                                      log_event_table,"site");
+
     st->localname=dict_read_string(dict, "local-name", True, "site", loc);
     st->remotename=dict_read_string(dict, "name", True, "site", loc);
 
+    st->tunname=safe_malloc(strlen(st->localname)+strlen(st->remotename)+5,
+                           "site_apply");
+    sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
+
+    /* Now slog is working */
+
     st->keepalive=dict_read_bool(dict,"keepalive",False,"site",loc,False);
 
     st->peer_mobile=dict_read_bool(dict,"mobile",False,"site",loc,False);
@@ -2415,16 +2424,12 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     }
 
     st->resolver=find_cl_if(dict,"resolver",CL_RESOLVER,True,"site",loc);
-    st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
     st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc);
 
-    st->defhash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
-
     st->privkeys=find_cl_if(dict,"key-cache",CL_PRIVCACHE,False,"site",loc);
     if (!st->privkeys) {
        st->privkey_fixed=
            find_cl_if(dict,"local-key",CL_SIGPRIVKEY,True,"site",loc);
-       SETUP_SETHASH(st->privkey_fixed);
     }
 
     struct sigpubkey_if *fixed_pubkey
@@ -2435,14 +2440,12 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
        pathprefix_template_init(&st->peerkeys_tmpl,st->peerkeys_path,
                                 PEERKEYS_SUFFIX_MAXLEN + 1 /* nul */);
        st->peerkeys_current=keyset_load(st->peerkeys_path,
-                                        &st->scratch,st->log,M_ERR,
-                                        st->defhash);
+                                        &st->scratch,st->log,M_ERR);
        if (fixed_pubkey) {
            fixed_pubkey->dispose(fixed_pubkey->st);
        }
     } else {
        assert(fixed_pubkey);
-       SETUP_SETHASH(fixed_pubkey);
        NEW(st->peerkeys_current);
        st->peerkeys_current->refcount=1;
        st->peerkeys_current->nkeys=1;
@@ -2495,16 +2498,9 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
                 "renegotiate-time must be less than key-lifetime\n");
     }
 
-    st->log_events=string_list_to_word(dict_lookup(dict,"log-events"),
-                                      log_event_table,"site");
-
     st->resolving_count=0;
     st->allow_send_prod=0;
 
-    st->tunname=safe_malloc(strlen(st->localname)+strlen(st->remotename)+5,
-                           "site_apply");
-    sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
-
     /* The information we expect to see in incoming messages of type 1 */
     /* fixme: lots of unchecked overflows here, but the results are only
        corrupted packets rather than undefined behaviour */
@@ -2524,8 +2520,8 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->chosen_transform=0;
     st->current.key_timeout=0;
     st->auxiliary_key.key_timeout=0;
-    transport_peers_clear(st,&st->peers);
-    transport_peers_clear(st,&st->setup_peers);
+    transport_peers_init(st,&st->peers);
+    transport_peers_init(st,&st->setup_peers);
     /* XXX mlock these */
     st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret");
     st->sharedsecretlen=st->sharedsecretallocd=0;
@@ -2563,7 +2559,8 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
 
     enter_state_stop(st);
 
-    add_hook(PHASE_SHUTDOWN,site_phase_hook,st);
+    add_hook(PHASE_SHUTDOWN,site_phase_shutdown_hook,st);
+    add_hook(PHASE_RUN,     site_phase_run_hook,     st);
     add_hook(PHASE_CHILDPERSIST,site_childpersist_clearkeys,st);
 
     return new_closure(&st->cl);
@@ -2611,6 +2608,8 @@ static void transport_peers_debug(struct site *st, transport_peers *dst,
 
 static void transport_peers_expire(struct site *st, transport_peers *peers) {
     /* peers must be sorted first */
+    if (st->local_mobile) return;
+
     int previous_peers=peers->npeers;
     struct timeval oldest;
     oldest.tv_sec  = tv_now->tv_sec - st->mobile_peer_expiry;
@@ -2739,9 +2738,14 @@ static void transport_data_msgok(struct site *st, const struct comm_addr *a) {
 static int transport_peers_valid(transport_peers *peers) {
     return peers->npeers;
 }
+static void transport_peers_init(struct site *st, transport_peers *peers) {
+    peers->npeers= 0;
+}
 static void transport_peers_clear(struct site *st, transport_peers *peers) {
+    bool_t need_debug=!!peers->npeers;
     peers->npeers= 0;
-    transport_peers_debug(st,peers,"clear",0,0,0);
+    if (need_debug)
+       transport_peers_debug(st,peers,"clear",0,0,0);
 }
 static void transport_peers_copy(struct site *st, transport_peers *dst,
                                 const transport_peers *src) {