/* you'll need to compile testdaemon.c with this... * * gcc -otestdaemon testdaemon.c authlocal.c -DUSE_AUTHLOCAL */ /* testdaemon.c - This short example shows how to use the authlocal module to automatically authenticate TCP/IP connections coming in from localhost. Copyright (C) January 2000 Jeremy D. Monin. http://shadowlands.org/authlocal/ authlocal is used in the Shadowlands Forum chatroom software. http://shadowlands.org/forum/ for more info. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define socket_arg3_t unsigned int #ifndef USE_AUTHLOCAL #error "You must define USE_AUTHLOCAL when compiling; otherwise, why bother?" #endif #include #include /* for atoi */ #include /* for write, close */ #include /* for errno */ #include /* for strerror */ #include /* for passwd struct */ #include #include #include #include #include "authlocal.h" /* for getUID */ int server_fd; /* server socket FD */ int port; /* port # we're listening on */ static struct in_addr localhost_ip; /* address for localhost */ /* util: write a buffer's contents to socket fd (from slforum.cc) */ int lpwrite( int fd, const char *buf) { int sz = (int) strlen(buf); const char *b= buf; int todo=sz; int done=0; while( todo>0 ) { int cnt=write( fd, b, sz ); if( cnt<0 && errno!=EINTR && errno!=EAGAIN) { done=-1; /* error! */ break; } if( cnt>0 ) { todo-=cnt; done+=cnt; b+=cnt; } } return done; } /* bind to server socket - from slforumroom.cc */ void BindSocket() { int er, len; struct sockaddr_in server_address; server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd == -1) { const char *es; es = strerror(errno); fprintf( stderr, "Could not make socket on port %d: %s\r\n", port, es ); exit(1); } len = sizeof(server_address); memset ((char*) &server_address, '\0', len); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(port); { int one = 1; /* thanks apache sources (main/http_main.c) */ if ((er = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(int)) == -1)) { perror ("couldn't set SO_REUSEADDR, but that's not the end of the world"); errno = 0; } } if ((er = bind(server_fd, (struct sockaddr *)&server_address, len)) != 0) { const char *es = strerror(errno); fprintf( stderr, "Error binding to port %d: %s\r\n", port, es ); exit(1); } listen(server_fd, 8); } /* wait for, accept, handle, and close one client connection to our "server" */ void handle_one_conn () { struct sockaddr_in user_address; socket_arg3_t len = (socket_arg3_t) sizeof(user_address); int user_fd = accept ( server_fd, (struct sockaddr *)&user_address, &len ); if (user_fd == -1) { perror ("couldn't accept connection"); return; } /* We now have a connection; * is it from localhost? * If not, we can't use authlocal. */ if (user_address.sin_addr.s_addr == localhost_ip.s_addr ) { uid_t authenticated; char buf[256]; buf[255] = '\0'; authenticated = getUID ( localhost_ip.s_addr, ntohs(user_address.sin_port), port ); snprintf (buf, 255, "hi user with userid %d\r\n", (int) authenticated); printf ("Connection is from localhost, userid = %d\n", (int) authenticated); lpwrite (user_fd, buf); } else { printf ("Connection not from localhost. (%s)\n", inet_ntoa(user_address.sin_addr) ); lpwrite (user_fd, "Sorry, you're not from localhost.\r\n"); /* in a "real" server, you'd ask for username/password, etc, here */ } /* we're done. Disconnect 'em. */ close (user_fd); } int main(int argc, char **argv) { fprintf (stderr, "%s\n", "testdaemon.c 1.0.0 (c) 2000 Jeremy Monin - http://shadowlands.org/authlocal/\n"); fprintf (stderr, "Test program for authlocal module.\n"); if( argc<2 ) { fprintf( stderr, "usage:\n\t%s port\n", argv[0] ); exit(1); } port=atoi(argv[1]); if (port < 128) { fprintf (stderr, "%s: The port number must be at least 128; you tried %d.\n", argv[0], port ); exit (1); } if (! inet_aton ("127.0.0.1", &localhost_ip)) { perror ("couldn't get localhost IP"); exit (1); } BindSocket(); printf ("Listening on port %d... Ctrl-C to exit\n", port); for ( ;; ) { handle_one_conn(); } return 0; }