X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fprotocol_auth.c;h=2cface2105567dfa40a77ae8ddaa9fe9d0652dee;hb=3a316823b971396a428f020f401b9fe41252d98d;hp=d4705bde819e1887c189951593d1a1e299e62fcd;hpb=0792a10a5a66bcbf56185e479feed78252122667;p=tinc diff --git a/src/protocol_auth.c b/src/protocol_auth.c index d4705bde..2cface21 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -1,7 +1,7 @@ /* protocol_auth.c -- handle the meta-protocol, authentication Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2017 Guus Sliepen 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 {