Impl auth-policy for handling with(out) auth
This commit is contained in:
parent
d94b44e4de
commit
7c444cb460
4 changed files with 121 additions and 2 deletions
|
@ -209,6 +209,8 @@ public:
|
||||||
std::atomic_bool isReceivingEvents;
|
std::atomic_bool isReceivingEvents;
|
||||||
std::atomic_uint32_t protocolID;
|
std::atomic_uint32_t protocolID;
|
||||||
std::atomic_uint_fast8_t loggingType;
|
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;
|
std::atomic_uint32_t atostrBufIndex;
|
||||||
char atostrBuf[UDPC_ATOSTR_SIZE];
|
char atostrBuf[UDPC_ATOSTR_SIZE];
|
||||||
|
|
||||||
|
|
|
@ -1159,6 +1159,28 @@ void UDPC::Context::update_impl() {
|
||||||
&& conMap.find(identifier) == conMap.end()
|
&& conMap.find(identifier) == conMap.end()
|
||||||
&& isAcceptNewConnections.load()) {
|
&& isAcceptNewConnections.load()) {
|
||||||
// is receiving as server, connection did not already exist
|
// 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 *sk = nullptr;
|
||||||
unsigned char *pk = nullptr;
|
unsigned char *pk = nullptr;
|
||||||
if(keysSet.load()) {
|
if(keysSet.load()) {
|
||||||
|
@ -1259,6 +1281,32 @@ void UDPC::Context::update_impl() {
|
||||||
", port ", ntohs(receivedData.sin6_port));
|
", port ", ntohs(receivedData.sin6_port));
|
||||||
return;
|
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)) {
|
if(pktType == 2 && flags.test(2) && iter->second.flags.test(6)) {
|
||||||
#ifdef UDPC_LIBSODIUM_ENABLED
|
#ifdef UDPC_LIBSODIUM_ENABLED
|
||||||
|
@ -1300,7 +1348,6 @@ void UDPC::Context::update_impl() {
|
||||||
UDPC_CHECK_LOG(this, UDPC_LoggingType::UDPC_WARNING,
|
UDPC_CHECK_LOG(this, UDPC_LoggingType::UDPC_WARNING,
|
||||||
"peer is not using libsodium, but peer_pk was "
|
"peer is not using libsodium, but peer_pk was "
|
||||||
"pre-set, dropping to no-verification mode");
|
"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_HContext UDPC_init(UDPC_ConnectionId listenId, int isClient, int isUsingLibsodium) {
|
||||||
UDPC::Context *ctx = new UDPC::Context(false);
|
UDPC::Context *ctx = new UDPC::Context(false);
|
||||||
ctx->flags.set(1, isClient != 0);
|
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_CHECK_LOG(ctx, UDPC_LoggingType::UDPC_INFO, "Got listen addr ",
|
||||||
UDPC_atostr((UDPC_HContext)ctx, listenId.addr));
|
UDPC_atostr((UDPC_HContext)ctx, listenId.addr));
|
||||||
|
@ -2146,6 +2194,35 @@ int UDPC_unset_libsodium_keys(UDPC_HContext ctx) {
|
||||||
return 1;
|
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) {
|
const char *UDPC_atostr_cid(UDPC_HContext ctx, UDPC_ConnectionId connectionId) {
|
||||||
return UDPC_atostr(ctx, connectionId.addr);
|
return UDPC_atostr(ctx, connectionId.addr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,20 @@ extern "C" {
|
||||||
struct UDPC_Context;
|
struct UDPC_Context;
|
||||||
typedef struct UDPC_Context *UDPC_HContext;
|
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
|
* \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_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_cid(UDPC_HContext ctx, UDPC_ConnectionId connectionId);
|
||||||
|
|
||||||
const char *UDPC_atostr(UDPC_HContext ctx, UDPC_IPV6_ADDR_TYPE addr);
|
const char *UDPC_atostr(UDPC_HContext ctx, UDPC_IPV6_ADDR_TYPE addr);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <threads.h>
|
#include <threads.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef UDPC_LIBSODIUM_ENABLED
|
#ifdef UDPC_LIBSODIUM_ENABLED
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
@ -25,6 +26,7 @@ void usage() {
|
||||||
puts("-ls - enable libsodium");
|
puts("-ls - enable libsodium");
|
||||||
puts("-ck <pubkey_file> - connect to server expecting this public key");
|
puts("-ck <pubkey_file> - connect to server expecting this public key");
|
||||||
puts("-sk <pubkey> <seckey> - start with pub/sec key pair");
|
puts("-sk <pubkey> <seckey> - start with pub/sec key pair");
|
||||||
|
puts("-p <\"fallback\" or \"strict\"> - set auth policy");
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep_seconds(unsigned int seconds) {
|
void sleep_seconds(unsigned int seconds) {
|
||||||
|
@ -55,6 +57,8 @@ int main(int argc, char **argv) {
|
||||||
const char *seckey_file = NULL;
|
const char *seckey_file = NULL;
|
||||||
unsigned char pubkey[crypto_sign_PUBLICKEYBYTES];
|
unsigned char pubkey[crypto_sign_PUBLICKEYBYTES];
|
||||||
unsigned char seckey[crypto_sign_SECRETKEYBYTES];
|
unsigned char seckey[crypto_sign_SECRETKEYBYTES];
|
||||||
|
int authPolicy = UDPC_AUTH_POLICY_FALLBACK;
|
||||||
|
|
||||||
while(argc > 0) {
|
while(argc > 0) {
|
||||||
if(strcmp(argv[0], "-c") == 0) {
|
if(strcmp(argv[0], "-c") == 0) {
|
||||||
isClient = 1;
|
isClient = 1;
|
||||||
|
@ -113,6 +117,18 @@ int main(int argc, char **argv) {
|
||||||
pubkey_file = argv[0];
|
pubkey_file = argv[0];
|
||||||
--argc; ++argv;
|
--argc; ++argv;
|
||||||
seckey_file = argv[0];
|
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 {
|
} else {
|
||||||
printf("ERROR: invalid argument \"%s\"\n", argv[0]);
|
printf("ERROR: invalid argument \"%s\"\n", argv[0]);
|
||||||
usage();
|
usage();
|
||||||
|
@ -196,6 +212,14 @@ int main(int argc, char **argv) {
|
||||||
puts("Set pubkey/seckey for server");
|
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);
|
UDPC_enable_threaded_update(context);
|
||||||
|
|
||||||
unsigned int tick = 0;
|
unsigned int tick = 0;
|
||||||
|
|
Loading…
Reference in a new issue