From: Alexander Barton Date: Mon, 12 Jul 2010 10:53:08 +0000 (+0200) Subject: Add pam.{c|h} to project and implement PAM_Authenticate() function X-Git-Tag: rel-17-rc1~69 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=77870ddf2d87ddf222d87b58cb9afdf0609d49dd Add pam.{c|h} to project and implement PAM_Authenticate() function --- diff --git a/src/ngircd/Makefile.am b/src/ngircd/Makefile.am index 2bce2924..4c9d9fa0 100644 --- a/src/ngircd/Makefile.am +++ b/src/ngircd/Makefile.am @@ -21,7 +21,7 @@ sbin_PROGRAMS = ngircd ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \ conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \ irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \ - match.c op.c numeric.c parse.c proc.c rendezvous.c resolve.c + match.c op.c numeric.c pam.c parse.c proc.c rendezvous.c resolve.c ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr @@ -30,7 +30,7 @@ ngircd_LDADD = -lngportab -lngtool -lngipaddr noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conf-ssl.h conn.h \ conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \ irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \ - irc-write.h lists.h log.h match.h numeric.h op.h parse.h proc.h \ + irc-write.h lists.h log.h match.h numeric.h op.h pam.h parse.h proc.h \ rendezvous.h resolve.h defines.h messages.h clean-local: diff --git a/src/ngircd/pam.c b/src/ngircd/pam.c new file mode 100644 index 00000000..e6d25bc5 --- /dev/null +++ b/src/ngircd/pam.c @@ -0,0 +1,139 @@ +/* + * ngIRCd -- The Next Generation IRC Daemon + * Copyright (c)2001-2010 Alexander Barton (alex@barton.de). + * + * 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. + * Please read the file COPYING, README and AUTHORS for more information. + * + * PAM User Authentification + */ + +#include "portab.h" + +#ifdef PAM + +#include "imp.h" +#include + +#include "defines.h" +#include "log.h" +#include "conn.h" +#include "client.h" + +#include +#include + +#ifdef HAVE_SECURITY_PAM_APPL_H +#include +#endif + +#ifdef HAVE_PAM_PAM_APPL_H +#include +#endif + +#include "exp.h" +#include "pam.h" + +static char *password; + +/** + * PAM "conversation function". + * This is a callback function used by the PAM library to get the password. + * Please see the PAM documentation for details :-) + */ +static int +password_conversation(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) { + LogDebug("PAM: conv(%d, %d, '%s', '%s')", + num_msg, msg[0]->msg_style, msg[0]->msg, appdata_ptr); + + /* Can we deal with this request? */ + if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) { + Log(LOG_ERR, "PAM: Unexpected PAM conversation '%d:%s'!", + msg[0]->msg_style, msg[0]->msg); + return PAM_CONV_ERR; + } + + if (!appdata_ptr) { + /* Sometimes appdata_ptr gets lost!? */ + appdata_ptr = password; + } + + /* Duplicate password ("application data") for the PAM library */ + *resp = calloc(num_msg, sizeof(struct pam_response)); + if (!*resp) { + Log(LOG_ERR, "PAM: Out of memory!"); + return PAM_CONV_ERR; + } + + (*resp)[0].resp = strdup((char *)appdata_ptr); + (*resp)[0].resp_retcode = 0; + + return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR); +} + +/** + * PAM "conversation" structure. + */ +static struct pam_conv conv = { + &password_conversation, + NULL +}; + +/** + * Authenticate a connectiong client using PAM. + * @param Client The client to authenticate. + * @return true when authentication succeeded, false otherwise. + */ +GLOBAL bool +PAM_Authenticate(CLIENT *Client) { + pam_handle_t *pam; + int retval = PAM_SUCCESS; + + LogDebug("PAM: Authenticate \"%s\" (%s) ...", + Client_OrigUser(Client), Client_Mask(Client)); + + /* Set supplied client password */ + if (password) + free(password); + password = strdup(Client_Password(Client)); + conv.appdata_ptr = password; + + /* Initialize PAM */ + retval = pam_start("ngircd", Client_OrigUser(Client), &conv, &pam); + if (retval != PAM_SUCCESS) { + Log(LOG_ERR, "PAM: Failed to create authenticator! (%d)", retval); + return false; + } + + pam_set_item(pam, PAM_RUSER, Client_User(Client)); + pam_set_item(pam, PAM_RHOST, Client_Hostname(Client)); +#ifdef HAVE_PAM_FAIL_DELAY + pam_fail_delay(pam, 0); +#endif + + /* PAM authentication ... */ + retval = pam_authenticate(pam, 0); + + /* Success? */ + if (retval == PAM_SUCCESS) + Log(LOG_INFO, "PAM: Authenticated \"%s\" (%s).", + Client_OrigUser(Client), Client_Mask(Client)); + else + Log(LOG_ERR, "PAM: Error on \"%s\" (%s): %s", + Client_OrigUser(Client), Client_Mask(Client), + pam_strerror(pam, retval)); + + /* Free PAM structures */ + if (pam_end(pam, retval) != PAM_SUCCESS) + Log(LOG_ERR, "PAM: Failed to release authenticator!"); + + return (retval == PAM_SUCCESS); +} + +#endif /* PAM */ + +/* -eof- */ diff --git a/src/ngircd/pam.h b/src/ngircd/pam.h new file mode 100644 index 00000000..74b838d0 --- /dev/null +++ b/src/ngircd/pam.h @@ -0,0 +1,25 @@ +/* + * ngIRCd -- The Next Generation IRC Daemon + * Copyright (c)2001-2010 Alexander Barton (alex@barton.de). + * + * 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. + * Please read the file COPYING, README and AUTHORS for more information. + * + * PAM User Authentification (header) + */ + +#ifdef PAM + +#ifndef __pam_h__ +#define __pam_h__ + +GLOBAL bool PAM_Authenticate PARAMS((CLIENT *Client)); + +#endif /* __pam_h__ */ + +#endif /* PAM */ + +/* -eof- */