From: Urban Wallasch Date: Fri, 1 Jun 2018 13:25:52 +0000 (+0200) Subject: * Converted line endings to LF. X-Git-Url: https://git.packet-gain.de/?a=commitdiff_plain;ds=inline;p=fident.git * Converted line endings to LF. --- diff --git a/fident.c b/fident.c index 16c5277..23362d3 100644 --- a/fident.c +++ b/fident.c @@ -1,204 +1,204 @@ -#define _DEFAULT_SOURCE - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifdef DEBUG - #define DPRINT(...) do{ fprintf( stderr, __VA_ARGS__ ); }while(0) -#else - #define DPRINT(...) do{;}while(0) -#endif - -typedef - struct { - int sd; - struct sockaddr_in addr; - socklen_t addrlen; - } - srvarg_t; - -static void die( const char *msg ) -{ - perror( msg ); - exit( EXIT_FAILURE ); -} - -static void droproot( const char *uname, const char *gname ) -{ - const struct group *gr = getgrnam( gname ); - const struct passwd *pw = getpwnam( uname ); - - if ( NULL == gr ) - die( gname ); - if ( NULL == pw ) - die( uname ); - - const gid_t newgid = gr->gr_gid; - const uid_t newuid = pw->pw_uid; - const gid_t oldgid = getegid(); - const uid_t olduid = geteuid(); - - if ( 0 == olduid ) - setgroups( 1, &newgid ); - if ( newgid != oldgid && 0 != setregid( newgid, newgid ) ) - die( "setregid" ); - if ( newuid != olduid && 0 != setreuid( newuid, newuid ) ) - die( "setreuid" ); - - /* Check by trying to regain old IDs: */ - if ( newgid != oldgid && ( 0 == setegid( oldgid ) || getegid() != newgid ) ) - die( "setegid" ); - if ( newuid != olduid && ( 0 == seteuid( olduid ) || geteuid() != newuid ) ) - die( "seteuid" ); - - DPRINT( "EGID=%d, EUID=%d\n", getegid(), geteuid() ); -} - - -// #define DFLT_MSG "ERROR : UNKNOWN-ERROR" -#define DFLT_MSG "USERID : OTHER : UNKNOWN" - -static void *servlet( void *parg ) -{ - srvarg_t *arg = parg; - uint16_t ps = 0, pc = 0; - int sd = arg->sd; - ssize_t rb = 0; - char buf[200] = ""; - char rsp[400] = ""; - char *ep = NULL; - struct timeval timeout; - - timeout.tv_sec = 3; - timeout.tv_usec = 0; - setsockopt( sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout ); - DPRINT( "(%s:%d) ", inet_ntoa( arg->addr.sin_addr ), (int)arg->addr.sin_port ); - rb = recv( sd, buf, sizeof buf - 1, 0 ); - if ( 0 < rb ) - { - buf[rb] = '\0'; - ep = buf; - while ( *ep ) - if ( '\r' == *ep || '\n' == *ep ) - *ep = '\0'; - else - ++ep; - DPRINT( "[%s] ", buf ); - if ( 2 == sscanf( buf, "%"SCNu16" ,%"SCNu16" ", &ps, &pc ) - && 0 < snprintf( rsp, sizeof rsp, "%"PRIu16" , %"PRIu16" : %s\r\n", ps, pc, DFLT_MSG ) ) - { - DPRINT( "%s", rsp ); - send( sd, rsp, strlen( rsp ), 0 ); - } - } - DPRINT( "%s", *rsp ? "" : "\n" ); - close( sd ); - free( parg ); - return 0; -} - -int main( int argc, char *argv[] ) -{ - struct sockaddr_in addr; - int sd, port; - const int enable = 1; - - if ( argc != 2 ) - { - fprintf( stderr, "usage: %s \n", argv[0] ); - exit( EXIT_FAILURE ); - } - - if ( !isdigit( argv[1][0] ) ) - { - struct servent *srv = getservbyname( argv[1], "tcp" ); - if ( srv == NULL ) - die( argv[1] ); - DPRINT( "%s: port=%d\n", srv->s_name, ntohs( srv->s_port ) ); - port = srv->s_port; - } - else - { - port = atoi( argv[1] ); - DPRINT( "port=%d\n", port ); - port = htons( port ); - } - - sd = socket( PF_INET, SOCK_STREAM, 0 ); - if ( sd < 0 ) - die( "socket" ); - if ( 0 > setsockopt( sd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof enable ) ) - die( "setsockopt(SO_REUSEADDR)" ); - - memset( &addr, 0, sizeof addr ); - addr.sin_family = AF_INET; - addr.sin_port = port; - addr.sin_addr.s_addr = INADDR_ANY; - if ( bind( sd, (struct sockaddr*)&addr, sizeof addr ) != 0 ) - die( "bind" ); - - droproot( "nobody", "nogroup" ); - - if ( listen( sd, 10 ) != 0 ) - die( "listen" ); - - puts( "" ); - - while ( 1 ) - { - int csd; - socklen_t addrlen = sizeof addr; - - if ( 0 > ( csd = accept( sd, (struct sockaddr *)&addr, &addrlen ) ) ) - { - switch ( errno ) - { - case EBADF: - case EFAULT: - case EINVAL: - case ENOTSOCK: - case EOPNOTSUPP: - case EPROTO: - die( "accept" ); - break; - default: - break; - } - } - else - { - srvarg_t *parg; - pthread_t child; - - if ( NULL != ( parg = malloc( sizeof *parg ) ) ) - { - if ( sizeof addr < addrlen ) - addrlen = sizeof addr; - memcpy( &parg->addr, &addr, addrlen ); - parg->addrlen = addrlen; - parg->sd = csd; - if ( 0 != pthread_create( &child, 0, servlet, (void *)parg ) ) - free( parg ); - else /* parg is free'd in child! */ - pthread_detach( child ); - } - } - sleep( 1 ); /* hard throttle */ - } -} +#define _DEFAULT_SOURCE + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef DEBUG + #define DPRINT(...) do{ fprintf( stderr, __VA_ARGS__ ); }while(0) +#else + #define DPRINT(...) do{;}while(0) +#endif + +typedef + struct { + int sd; + struct sockaddr_in addr; + socklen_t addrlen; + } + srvarg_t; + +static void die( const char *msg ) +{ + perror( msg ); + exit( EXIT_FAILURE ); +} + +static void droproot( const char *uname, const char *gname ) +{ + const struct group *gr = getgrnam( gname ); + const struct passwd *pw = getpwnam( uname ); + + if ( NULL == gr ) + die( gname ); + if ( NULL == pw ) + die( uname ); + + const gid_t newgid = gr->gr_gid; + const uid_t newuid = pw->pw_uid; + const gid_t oldgid = getegid(); + const uid_t olduid = geteuid(); + + if ( 0 == olduid ) + setgroups( 1, &newgid ); + if ( newgid != oldgid && 0 != setregid( newgid, newgid ) ) + die( "setregid" ); + if ( newuid != olduid && 0 != setreuid( newuid, newuid ) ) + die( "setreuid" ); + + /* Check by trying to regain old IDs: */ + if ( newgid != oldgid && ( 0 == setegid( oldgid ) || getegid() != newgid ) ) + die( "setegid" ); + if ( newuid != olduid && ( 0 == seteuid( olduid ) || geteuid() != newuid ) ) + die( "seteuid" ); + + DPRINT( "EGID=%d, EUID=%d\n", getegid(), geteuid() ); +} + + +// #define DFLT_MSG "ERROR : UNKNOWN-ERROR" +#define DFLT_MSG "USERID : OTHER : UNKNOWN" + +static void *servlet( void *parg ) +{ + srvarg_t *arg = parg; + uint16_t ps = 0, pc = 0; + int sd = arg->sd; + ssize_t rb = 0; + char buf[200] = ""; + char rsp[400] = ""; + char *ep = NULL; + struct timeval timeout; + + timeout.tv_sec = 3; + timeout.tv_usec = 0; + setsockopt( sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout ); + DPRINT( "(%s:%d) ", inet_ntoa( arg->addr.sin_addr ), (int)arg->addr.sin_port ); + rb = recv( sd, buf, sizeof buf - 1, 0 ); + if ( 0 < rb ) + { + buf[rb] = '\0'; + ep = buf; + while ( *ep ) + if ( '\r' == *ep || '\n' == *ep ) + *ep = '\0'; + else + ++ep; + DPRINT( "[%s] ", buf ); + if ( 2 == sscanf( buf, "%"SCNu16" ,%"SCNu16" ", &ps, &pc ) + && 0 < snprintf( rsp, sizeof rsp, "%"PRIu16" , %"PRIu16" : %s\r\n", ps, pc, DFLT_MSG ) ) + { + DPRINT( "%s", rsp ); + send( sd, rsp, strlen( rsp ), 0 ); + } + } + DPRINT( "%s", *rsp ? "" : "\n" ); + close( sd ); + free( parg ); + return 0; +} + +int main( int argc, char *argv[] ) +{ + struct sockaddr_in addr; + int sd, port; + const int enable = 1; + + if ( argc != 2 ) + { + fprintf( stderr, "usage: %s \n", argv[0] ); + exit( EXIT_FAILURE ); + } + + if ( !isdigit( argv[1][0] ) ) + { + struct servent *srv = getservbyname( argv[1], "tcp" ); + if ( srv == NULL ) + die( argv[1] ); + DPRINT( "%s: port=%d\n", srv->s_name, ntohs( srv->s_port ) ); + port = srv->s_port; + } + else + { + port = atoi( argv[1] ); + DPRINT( "port=%d\n", port ); + port = htons( port ); + } + + sd = socket( PF_INET, SOCK_STREAM, 0 ); + if ( sd < 0 ) + die( "socket" ); + if ( 0 > setsockopt( sd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof enable ) ) + die( "setsockopt(SO_REUSEADDR)" ); + + memset( &addr, 0, sizeof addr ); + addr.sin_family = AF_INET; + addr.sin_port = port; + addr.sin_addr.s_addr = INADDR_ANY; + if ( bind( sd, (struct sockaddr*)&addr, sizeof addr ) != 0 ) + die( "bind" ); + + droproot( "nobody", "nogroup" ); + + if ( listen( sd, 10 ) != 0 ) + die( "listen" ); + + puts( "" ); + + while ( 1 ) + { + int csd; + socklen_t addrlen = sizeof addr; + + if ( 0 > ( csd = accept( sd, (struct sockaddr *)&addr, &addrlen ) ) ) + { + switch ( errno ) + { + case EBADF: + case EFAULT: + case EINVAL: + case ENOTSOCK: + case EOPNOTSUPP: + case EPROTO: + die( "accept" ); + break; + default: + break; + } + } + else + { + srvarg_t *parg; + pthread_t child; + + if ( NULL != ( parg = malloc( sizeof *parg ) ) ) + { + if ( sizeof addr < addrlen ) + addrlen = sizeof addr; + memcpy( &parg->addr, &addr, addrlen ); + parg->addrlen = addrlen; + parg->sd = csd; + if ( 0 != pthread_create( &child, 0, servlet, (void *)parg ) ) + free( parg ); + else /* parg is free'd in child! */ + pthread_detach( child ); + } + } + sleep( 1 ); /* hard throttle */ + } +}