return x;
}
+bool append_connection_config(const connection_t *c, const char *key, const char *value) {
+ char *fname;
+ xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
+
+ FILE *fp = fopen(fname, "a");
+
+ if(!fp) {
+ logger(LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno));
+ } else {
+ fprintf(fp, "\n# The following line was automatically added by tinc\n%s = %s\n", key, value);
+ fclose(fp);
+ }
+
+ free(fname);
+
+ return fp;
+}
+
bool disable_old_keys(FILE *f) {
char buf[100];
long pos;
bool send_id(connection_t *c) {
gettimeofday(&c->start, NULL);
+ int minor = myself->connection->protocol_minor;
+ if(c->config_tree && !read_ecdsa_public_key(c))
+ minor = 1;
+
return send_request(c, "%d %s %d.%d", ID, myself->connection->name,
- myself->connection->protocol_major, myself->connection->protocol_minor);
+ myself->connection->protocol_major, minor);
}
bool id_h(connection_t *c, char *request) {
c->name);
return false;
}
+
+ if(c->protocol_minor >= 2)
+ if(!read_ecdsa_public_key(c))
+ return false;
+ } else {
+ if(!ecdsa_active(&c->ecdsa))
+ c->protocol_minor = 1;
}
c->allow_request = METAKEY;
}
bool send_metakey_ec(connection_t *c) {
- if(!read_ecdsa_public_key(c))
- return false;
-
logger(LOG_DEBUG, "Sending ECDH metakey to %s", c->name);
size_t siglen = ecdsa_size(&myself->connection->ecdsa);
}
bool send_metakey(connection_t *c) {
- size_t len = rsa_size(&c->rsa);
- char key[len];
- char enckey[len];
- char hexkey[2 * len + 1];
-
if(!read_rsa_public_key(c))
return false;
if(!digest_open_sha1(&c->outdigest, -1))
return false;
+ size_t len = rsa_size(&c->rsa);
+ char key[len];
+ char enckey[len];
+ char hexkey[2 * len + 1];
+
/* Create a random key */
randomize(key, len);
return send_ack(c);
}
+static bool send_upgrade(connection_t *c) {
+ /* Special case when protocol_minor is 1: the other end is ECDSA capable,
+ * but doesn't know our key yet. So send it now. */
+
+ char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa);
+
+ if(!pubkey)
+ return false;
+
+ bool result = send_request(c, "%d %s", ACK, pubkey);
+ free(pubkey);
+ return result;
+}
+
bool send_ack(connection_t *c) {
+ if(c->protocol_minor == 1)
+ return send_upgrade(c);
+
/* ACK message contains rest of the information the other end needs
to create node_t and edge_t structures. */
}
}
+static bool upgrade_h(connection_t *c, char *request) {
+ char pubkey[MAX_STRING_SIZE];
+
+ if(sscanf(request, "%*d " MAX_STRING, pubkey) != 1) {
+ logger(LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, c->hostname);
+ return false;
+ }
+
+ if(ecdsa_active(&c->ecdsa) || read_ecdsa_public_key(c)) {
+ logger(LOG_INFO, "Already have ECDSA public key from %s (%s), not upgrading.", c->name, c->hostname);
+ return false;
+ }
+
+ logger(LOG_INFO, "Got ECDSA public key from %s (%s), upgrading!", c->name, c->hostname);
+ append_connection_config(c, "ECDSAPublicKey", pubkey);
+ c->allow_request = TERMREQ;
+ return send_termreq(c);
+}
+
bool ack_h(connection_t *c, char *request) {
+ if(c->protocol_minor == 1)
+ return upgrade_h(c, request);
+
char hisport[MAX_STRING_SIZE];
char *hisaddress;
int weight, mtu;