]> git.seodisparate.com - UDPConnection/commitdiff
Impl auth-policy for handling with(out) auth
authorStephen Seo <seo.disparate@gmail.com>
Mon, 9 Dec 2019 12:27:58 +0000 (21:27 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Mon, 9 Dec 2019 12:27:58 +0000 (21:27 +0900)
src/UDPC_Defines.hpp
src/UDPConnection.cpp
src/UDPConnection.h
src/test/UDPC_NetworkTest.c

index 0854ae7d72b87f7dc230d0a8fb23ce97adf74d6a..6afde2db8c14c98739d5f8116fd40bbaad4ad96c 100644 (file)
@@ -209,6 +209,8 @@ public:
     std::atomic_bool isReceivingEvents;
     std::atomic_uint32_t protocolID;
     std::atomic_uint_fast8_t loggingType;
+    // See UDPC_AuthPolicy enum in UDPConnection.h for possible values
+    std::atomic_uint_fast8_t authPolicy;
     std::atomic_uint32_t atostrBufIndex;
     char atostrBuf[UDPC_ATOSTR_SIZE];
 
index a9d50fc8342f2eacad5f33d8b1bebf8dddb42d41..c2501c767b00248cb7361fa934439cd0ecfcf39f 100644 (file)
@@ -1159,6 +1159,28 @@ void UDPC::Context::update_impl() {
                 && conMap.find(identifier) == conMap.end()
                 && isAcceptNewConnections.load()) {
             // is receiving as server, connection did not already exist
+            int authPolicy = this->authPolicy.load();
+            if(pktType == 1 && !flags.test(2)
+                    && authPolicy == UDPC_AuthPolicy::UDPC_AUTH_POLICY_STRICT) {
+                UDPC_CHECK_LOG(this, UDPC_LoggingType::UDPC_ERROR,
+                    "Client peer ",
+                    UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
+                    " port ",
+                    ntohs(receivedData.sin6_port),
+                    " attempted connection with packet authentication "
+                    "enabled, but auth is disabled and AuthPolicy is STRICT");
+                return;
+            } else if(pktType == 0 && flags.test(2)
+                    && authPolicy == UDPC_AuthPolicy::UDPC_AUTH_POLICY_STRICT) {
+                UDPC_CHECK_LOG(this, UDPC_LoggingType::UDPC_ERROR,
+                    "Client peer ",
+                    UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
+                    " port ",
+                    ntohs(receivedData.sin6_port),
+                    " attempted connection with packet authentication "
+                    "disabled, but auth is enabled and AuthPolicy is STRICT");
+                return;
+            }
             unsigned char *sk = nullptr;
             unsigned char *pk = nullptr;
             if(keysSet.load()) {
@@ -1259,6 +1281,32 @@ void UDPC::Context::update_impl() {
                     ", port ", ntohs(receivedData.sin6_port));
                 return;
             }
+            int authPolicy = this->authPolicy.load();
+            if(pktType == 2 && !iter->second.flags.test(6)
+                    && authPolicy == UDPC_AuthPolicy::UDPC_AUTH_POLICY_STRICT) {
+                // This block actually should never happen, because the server
+                // receives a packet first. If client requests without auth,
+                // then the server will either deny connection (if strict) or
+                // fallback to a connection without auth (if fallback).
+                UDPC_CHECK_LOG(this, UDPC_LoggingType::UDPC_ERROR,
+                    "Server peer ",
+                    UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
+                    " port ",
+                    ntohs(receivedData.sin6_port),
+                    " attempted connection with packet authentication "
+                    "enabled, but auth is disabled and AuthPolicy is STRICT");
+                return;
+            } else if(pktType == 0 && iter->second.flags.test(6)
+                    && authPolicy == UDPC_AuthPolicy::UDPC_AUTH_POLICY_STRICT) {
+                UDPC_CHECK_LOG(this, UDPC_LoggingType::UDPC_ERROR,
+                    "Server peer ",
+                    UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
+                    " port ",
+                    ntohs(receivedData.sin6_port),
+                    " attempted connection with packet authentication "
+                    "disabled, but auth is enabled and AuthPolicy is STRICT");
+                return;
+            }
 
             if(pktType == 2 && flags.test(2) && iter->second.flags.test(6)) {
 #ifdef UDPC_LIBSODIUM_ENABLED
@@ -1300,7 +1348,6 @@ void UDPC::Context::update_impl() {
                     UDPC_CHECK_LOG(this, UDPC_LoggingType::UDPC_WARNING,
                         "peer is not using libsodium, but peer_pk was "
                         "pre-set, dropping to no-verification mode");
-                    // TODO set policy for using/not-using libsodium
                 }
             }
 
@@ -1663,6 +1710,7 @@ UDPC_ConnectionId UDPC_create_id_easy(const char *addrString, uint16_t port) {
 UDPC_HContext UDPC_init(UDPC_ConnectionId listenId, int isClient, int isUsingLibsodium) {
     UDPC::Context *ctx = new UDPC::Context(false);
     ctx->flags.set(1, isClient != 0);
+    ctx->authPolicy.exchange(UDPC_AuthPolicy::UDPC_AUTH_POLICY_FALLBACK);
 
     UDPC_CHECK_LOG(ctx, UDPC_LoggingType::UDPC_INFO, "Got listen addr ",
         UDPC_atostr((UDPC_HContext)ctx, listenId.addr));
@@ -2146,6 +2194,35 @@ int UDPC_unset_libsodium_keys(UDPC_HContext ctx) {
     return 1;
 }
 
+int UDPC_get_auth_policy(UDPC_HContext ctx) {
+    UDPC::Context *c = UDPC::verifyContext(ctx);
+    if(!c) {
+        return 0;
+    }
+
+    return c->authPolicy.load();
+}
+
+int UDPC_set_auth_policy(UDPC_HContext ctx, int policy) {
+    UDPC::Context *c = UDPC::verifyContext(ctx);
+    if(!c) {
+        return 0;
+    }
+
+    bool isInRange = false;
+    for(int i = 0; i < UDPC_AuthPolicy::UDPC_AUTH_POLICY_SIZE; ++i) {
+        if(policy == i) {
+            isInRange = true;
+            break;
+        }
+    }
+    if(!isInRange) {
+        return 0;
+    }
+
+    return c->authPolicy.exchange(policy);
+}
+
 const char *UDPC_atostr_cid(UDPC_HContext ctx, UDPC_ConnectionId connectionId) {
     return UDPC_atostr(ctx, connectionId.addr);
 }
index f64df967e51d3d74d5467398e778b9a63b18f9c9..bb9eef1212ef2bb68a8eacbcd1495e4b654b76e4 100644 (file)
@@ -109,7 +109,20 @@ extern "C" {
 struct UDPC_Context;
 typedef struct UDPC_Context *UDPC_HContext;
 
-typedef enum { UDPC_SILENT, UDPC_ERROR, UDPC_WARNING, UDPC_INFO, UDPC_VERBOSE, UDPC_DEBUG } UDPC_LoggingType;
+typedef enum {
+    UDPC_SILENT,
+    UDPC_ERROR,
+    UDPC_WARNING,
+    UDPC_INFO,
+    UDPC_VERBOSE,
+    UDPC_DEBUG
+} UDPC_LoggingType;
+
+typedef enum {
+    UDPC_AUTH_POLICY_FALLBACK=0,
+    UDPC_AUTH_POLICY_STRICT,
+    UDPC_AUTH_POLICY_SIZE /// Used internally to get max size of enum
+} UDPC_AuthPolicy;
 
 /*!
  * \brief Data identifying a peer via addr, port, and scope_id
@@ -474,6 +487,9 @@ int UDPC_set_libsodium_key_easy(UDPC_HContext ctx, unsigned char *sk);
 
 int UDPC_unset_libsodium_keys(UDPC_HContext ctx);
 
+int UDPC_get_auth_policy(UDPC_HContext ctx);
+int UDPC_set_auth_policy(UDPC_HContext ctx, int value);
+
 const char *UDPC_atostr_cid(UDPC_HContext ctx, UDPC_ConnectionId connectionId);
 
 const char *UDPC_atostr(UDPC_HContext ctx, UDPC_IPV6_ADDR_TYPE addr);
index 949320b542305a48cc3e403e6d9f7476f4ed7553..8e7a0d8b47aafabb5c86c591dfd164a264a6a49f 100644 (file)
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <threads.h>
+#include <assert.h>
 
 #ifdef UDPC_LIBSODIUM_ENABLED
 #include <sodium.h>
@@ -25,6 +26,7 @@ void usage() {
     puts("-ls - enable libsodium");
     puts("-ck <pubkey_file> - connect to server expecting this public key");
     puts("-sk <pubkey> <seckey> - start with pub/sec key pair");
+    puts("-p <\"fallback\" or \"strict\"> - set auth policy");
 }
 
 void sleep_seconds(unsigned int seconds) {
@@ -55,6 +57,8 @@ int main(int argc, char **argv) {
     const char *seckey_file = NULL;
     unsigned char pubkey[crypto_sign_PUBLICKEYBYTES];
     unsigned char seckey[crypto_sign_SECRETKEYBYTES];
+    int authPolicy = UDPC_AUTH_POLICY_FALLBACK;
+
     while(argc > 0) {
         if(strcmp(argv[0], "-c") == 0) {
             isClient = 1;
@@ -113,6 +117,18 @@ int main(int argc, char **argv) {
             pubkey_file = argv[0];
             --argc; ++argv;
             seckey_file = argv[0];
+        } else if(strcmp(argv[0], "-p") == 0 && argc > 1) {
+            if(strcmp(argv[1], "fallback") == 0) {
+                authPolicy = UDPC_AUTH_POLICY_FALLBACK;
+                --argc; ++argv;
+            } else if(strcmp(argv[1], "strict") == 0) {
+                authPolicy = UDPC_AUTH_POLICY_STRICT;
+                --argc; ++argv;
+            } else {
+                printf("ERROR: invalid argument \"%s %s\"\n", argv[0], argv[1]);
+                usage();
+                return 1;
+            }
         } else {
             printf("ERROR: invalid argument \"%s\"\n", argv[0]);
             usage();
@@ -196,6 +212,14 @@ int main(int argc, char **argv) {
         puts("Set pubkey/seckey for server");
     }
 
+    UDPC_set_auth_policy(context, authPolicy);
+    assert(UDPC_get_auth_policy(context) == authPolicy);
+    if(authPolicy == UDPC_AUTH_POLICY_FALLBACK) {
+        puts("Auth policy set to \"fallback\"");
+    } else if(authPolicy == UDPC_AUTH_POLICY_STRICT) {
+        puts("Auth policy set to \"strict\"");
+    }
+
     UDPC_enable_threaded_update(context);
 
     unsigned int tick = 0;