]> git.meshlink.io Git - meshlink/commitdiff
Add meshlink_set_invitation_timeout().
authorGuus Sliepen <guus@meshlink.io>
Tue, 26 Jun 2018 14:42:57 +0000 (16:42 +0200)
committerGuus Sliepen <guus@meshlink.io>
Tue, 26 Jun 2018 14:42:57 +0000 (16:42 +0200)
This sets a global timeout for invitation files. If a node tries to join
with an invitation whose file is older than the timeout, the invitation is
rejected.

src/meshlink++.h
src/meshlink.c
src/meshlink.h
src/meshlink_internal.h
src/protocol_auth.c
test/invite-join.c

index 4cea8cfa206334e07b9b106b7941ce15daeeb4da..413534ea2ceae0a4beeb3f77a2d7c3f1800d0b8c 100644 (file)
@@ -474,6 +474,16 @@ public:
                return meshlink_set_port(handle, port);
        }
 
+       /// Set the timeout for invitations.
+       /** This function sets the timeout for invitations.
+        *  The timeout is retroactively applied to all outstanding invitations.
+        *
+        *  @param timeout      The timeout for invitations in seconds.
+        */
+       void set_invitation_timeout(int timeout) {
+               meshlink_set_invitation_timeout(handle, timeout);
+       }
+
        /// Invite another node into the mesh.
        /** This function generates an invitation that can be used by another node to join the same mesh as the local node.
         *  The generated invitation is a string containing a URL.
index 1c81ad22673957362d0b11de8ef9bbd0c3eb38c8..52a4389a9311e1e872091e9cccc335db94ca3b37 100644 (file)
@@ -1033,6 +1033,7 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const c
        mesh->appname = xstrdup(appname);
        mesh->devclass = devclass;
        mesh->discovery = true;
+       mesh->invitation_timeout = 604800; // 1 week
 
        if(usingname) {
                mesh->name = xstrdup(name);
@@ -1832,6 +1833,10 @@ done:
        return rval;
 }
 
+void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout) {
+       mesh->invitation_timeout = timeout;
+}
+
 char *meshlink_invite(meshlink_handle_t *mesh, const char *name) {
        if(!mesh) {
                meshlink_errno = MESHLINK_EINVAL;
index 26d0dfceda73af09b62bbb93565a928192823673..a0cb11877a1d6190ace6d69f903561e80ffa9980 100644 (file)
@@ -520,6 +520,16 @@ extern int meshlink_get_port(meshlink_handle_t *mesh);
 
 extern bool meshlink_set_port(meshlink_handle_t *mesh, int port);
 
+/// Set the timeout for invitations.
+/** This function sets the timeout for invitations.
+ *  Note that timeouts are only checked at the time a node tries to join using an invitation.
+ *  The default timeout for invitations is 1 week.
+ *
+ *  @param mesh         A handle which represents an instance of MeshLink.
+ *  @param timeout      The timeout for invitations in seconds.
+ */
+extern void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout);
+
 /// Invite another node into the mesh.
 /** This function generates an invitation that can be used by another node to join the same mesh as the local node.
  *  The generated invitation is a string containing a URL.
index d7d4910b18cfccf79461195d3246f137d4396445..c6c99541d66b0d7fa622c097313e1090b19dc09c 100644 (file)
@@ -120,6 +120,7 @@ struct meshlink_handle {
        hash_t *node_udp_cache;
        struct connection_t *everyone;
        struct ecdsa *invitation_key;
+       int invitation_timeout;
 
        int pinginterval;       /* seconds between pings */
        int pingtimeout;        /* seconds to wait for response */
index b11acaef7c5e4238dcba37af577bb8077da2fef3..4ba3ebe4282dc1742942b2944a31309a233559da 100644 (file)
@@ -239,6 +239,24 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
 
        if(!f) {
                logger(mesh, MESHLINK_ERROR, "Error trying to open invitation %s\n", cookie);
+               unlink(usedname);
+               return false;
+       }
+
+       // Check the timestamp
+       struct stat st;
+
+       if(fstat(fileno(f), &st)) {
+               logger(mesh, MESHLINK_ERROR, "Could not stat invitation file %s\n", usedname);
+               fclose(f);
+               unlink(usedname);
+               return false;
+       }
+
+       if(time(NULL) > st.st_mtime + mesh->invitation_timeout) {
+               logger(mesh, MESHLINK_ERROR, "Peer %s tried to use an outdated invitation file %s\n", c->name, usedname);
+               fclose(f);
+               unlink(usedname);
                return false;
        }
 
index 90326a0d1d8b574e40395f97c7f5a0e05a5e11cf..03e169176ee2e52e771b1641daa6443ed6ef4788 100644 (file)
@@ -32,12 +32,20 @@ int main() {
                return 1;
        }
 
+       meshlink_handle_t *mesh3 = meshlink_open("invite_join_conf.3", "quux", "invite-join", DEV_CLASS_BACKBONE);
+
+       if(!mesh3) {
+               fprintf(stderr, "Could not initialize configuration for quux\n");
+               return 1;
+       }
+
        // Disable local discovery.
 
        meshlink_enable_discovery(mesh1, false);
        meshlink_enable_discovery(mesh2, false);
+       meshlink_enable_discovery(mesh3, false);
 
-       // Start the first instance and have it generate an invitation.
+       // Start the first instance and have it generate invitations.
 
        meshlink_set_node_status_cb(mesh1, status_cb);
 
@@ -47,21 +55,28 @@ int main() {
        }
 
        meshlink_add_address(mesh1, "localhost");
-       char *url = meshlink_invite(mesh1, "baz");
+       char *baz_url = meshlink_invite(mesh1, "baz");
 
-       if(!url) {
+       if(!baz_url) {
                fprintf(stderr, "Foo could not generate an invitation for baz\n");
                return 1;
        }
 
+       char *quux_url = meshlink_invite(mesh1, "quux");
+
+       if(!quux_url) {
+               fprintf(stderr, "Foo could not generate an invitation for quux\n");
+               return 1;
+       }
+
        // Have the second instance join the first.
 
-       if(!meshlink_join(mesh2, url)) {
+       if(!meshlink_join(mesh2, baz_url)) {
                fprintf(stderr, "Baz could not join foo's mesh\n");
                return 1;
        }
 
-       free(url);
+       free(baz_url);
 
        if(!meshlink_start(mesh2)) {
                fprintf(stderr, "Baz could not start\n");
@@ -95,6 +110,17 @@ int main() {
                return 1;
        }
 
+       // Check that nodes cannot join with expired invitations
+
+       meshlink_set_invitation_timeout(mesh1, 0);
+
+       if(meshlink_join(mesh3, quux_url)) {
+               fprintf(stderr, "Quux could join foo's mesh using an outdated invitation\n");
+               return 1;
+       }
+
+       free(quux_url);
+
        // Clean up.
 
        meshlink_stop(mesh2);