X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=src%2Fserver%2Fserver.c;h=2bcd8d3e7e0c60f82cd4337c5bd934b32b750d30;hb=de8c5fd93c75b8611cba5530b255a3dcfd97db41;hp=3169ca0fa9b98ef0e649002212c5167e34e1ee86;hpb=bd4eed9ef150a921ee80121522a1a7918739b720;p=tpg%2Fopendispense2.git diff --git a/src/server/server.c b/src/server/server.c index 3169ca0..2bcd8d3 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -18,8 +18,9 @@ #include #include #include -#include -#include +#include // Signal handling +#include // AUTHIDENT +#include // time(2) #define DEBUG_TRACE_CLIENT 0 #define HACK_NO_REFUNDS 1 @@ -34,13 +35,17 @@ #define MSG_STR_TOO_LONG "499 Command too long (limit "EXPSTR(INPUT_BUFFER_SIZE)")\n" +#define IDENT_TRUSTED_NETWORK 0x825F0D00 +#define IDENT_TRUSTED_NETMASK 0xFFFFFFC0 + // === TYPES === typedef struct sClient { int Socket; // Client socket ID int ID; // Client ID - int bIsTrusted; // Is the connection from a trusted host/port + int bTrustedHost; + int bCanAutoAuth; // Is the connection from a trusted host/port char *Username; char Salt[9]; @@ -53,7 +58,7 @@ typedef struct sClient // === PROTOTYPES === void Server_Start(void); void Server_Cleanup(void); -void Server_HandleClient(int Socket, int bTrusted); +void Server_HandleClient(int Socket, int bTrustedHost, int bRootPort); void Server_ParseClientCommand(tClient *Client, char *CommandString); // --- Commands --- void Server_Cmd_USER(tClient *Client, char *Args); @@ -114,6 +119,8 @@ const struct sClientCommand { int gbServer_RunInBackground = 0; char *gsServer_LogFile = "/var/log/dispsrv.log"; char *gsServer_ErrorLog = "/var/log/dispsrv.err"; + int giServer_NumTrustedHosts; +struct in_addr *gaServer_TrustedHosts; // - State variables int giServer_Socket; // Server socket int giServer_NextClientID = 1; // Debug client ID @@ -128,6 +135,19 @@ void Server_Start(void) int client_socket; struct sockaddr_in server_addr, client_addr; + // Parse trusted hosts list + giServer_NumTrustedHosts = Config_GetValueCount("trusted_host"); + gaServer_TrustedHosts = malloc(giServer_NumTrustedHosts * sizeof(*gaServer_TrustedHosts)); + for( int i = 0; i < giServer_NumTrustedHosts; i ++ ) + { + const char *addr = Config_GetValue("trusted_host", i); + + if( inet_aton(addr, &gaServer_TrustedHosts[i]) == 0 ) { + fprintf(stderr, "Invalid IP address '%s'\n", addr); + continue ; + } + } + atexit(Server_Cleanup); // Ignore SIGPIPE (stops crashes when the client exits early) signal(SIGPIPE, SIG_IGN); @@ -163,6 +183,7 @@ void Server_Start(void) } if( pid != 0 ) { // Parent, quit + printf("Forked child %i\n", pid); exit(0); } // In child @@ -175,6 +196,8 @@ void Server_Start(void) freopen("/dev/null", "r", stdin); freopen(gsServer_LogFile, "a", stdout); freopen(gsServer_ErrorLog, "a", stderr); + fprintf(stdout, "OpenDispense 2 Server Started at %lld\n", (long long)time(NULL)); + fprintf(stderr, "OpenDispense 2 Server Started at %lld\n", (long long)time(NULL)); #endif } @@ -203,6 +226,7 @@ void Server_Start(void) { uint len = sizeof(client_addr); int bTrusted = 0; + int bRootPort = 0; // Accept a connection client_socket = accept(giServer_Socket, (struct sockaddr *) &client_addr, &len); @@ -234,9 +258,22 @@ void Server_Start(void) // Doesn't matter what, localhost is trusted if( ntohl( client_addr.sin_addr.s_addr ) == 0x7F000001 ) bTrusted = 1; - - // Trusted Connections + + // Check if the host is on the trusted list + for( int i = 0; i < giServer_NumTrustedHosts; i ++ ) + { + if( memcmp(&client_addr.sin_addr, &gaServer_TrustedHosts[i], sizeof(struct in_addr)) == 0 ) + { + bTrusted = 1; + break; + } + } + + // Root port (can AUTOAUTH if also a trusted machine if( ntohs(client_addr.sin_port) < 1024 ) + bRootPort = 1; + + #if 0 { // TODO: Make this runtime configurable switch( ntohl( client_addr.sin_addr.s_addr ) ) @@ -257,9 +294,10 @@ void Server_Start(void) break; } } + #endif // TODO: Multithread this? - Server_HandleClient(client_socket, bTrusted); + Server_HandleClient(client_socket, bTrusted, bRootPort); close(client_socket); } @@ -277,7 +315,7 @@ void Server_Cleanup(void) * \param Socket Client socket number/handle * \param bTrusted Is the client trusted? */ -void Server_HandleClient(int Socket, int bTrusted) +void Server_HandleClient(int Socket, int bTrusted, int bRootPort) { char inbuf[INPUT_BUFFER_SIZE]; char *buf = inbuf; @@ -290,7 +328,8 @@ void Server_HandleClient(int Socket, int bTrusted) // Initialise Client info clientInfo.Socket = Socket; clientInfo.ID = giServer_NextClientID ++; - clientInfo.bIsTrusted = bTrusted; + clientInfo.bTrustedHost = bTrusted; + clientInfo.bCanAutoAuth = bTrusted && bRootPort; clientInfo.EffectiveUID = -1; // Read from client @@ -485,7 +524,7 @@ void Server_Cmd_AUTOAUTH(tClient *Client, char *Args) } // Check if trusted - if( !Client->bIsTrusted ) { + if( !Client->bCanAutoAuth ) { if(giDebugLevel) Debug(Client, "Untrusted client attempting to AUTOAUTH"); sendf(Client->Socket, "401 Untrusted\n"); @@ -548,7 +587,7 @@ void Server_Cmd_AUTHIDENT(tClient *Client, char *Args) } // Check if trusted - if( !Client->bIsTrusted ) { + if( !Client->bTrustedHost ) { if(giDebugLevel) Debug(Client, "Untrusted client attempting to AUTHIDENT"); sendf(Client->Socket, "401 Untrusted\n"); @@ -557,8 +596,10 @@ void Server_Cmd_AUTHIDENT(tClient *Client, char *Args) // Get username via IDENT username = ident_id(Client->Socket, ident_timeout); - if (!username) { + if( !username ) { + perror("AUTHIDENT - IDENT timed out"); sendf(Client->Socket, "403 Authentication failure: IDENT auth timed out\n"); + return ; } // Get UID @@ -659,6 +700,13 @@ void Server_Cmd_SETEUSER(tClient *Client, char *Args) return ; } } + + // Disabled accounts + if( userFlags & USER_FLAG_DISABLED ) { + Client->UID = -1; + sendf(Client->Socket, "403 Account disabled\n"); + return ; + } sendf(Client->Socket, "200 User set\n"); } @@ -683,6 +731,8 @@ void Server_int_SendItem(tClient *Client, tItem *Item) } } + if( Item->Price == 0 ) + status = "error"; // KNOWN HACK: Naming a slot 'dead' disables it if( strcmp(Item->Name, "dead") == 0 ) status = "sold"; // Another status?