/** * A client-side 802.1x implementation supporting EAP/TLS * * This code is released under both the GPL version 2 and BSD licenses. * Either license may be used. The respective licenses are found below. * * Copyright (C) 2002 Bryan D. Payne & Nick L. Petroni Jr. * All Rights Reserved * * --- GPL Version 2 License --- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * --- BSD License --- * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * Maryland at College Park and its contributors. * - Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /******************************************************************* * The driver function for a Linux application layer EAPOL * implementation * File: 1xdriver.c * * Authors: bdpayne@cs.umd.edu, npetroni@cs.umd.edu * * $Id: 1xdriver.c,v 1.19 2003/03/02 20:13:04 npetroni Exp $ * $Date: 2003/03/02 20:13:04 $ * $Log: 1xdriver.c,v $ * Revision 1.19 2003/03/02 20:13:04 npetroni * increased error checking for a number of function calls * fixed tls to set ctx = NULL after freeing it (redundant free's segfault) * * Revision 1.18 2003/02/27 04:05:54 chessing * Added more error checking, fixed a few omissions that have not yet caused bugs. ;) * * Revision 1.17 2003/02/17 19:32:45 chessing * Added the -m (NAK) option support by default, fixed a few cosmetic bugs in the MD5 code, and fixed build process with the new 1xdaemon.c code. * * Revision 1.16 2003/02/11 00:25:21 galimorerpg * GCC 2.95.3 Fixes. * * Revision 1.15 2003/02/10 02:08:00 galimorerpg * Memory leak fix. * * Revision 1.14 2003/02/10 01:57:53 galimorerpg * Double free fix. * Code cleanups. * * Revision 1.13 2003/02/10 00:16:50 galimorerpg * Configuration parsing checks. We now recover from some potential segfaults. * * Revision 1.12 2003/02/08 00:58:59 galimorerpg * Fixes for 1xdaemon.c (we now catch the SIGPIPE) * * Revision 1.11 2003/02/07 22:17:29 galimorerpg * Socket code to allow for daemonizing has been added. * * Revision 1.10 2003/02/04 20:17:38 galimorerpg * 02/04/03: * Modifications to allow daemonization have been implemented: * 1xdriver.c now sets up a server socket to listen for a front end connection for clients wishing to control the authentication process. * eapol.c: Fixed a bug in eapol_authenticate() that caused the main event loop in 1xdriver.c to stop functioning until the next auth cycle. * ChangeLog Updates. * * Revision 1.9 2003/01/09 23:09:22 galimorerpg * Logging Updates. * * Revision 1.8 2003/01/09 21:01:58 galimorerpg * Logging Updates and Build Fixes. * * Revision 1.7 2003/01/09 20:50:15 chessing * Code cleanups. * * Revision 1.6 2003/01/09 20:48:32 galimorerpg * Logging updates. * * Revision 1.5 2003/01/09 20:17:23 galimorerpg * Logging Updates * * Revision 1.4 2003/01/03 22:25:35 chessing * Turned off debugging code, (use the configure options to turn on the debugging) and added -w option to get around some problems with the Intel iANS drivers, and some wired/wireless issues with the MacOS-X wireless code. * * Revision 1.3 2003/01/02 19:29:37 chessing * Update to bring the xsupplicant code current with the development work. * * *******************************************************************/ /*** *** This code implements 802.1X Authentication on a supplicant *** and supports multiple Authentication types. *** See IEEE Draft P802.1X/D11, March 27, 2001 for more details ***/ #include #include #include #include #include #include #include "eapol.h" #include "configparse.h" #include "userconf.h" #include "logging.h" #include "1xdaemon.h" #ifndef DEBUG_1XDRIVER #define DEBUG_1XDRIVER 1 #endif char pidfileName[100] = "/var/run/"; int pidFileSet = 0; extern char * optarg; /* argument from getopt */ void usage(char *prog) { char *temp; xlogf(DEBUG_NORMAL, "Usage: %s " "[-w]" "[-a authenticator_MAC_address] " "[-c config file] " "[-i device] " "[-n network_id] " "[-u user_name] " "[-p password] " "[-d debug_level] " "[-m authentication_type] " "\n", prog); temp = (char *)return_known_eap_types(); xlogf(DEBUG_NORMAL, "\n\nThe following EAP types are understood : %s\n", temp); free(temp); temp = NULL; } void exit_cleanly(int the_signal) { if (pidFileSet) unlink(pidfileName); close(msgSock); close(serverSock); eapol_shutdown(); clean_user_conf(); exit(0); } int main(int argc, char * argv[]) { int ret, op; char * theOpts = "m:p:u:a:c:i:n:d:Dw"; char *netid = NULL, *device = NULL, *config = NULL; u_char *dstAddr = NULL; u_char *auth_addr = NULL; int daemon = 0; /* no daemon by default */ int m0=0,m1=0,m2=0,m3=0,m4=0,m5=0; FILE *pidfile = NULL; int pid; char *temp; netid = malloc(8); if(netid) { strcpy(netid, "default"); } config = malloc(16); if(config) { strcpy(config, "/etc/1x/1x.conf"); } initalize_user_conf(); // Set up our user information structure. /* check for existing copies of the program */ /**** Command Line Parsing ****/ while ((op = getopt(argc, argv, theOpts)) != EOF) { switch(op) { case 'a': dstAddr = optarg; break; case 'c': if(config != NULL) { free(config); } config = optarg; break; case 'd': debug_level = atoi(optarg); break; case 'i': device = optarg; break; case 'n': if(netid != NULL) { free(netid); } netid = optarg; break; case 'D': daemon = 1; break; case 'u': set_username(optarg); xlogf(DEBUG_NORMAL, "Username override! Using username %s\n", optarg); break; case 'p': set_password(optarg); xlogf(DEBUG_NORMAL, "Password passed in from command line! (This isn't very secure!)\n"); break; case 'm': set_preferred_auth(optarg); temp = get_preferred_auth(); xlogf(DEBUG_NORMAL, "Using preferred authentication method of %s\n",temp); if (is_valid_eap(temp) == -1) // uh, oh.. We don't know this one. { xlogf(DEBUG_NORMAL, "\n\nUnknown EAP type!\n"); free(temp); temp = NULL; return -1; } free(temp); temp = NULL; break; case 'w': //Force this to be a wired connection. temp = (char *)malloc(6); // Enough for WIRED\0 strncpy(temp, "WIRED", 6); set_client_type(temp); free(temp); break; default: usage(argv[0]); return -1; } } strcat(pidfileName, "xsupplicant-"); if (device){ strncat(pidfileName, device, 99-strlen(pidfileName)); pidfileName[99] = '\0'; } pidfile = fopen(pidfileName, "r"); if (pidfile) { fscanf(pidfile, "%d", &pid); xlogf(DEBUG_NORMAL, "Process already running. kill pid %d\n", pid); fclose(pidfile); exit_cleanly(-1); } if(config && netid) { if(parse_all_configs(config, netid) < 0) //Parse the config (default by default) { xlogf(DEBUG_NORMAL, "A config parse error has occured.\nMake sure you are specifying your profile name (with -n) or that a profile named \"default\" exists.\n"); exit_cleanly(-1); } } else { xlogf(DEBUG_NORMAL, "Ack! There's a problem with config or netid in 1xdriver.c... they seem to be NULL.\n"); exit_cleanly(-1); } if (dstAddr != NULL) { auth_addr = (u_char *)malloc(sizeof(u_char) * MY_ETHER_ADDR_LEN); sscanf(dstAddr, "%x:%x:%x:%x:%x:%x", &m0, &m1, &m2, &m3, &m4, &m5); auth_addr[0] = m0; auth_addr[1] = m1; auth_addr[2] = m2; auth_addr[3] = m3; auth_addr[4] = m4; auth_addr[5] = m5; } /**** Begin EAPOL Conversation ****/ if ((ret = init_eapol(device, netid, auth_addr, config)) == -1) { free(auth_addr); auth_addr = NULL; exit_cleanly(-1); } signal(SIGTERM, exit_cleanly); signal(SIGINT, exit_cleanly); signal(SIGQUIT, exit_cleanly); if (daemon) { close(0); close(1); close(2); pid = fork(); if (pid > 0) { exit(0); } if (pid < 0) { xlogf(DEBUG_NORMAL, "Failed to spawn daemon. exiting..."); free(auth_addr); auth_addr = NULL; exit_cleanly(-1); } } pidfile = fopen(pidfileName, "w"); if (!pidfile) { xlogf(DEBUG_NORMAL, "Failed to create file %s\n", pidfileName); free(auth_addr); auth_addr = NULL; exit_cleanly(-1); } fprintf(pidfile, "%d\n", getpid()); pidFileSet = 1; fclose(pidfile); serverSock = serverSockInit(); // Set up our non-blocking server socket if(serverSock == -1) { xlogf(DEBUG_NORMAL, "Server Socket Setup Failure in 1xdriver.c\n"); exit_cleanly(-1); } while (eapol_authenticate() == 0) // Loop through, and try to authenticate. { handleMessages(); // Handle daemon front end messages. } free(auth_addr); auth_addr = NULL; exit_cleanly(ret); return 0; //We never get here, but this will silence compiler warnings. } /** EOF **/