chiark / gitweb /
test-example: Use subdirmk's new &:macro feature
[secnet.git] / site.c
diff --git a/site.c b/site.c
index 640ca68ba57ebb4ef4aa18ee0d4ee0939e142507..df083f40948f1643863a49617b31257a64293a59 100644 (file)
--- a/site.c
+++ b/site.c
@@ -318,6 +318,7 @@ 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;
@@ -662,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);
     }
@@ -710,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);
     }
 
@@ -902,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);
+       keyset_load(file,&st->scratch,st->log,logcl_enoent,st->defhash);
     if (!atsuffix) return;
 
     if (st->peerkeys_current &&
@@ -928,24 +928,6 @@ static void peerkeys_maybe_incorporate(struct site *st, const char *file,
 
 static void peerkeys_check_for_update(struct site *st)
 {
-    /* peerkeys files
-     *
-     *  <F>            live file, loaded on startup, updated by secnet
-     *                  (only).  * in-memory peerkeys_current is kept
-     *                  synced with this file
-     *
-     *  <F>~update     update file from config manager, checked before
-     *                  every key exchange.  config manager must rename
-     *                  this file into place; it will be renamed and
-     *                  then removed by secnet.
-     *
-     *  <F>~proc       update file being processed by secnet.
-     *                  only secnet may write or remove.
-     *
-     *  <F>~incoming   update file from peer, being received by secnet
-     *                  may be incomplete, unverified, or even malicious
-     *                  only secnet may write or remove.
-     */
     if (!st->peerkeys_path) return;
 
     pathprefix_template_setsuffix(&st->peerkeys_tmpl,"~proc");
@@ -973,7 +955,7 @@ static void peerkeys_check_for_update(struct site *st)
 
     int r=rename(inputp,oursp);
     if (r) {
-       slog(st,LOG_ERROR,"failed to claim key update file %s as %s: %s\n",
+       slog(st,LOG_ERROR,"failed to claim key update file %s as %s: %s",
             inputp,oursp,strerror(errno));
        return;
     }
@@ -1105,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;
 
@@ -2329,14 +2316,15 @@ static void site_childpersist_clearkeys(void *sst, uint32_t newphase)
 }
 
 static void setup_sethash(struct site *st, dict_t *dict,
-                         struct hash_if **hash, struct cloc loc,
+                         struct cloc loc,
                          sig_sethash_fn *sethash, void *sigkey_st) {
-    if (!*hash) *hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
-    sethash(sigkey_st,*hash);
+    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, &hash,loc, (k)->sethash,(k)->st);       \
+        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,
@@ -2367,9 +2355,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);
@@ -2431,10 +2429,9 @@ 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);
 
-    struct hash_if *hash=0;
+    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) {
@@ -2451,7 +2448,8 @@ 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->scratch,st->log,M_ERR,
+                                        st->defhash);
        if (fixed_pubkey) {
            fixed_pubkey->dispose(fixed_pubkey->st);
        }
@@ -2510,16 +2508,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 */