Convert sizeof foo to sizeof(foo).
[tinc] / src / protocol_auth.c
index d4705bd..2cface2 100644 (file)
@@ -1,7 +1,7 @@
 /*
     protocol_auth.c -- handle the meta-protocol, authentication
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2016 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2017 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -47,6 +47,7 @@
 
 #include "ed25519/sha512.h"
 
+int invitation_lifetime;
 ecdsa_t *invitation_key = NULL;
 
 static bool send_proxyrequest(connection_t *c) {
@@ -73,9 +74,9 @@ static bool send_proxyrequest(connection_t *c) {
                        memcpy(s4req + 4, &c->address.in.sin_addr, 4);
                        if(proxyuser)
                                memcpy(s4req + 8, proxyuser, strlen(proxyuser));
-                       s4req[sizeof s4req - 1] = 0;
+                       s4req[sizeof(s4req) - 1] = 0;
                        c->tcplen = 8;
-                       return send_meta(c, s4req, sizeof s4req);
+                       return send_meta(c, s4req, sizeof(s4req));
                }
                case PROXY_SOCKS5: {
                        int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16);
@@ -122,7 +123,7 @@ static bool send_proxyrequest(connection_t *c) {
                        }
                        if(i > len)
                                abort();
-                       return send_meta(c, s5req, sizeof s5req);
+                       return send_meta(c, s5req, sizeof(s5req));
                }
                case PROXY_SOCKS4A:
                        logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet");
@@ -162,7 +163,7 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len)
 
        // Create a new host config file
        char filename[PATH_MAX];
-       snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
+       snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
        if(!access(filename, F_OK)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Host config file for %s (%s) already exists!\n", c->name, c->hostname);
                return false;
@@ -180,21 +181,18 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len)
        logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname);
 
        // Call invitation-accepted script
-       char *envp[7] = {NULL};
+       environment_t env;
        char *address, *port;
 
-       xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
-        xasprintf(&envp[1], "DEVICE=%s", device ? : "");
-        xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
-        xasprintf(&envp[3], "NODE=%s", c->name);
+       environment_init(&env);
+        environment_add(&env, "NODE=%s", c->name);
        sockaddr2str(&c->address, &address, &port);
-       xasprintf(&envp[4], "REMOTEADDRESS=%s", address);
-       xasprintf(&envp[5], "NAME=%s", myself->name);
+       environment_add(&env, "REMOTEADDRESS=%s", address);
+       environment_add(&env, "NAME=%s", myself->name);
 
-       execute_script("invitation-accepted", envp);
+       execute_script("invitation-accepted", &env);
 
-       for(int i = 0; envp[i] && i < 7; i++)
-               free(envp[i]);
+       environment_exit(&env);
 
        sptps_send_record(&c->sptps, 2, data, 0);
        return true;
@@ -217,14 +215,14 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
        char hashbuf[18 + strlen(fingerprint)];
        char cookie[64];
        memcpy(hashbuf, data, 18);
-       memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18);
-       sha512(hashbuf, sizeof hashbuf, cookie);
+       memcpy(hashbuf + 18, fingerprint, sizeof(hashbuf) - 18);
+       sha512(hashbuf, sizeof(hashbuf), cookie);
        b64encode_urlsafe(cookie, cookie, 18);
        free(fingerprint);
 
        char filename[PATH_MAX], usedname[PATH_MAX];
-       snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie);
-       snprintf(usedname, sizeof usedname, "%s" SLASH "invitations" SLASH "%s.used", confbase, cookie);
+       snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "%s", confbase, cookie);
+       snprintf(usedname, sizeof(usedname), "%s" SLASH "invitations" SLASH "%s.used", confbase, cookie);
 
        // Atomically rename the invitation file
        if(rename(filename, usedname)) {
@@ -235,6 +233,18 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
                return false;
        }
 
+       // Check the timestamp of the invitation
+       struct stat st;
+       if(stat(usedname, &st)) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat %s", usedname);
+               return false;
+       }
+
+       if(st.st_mtime + invitation_lifetime < now.tv_sec) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use expired invitation %s", c->hostname, cookie);
+               return false;
+       }
+
        // Open the renamed file
        FILE *f = fopen(usedname, "r");
        if(!f) {
@@ -244,7 +254,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
 
        // Read the new node's Name from the file
        char buf[1024];
-       fgets(buf, sizeof buf, f);
+       fgets(buf, sizeof(buf), f);
        if(*buf)
                buf[strlen(buf) - 1] = 0;
 
@@ -269,7 +279,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
        // Send the node the contents of the invitation file
        rewind(f);
        size_t result;
-       while((result = fread(buf, 1, sizeof buf, f)))
+       while((result = fread(buf, 1, sizeof(buf), f)))
                sptps_send_record(&c->sptps, 0, buf, result);
        sptps_send_record(&c->sptps, 1, buf, 0);
        fclose(f);
@@ -284,7 +294,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
 bool id_h(connection_t *c, const char *request) {
        char name[MAX_STRING_SIZE];
 
-       if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) {
+       if(sscanf(request, "%*d " MAX_STRING " %2d.%3d", name, &c->protocol_major, &c->protocol_minor) < 2) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name,
                           c->hostname);
                return false;
@@ -399,11 +409,11 @@ bool id_h(connection_t *c, const char *request) {
                char label[25 + strlen(myself->name) + strlen(c->name)];
 
                if(c->outgoing)
-                       snprintf(label, sizeof label, "tinc TCP key expansion %s %s", myself->name, c->name);
+                       snprintf(label, sizeof(label), "tinc TCP key expansion %s %s", myself->name, c->name);
                else
-                       snprintf(label, sizeof label, "tinc TCP key expansion %s %s", c->name, myself->name);
+                       snprintf(label, sizeof(label), "tinc TCP key expansion %s %s", c->name, myself->name);
 
-               return sptps_start(&c->sptps, c, c->outgoing, false, myself->connection->ecdsa, c->ecdsa, label, sizeof label, send_meta_sptps, receive_meta_sptps);
+               return sptps_start(&c->sptps, c, c->outgoing, false, myself->connection->ecdsa, c->ecdsa, label, sizeof(label), send_meta_sptps, receive_meta_sptps);
        } else {
                return send_metakey(c);
        }
@@ -518,7 +528,7 @@ bool metakey_h(connection_t *c, const char *request) {
 
        /* Convert the challenge from hexadecimal back to binary */
 
