Impl auth-policy for handling with(out) auth

This commit is contained in:
Stephen Seo 2019-12-09 21:27:58 +09:00
parent d94b44e4de
commit 7c444cb460
4 changed files with 121 additions and 2 deletions

View file

@ -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];

View file

@ -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);
} }

View file

@ -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);

View file

@ -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;