mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
Added PAM authentication.
This commit is contained in:
@@ -120,6 +120,9 @@
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Enable the PAM library */
|
||||
#undef HAVE_PAM
|
||||
|
||||
/* Define this if pathfind(3) works */
|
||||
#undef HAVE_PATHFIND
|
||||
|
||||
|
||||
30
configure.ac
30
configure.ac
@@ -11,6 +11,9 @@ AC_PROG_CC
|
||||
gl_EARLY
|
||||
|
||||
AM_PROG_CC_C_O
|
||||
if [ test "$GCC" = "yes" ];then
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.0.0])
|
||||
|
||||
@@ -31,6 +34,22 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
*** ]])])
|
||||
LIBS="$oldlibs"
|
||||
|
||||
LIBS="$oldlibs -lpam"
|
||||
AC_MSG_CHECKING([for pam library])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <security/pam_appl.h>],[
|
||||
pam_start(0, 0, 0, 0);])],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_SUBST([PAM_LIBS], [-lpam])
|
||||
AC_SUBST([PAM_CFLAGS], [])
|
||||
AC_DEFINE([HAVE_PAM], 1, [Enable the PAM library])],
|
||||
[AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([[
|
||||
***
|
||||
*** libpam was not found. It is required for building this program.
|
||||
*** ]])])
|
||||
LIBS="$oldlibs"
|
||||
|
||||
gl_INIT
|
||||
|
||||
enable_local_libopts=yes
|
||||
@@ -43,3 +62,14 @@ AC_CONFIG_FILES([
|
||||
gl/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_NOTICE([summary of build options:
|
||||
|
||||
version: ${VERSION}
|
||||
Host type: ${host}
|
||||
Install prefix: ${prefix}
|
||||
Compiler: ${CC}
|
||||
CFlags: ${CFLAGS}
|
||||
Library types: Shared=${enable_shared}, Static=${enable_static}
|
||||
])
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ bin_PROGRAMS = ocserv
|
||||
ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
||||
cookies.c http-parser/http_parser.c \
|
||||
vpn.h cookies.h tlslib.h http-parser/http_parser.h log.c tun.c tun.h \
|
||||
config.c worker-auth.h
|
||||
config.c worker-auth.h pam.c pam.h
|
||||
|
||||
ocserv_SOURCES += ocserv-args.def ocserv-args.c ocserv-args.h
|
||||
|
||||
ocserv_LDADD = ../gl/libgnu.a ../libopts/libopts.a
|
||||
ocserv_LDADD += $(LIBGNUTLS_LIBS) $(GDBM_LIBS)
|
||||
ocserv_LDADD += $(LIBGNUTLS_LIBS) $(GDBM_LIBS) $(PAM_LIBS)
|
||||
|
||||
ocserv-args.c ocserv-args.h: $(srcdir)/ocserv-args.def
|
||||
-autogen ocserv-args.def
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <cookies.h>
|
||||
#include <tun.h>
|
||||
#include <list.h>
|
||||
#include "pam.h"
|
||||
|
||||
static int send_auth_reply(cmd_auth_reply_t r, struct proc_list_st* proc, struct lease_st* lease)
|
||||
{
|
||||
@@ -138,15 +139,33 @@ static int handle_auth_req(const struct cfg_st *config, struct tun_st *tun,
|
||||
const struct cmd_auth_req_st * req, struct lease_st **lease,
|
||||
char username[MAX_USERNAME_SIZE])
|
||||
{
|
||||
int ret;
|
||||
#warning fix auth
|
||||
if (strcmp(req->user, "test") == 0 && strcmp(req->pass, "test") == 0)
|
||||
ret = 0;
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
memcpy(username, req->user, MAX_USERNAME_SIZE);
|
||||
int ret = -1;
|
||||
unsigned username_set = 0;
|
||||
|
||||
if (config->auth_types & AUTH_TYPE_PAM) {
|
||||
ret = pam_auth_user(req->user, req->pass);
|
||||
if (ret != 0)
|
||||
ret = -1;
|
||||
|
||||
memcpy(username, req->user, MAX_USERNAME_SIZE);
|
||||
username_set = 1;
|
||||
}
|
||||
|
||||
if (config->auth_types & AUTH_TYPE_CERTIFICATE) {
|
||||
if (req->tls_auth_ok != 0) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (username_set == 0)
|
||||
memcpy(username, req->cert_user, MAX_USERNAME_SIZE);
|
||||
else {
|
||||
if (strcmp(username, req->cert_user) != 0) {
|
||||
syslog(LOG_INFO, "User '%s' presented a certificate from user '%s'", username, req->cert_user);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) { /* open tun */
|
||||
ret = open_tun(config, tun, lease);
|
||||
if (ret < 0)
|
||||
|
||||
72
src/pam.c
Normal file
72
src/pam.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#define APP_NAME PACKAGE
|
||||
|
||||
#define MAX_REPLIES 2
|
||||
|
||||
struct local_st {
|
||||
const char* password;
|
||||
const char* username;
|
||||
};
|
||||
|
||||
int dummy_conv(int msg_size, const struct pam_message **msg,
|
||||
struct pam_response **resp, void *uptr)
|
||||
{
|
||||
struct local_st * l = uptr;
|
||||
unsigned i;
|
||||
struct pam_response *replies;
|
||||
|
||||
if (msg_size == 0)
|
||||
return PAM_SUCCESS;
|
||||
|
||||
replies = calloc(1, msg_size*sizeof(*replies));
|
||||
if (replies == NULL)
|
||||
return PAM_BUF_ERR;
|
||||
|
||||
for (i=0;i<msg_size;i++) {
|
||||
/*syslog(LOG_DEBUG, "PAM message: %s\n", msg[i]->msg);*/
|
||||
if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF)
|
||||
replies[i].resp = strdup(l->password);
|
||||
else if (msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
|
||||
replies[i].resp = strdup(l->username);
|
||||
}
|
||||
|
||||
*resp = replies;
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
/* Returns 0 if the user is successfully authenticated
|
||||
*/
|
||||
int pam_auth_user(const char* user, const char* pass)
|
||||
{
|
||||
pam_handle_t * ph;
|
||||
int ret, pret;
|
||||
struct local_st local;
|
||||
const struct pam_conv dc = { dummy_conv, &local };
|
||||
|
||||
local.username = user;
|
||||
local.password = pass;
|
||||
|
||||
pret = pam_start(APP_NAME, user, &dc, &ph);
|
||||
if (pret != PAM_SUCCESS) {
|
||||
syslog(LOG_AUTH, "Error in PAM authentication initialization: %s", pam_strerror(ph, pret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pret = pam_authenticate(ph, PAM_SILENT|PAM_DISALLOW_NULL_AUTHTOK);
|
||||
if (pret != PAM_SUCCESS) {
|
||||
syslog(LOG_AUTH, "Error in PAM authentication: %s", pam_strerror(ph, pret));
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
fail:
|
||||
pam_end(ph, pret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user