-       int inlen = hex2bin(hexkey, enckey, sizeof enckey);
+       int inlen = hex2bin(hexkey, enckey, sizeof(enckey));
 
        /* Check if the length of the meta key is all right */
 
@@ -612,7 +622,7 @@ bool challenge_h(connection_t *c, const char *request) {
 
        /* Convert the challenge from hexadecimal back to binary */
 
-       int inlen = hex2bin(buffer, buffer, sizeof buffer);
+       int inlen = hex2bin(buffer, buffer, sizeof(buffer));
 
        /* Check if the length of the challenge is all right */
 
@@ -652,7 +662,7 @@ bool chal_reply_h(connection_t *c, const char *request) {
 
        /* Convert the hash to binary format */
 
-       int inlen = hex2bin(hishash, hishash, sizeof hishash);
+       int inlen = hex2bin(hishash, hishash, sizeof(hishash));
 
        /* Check if the length of the hash is all right */
 
@@ -745,7 +755,7 @@ static void send_everything(connection_t *c) {
                        char pad[MAXBUFSIZE - MAXSIZE];
                } zeropkt;
 
-               memset(&zeropkt, 0, sizeof zeropkt);
+               memset(&zeropkt, 0, sizeof(zeropkt));
                zeropkt.pkt.len = MAXBUFSIZE;
                send_tcppacket(c, &zeropkt.pkt);
        }
@@ -885,7 +895,7 @@ bool ack_h(connection_t *c, const char *request) {
        sockaddrcpy(&c->edge->address, &c->address);
        sockaddr_setport(&c->edge->address, hisport);
        sockaddr_t local_sa;
-       socklen_t local_salen = sizeof 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 {