Use void pointers for opaque data blobs in the SPTPS code.
[tinc] / src / protocol_auth.c
index b8d4ee8..cd45deb 100644 (file)
@@ -198,7 +198,7 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len)
        return true;
 }
 
-static bool receive_invitation_sptps(void *handle, uint8_t type, const char *data, uint16_t len) {
+static bool receive_invitation_sptps(void *handle, uint8_t type, const void *data, uint16_t len) {
        connection_t *c = handle;
 
        if(type == 128)
@@ -379,13 +379,13 @@ bool id_h(connection_t *c, const char *request) {
                }
 
                if(experimental)
-                       if(!read_ecdsa_public_key(c))
-                               return false;
-       } else {
-               if(c->protocol_minor && !ecdsa_active(c->ecdsa))
-                       c->protocol_minor = 1;
+                       read_ecdsa_public_key(c);
+                       /* Ignore failures if no key known yet */
        }
 
+       if(c->protocol_minor && !ecdsa_active(c->ecdsa))
+               c->protocol_minor = 1;
+
        /* Forbid version rollback for nodes whose Ed25519 key we know */
 
        if(ecdsa_active(c->ecdsa) && c->protocol_minor < 2) {
@@ -726,7 +726,21 @@ static bool upgrade_h(connection_t *c, const char *request) {
        }
 
        if(ecdsa_active(c->ecdsa) || read_ecdsa_public_key(c)) {
-               logger(DEBUG_ALWAYS, LOG_INFO, "Already have Ed25519 public key from %s (%s), not upgrading.", c->name, c->hostname);
+               char *knownkey = ecdsa_get_base64_public_key(c->ecdsa);
+               bool different = strcmp(knownkey, pubkey);
+               free(knownkey);
+               if(different) {
+                       logger(DEBUG_ALWAYS, LOG_ERR, "Already have an Ed25519 public key from %s (%s) which is different from the one presented now!", c->name, c->hostname);
+                       return false;
+               }
+               logger(DEBUG_ALWAYS, LOG_INFO, "Already have Ed25519 public key from %s (%s), ignoring.", c->name, c->hostname);
+               c->allow_request = TERMREQ;
+               return send_termreq(c);
+       }
+
+       c->ecdsa = ecdsa_set_base64_public_key(pubkey);
+       if(!c->ecdsa) {
+               logger(DEBUG_ALWAYS, LOG_INFO, "Got bad Ed25519 public key from %s (%s), not upgrading.", c->name, c->hostname);
                return false;
        }
 
@@ -805,7 +819,6 @@ bool ack_h(connection_t *c, const char *request) {
        /* Activate this connection */
 
        c->allow_request = ALL;
-       c->status.active = true;
 
        logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection with %s (%s) activated", c->name,
                           c->hostname);
@@ -822,6 +835,16 @@ bool ack_h(connection_t *c, const char *request) {
        sockaddr2str(&c->address, &hisaddress, NULL);
        c->edge->address = str2sockaddr(hisaddress, hisport);
        free(hisaddress);
+       sockaddr_t local_sa;
+       socklen_t local_salen = sizeof local_sa;
+       if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0)
+               logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name);
+       else {
+               char *local_address;
+               sockaddr2str(&local_sa, &local_address, NULL);
+               c->edge->local_address = str2sockaddr(local_address, myport);
+               free(local_address);
+       }
        c->edge->weight = (weight + c->estimated_weight) / 2;
        c->edge->connection = c;
        c->edge->options = c->options;