/* $CoreSDI: auth_raw.c,v 1.19 2001/09/06 21:46:25 claudio Exp $ */ /* * Copyright (c) 2000, 2001, Core SDI S.A., Argentina * All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. Neither name of the Core SDI S.A. 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 AUTHOR ``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 AUTHOR 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. */ /* * Raw Authentication Module * Author: Claudio Castiglia */ #ifndef WIN32 /* Unix */ #include #ifdef __linux__ #include /* in_addr_t */ #endif #include #include #include #include #include #include #include #include #ifdef HAVE_SHADOW #include #endif #else /* Win32 */ #include #include #include #include #include #include "exits.h" #endif /* WIN32 */ #include "sysdep.h" #include "packet.h" #include "resource.h" #include "modtypes.h" #include "authargs.h" #include "commands.h" #ifndef AUDIT_GROUPNAME #define AUDIT_GROUPNAME "audit" #endif #ifdef HAVE_SHADOW struct _passwd { char *pw_name; /* user name */ char *pw_passwd; /* encrypted password */ uid_t pw_uid; /* user uid */ gid_t pw_gid; /* user gid */ time_t pw_change; /* password change time */ char *pw_class; /* user access class */ char *pw_gecos; /* Honeywell login info */ char *pw_dir; /* home directory */ char *pw_shell; /* default shell */ time_t pw_expire; /* account expiration */ }; extern char * crypt (const char *, const char *); static struct _passwd * _getpwnam(const char *login) { static struct _passwd pw; struct passwd *np; struct spwd *sp; if ( (np = getpwnam(login)) == NULL) return (NULL); pw.pw_name = np->pw_name; pw.pw_uid = np->pw_uid; pw.pw_gid = np->pw_gid; pw.pw_shell = np->pw_shell; if (np->pw_passwd[0] == 'x') { if ( (sp = getspnam(login)) == NULL) return (NULL); pw.pw_passwd = sp->sp_pwdp; } else pw.pw_passwd = np->pw_passwd; return (&pw); } #else #define _getpwnam getpwnam #define _passwd passwd #endif /* HAVE_SHADOW */ /* * _auth_srvr() * Server side authentication. * return 0 on success or -1 if login failed. */ static int _auth_srvr(AUTHCON *ct) { #ifndef WIN32 /* Unix */ int32_t srvr_ok; char hostname[MAXHOSTNAMELEN] = { "" }, clntpass[_PASSWORD_LEN + 1], **m; struct group *gp; struct _passwd *pw; /* XXX move to engine: Send server hostname to the client */ gethostname(hostname, sizeof(hostname)); packet_put_string(ct->packet, hostname); /* Receive client username and password */ packet_get_string(ct->packet, ct->peername, sizeof(ct->peername)); packet_get_string(ct->packet, clntpass, sizeof(clntpass)); /* * No access if AUDIT_GROUPNAME does not exists; * no access if user does not exists in /etc/passwd. */ srvr_ok = LOGIN_SUCCESS; if ( (gp = getgrnam(AUDIT_GROUPNAME)) == NULL || (pw = _getpwnam(ct->peername)) == NULL) srvr_ok = LOGIN_FAILED; else { /* * No access if user does not belongs * to the AUDIT_GROUPNAME group. */ for (m = gp->gr_mem; *m != NULL; m++) if (!strcmp(*m, ct->peername)) break; if (*m == NULL) srvr_ok = LOGIN_FAILED; } /* No access if password is not correct */ if (srvr_ok == LOGIN_SUCCESS && strcmp(pw->pw_passwd, crypt(clntpass, pw->pw_passwd))) srvr_ok = LOGIN_FAILED; /* Send login status to the client */ packet_put_int32(ct->packet, srvr_ok); return ((srvr_ok == LOGIN_SUCCESS) ? 0 : -1); #else /* Win32 */ return (-1); #endif /* WIN32 */ } /* * _auth_clnt() * Client side authentication; * return 0 on success or -1 if permission denied. */ static int _auth_clnt(AUTHCON *ct, struct autharg_clnt *args) { int32_t login_status; /* XXX: move to engine: Get server hostnmae */ packet_get_string(ct->packet, ct->peername, sizeof(ct->peername)); /* Get username */ if (args->user[0] == '\0') { fprintf(stderr, "login: "); fgets(args->user, sizeof(args->user), stdin); args->user[strlen(args->user) - 1] = '\0'; } /* Get password */ if (args->pass[0] == '\0') { char *pass; fprintf(stderr, "password: "); pass = (char *) getpass(""); strlcpy(args->pass, pass, sizeof(args->pass)); bzero(pass, _PASSWORD_LEN); } /* Send username and password to the server */ packet_put_string(ct->packet, args->user); packet_put_string(ct->packet, args->pass); bzero(args->pass, sizeof(args->pass)); /* Receive server authentication status */ packet_get_int32(ct->packet, &login_status); return ((login_status == LOGIN_SUCCESS) ? 0 : -1); } /* * init() */ EXPORT AUTHCON * init() { return ((AUTHCON *) malloc(sizeof(AUTHCON))); } /* * proc_entry() */ EXPORT int proc_entry(int opcode, AUTHCON *context, void *args) { if (context == NULL) { errno = EINVAL; return (-1); } switch (opcode) { case AUTH_SERVER: /* Authentication process: server side */ return (_auth_srvr(context)); case AUTH_CLIENT: /* Authentication process: client side */ return (_auth_clnt(context, args)); case AUTH_FILTER_RESOURCE: /* Raw module does not filter any resource */ ((struct autharg_filter *) args)->fvalue = NULL; ((struct autharg_filter *) args)->fvsize = 0; return (0); default: errno = EINVAL; } return (-1); }