1
0
mirror of https://github.com/Yubico/yubico-pam.git synced 2025-02-20 12:54:16 +01:00

Use libyubikey-client instead of curl directly.

This commit is contained in:
Simon Josefsson 2008-06-25 13:40:19 +00:00
parent 31b7ea6758
commit 454d5b1bab
3 changed files with 15 additions and 331 deletions

View File

@ -40,7 +40,9 @@ AC_PROG_LIBTOOL
AC_CHECK_HEADERS([security/pam_appl.h security/pam_modules.h security/_pam_macros.h], [], [AC_MSG_ERROR([[PAM header files not found, install libpam-dev.]])])
LIBCURL_CHECK_CONFIG([yes], [], [], [AC_MSG_ERROR([[Libcurl header files not found, install libcurl-dev.]])])
AC_LIB_HAVE_LINKFLAGS([yubikey-client],,
[#include <libykclient.h>],
[yubikey_client_init ();])
AC_SUBST(PAMDIR, "\$(exec_prefix)/lib/security")
AC_ARG_WITH(pam-dir,

View File

@ -1,240 +0,0 @@
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
# [ACTION-IF-YES], [ACTION-IF-NO])
# ----------------------------------------------------------
# David Shaw <dshaw@jabberwocky.com> May-09-2006
#
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
# specify whether to default to --with-libcurl or --without-libcurl.
# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the
# minimum version of libcurl to accept. Pass the version as a regular
# version number like 7.10.1. If not supplied, any version is
# accepted. ACTION-IF-YES is a list of shell commands to run if
# libcurl was successfully found and passed the various tests.
# ACTION-IF-NO is a list of shell commands that are run otherwise.
# Note that using --without-libcurl does run ACTION-IF-NO.
#
# This macro #defines HAVE_LIBCURL if a working libcurl setup is
# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary
# values. Other useful defines are LIBCURL_FEATURE_xxx where xxx are
# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy
# where yyy are the various protocols supported by libcurl. Both xxx
# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of
# the macro for the complete list of possible defines. Shell
# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also
# defined to 'yes' for those features and protocols that were found.
# Note that xxx and yyy keep the same capitalization as in the
# curl-config list (e.g. it's "HTTP" and not "http").
#
# Users may override the detected values by doing something like:
# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure
#
# For the sake of sanity, this macro assumes that any libcurl that is
# found is after version 7.7.2, the first version that included the
# curl-config script. Note that it is very important for people
# packaging binary versions of libcurl to include this script!
# Without curl-config, we can only guess what protocols are available,
# or use curl_version_info to figure it out at runtime.
AC_DEFUN([LIBCURL_CHECK_CONFIG],
[
AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL])
AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4])
AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6])
AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz])
AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS])
AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN])
AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI])
AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM])
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP])
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS])
AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP])
AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS])
AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE])
AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET])
AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP])
AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT])
AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP])
AC_ARG_WITH(libcurl,
AC_HELP_STRING([--with-libcurl=DIR],[look for the curl library in DIR]),
[_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])])
if test "$_libcurl_with" != "no" ; then
AC_PROG_AWK
_libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'"
_libcurl_try_link=yes
if test -d "$_libcurl_with" ; then
LIBCURL_CPPFLAGS="-I$withval/include"
_libcurl_ldflags="-L$withval/lib"
AC_PATH_PROG([_libcurl_config],[curl-config],["$withval/bin"],
["$withval/bin"])
else
AC_PATH_PROG([_libcurl_config],[curl-config])
fi
if test x$_libcurl_config != "x" ; then
AC_CACHE_CHECK([for the version of libcurl],
[libcurl_cv_lib_curl_version],
[libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`])
_libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse`
_libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse`
if test $_libcurl_wanted -gt 0 ; then
AC_CACHE_CHECK([for libcurl >= version $2],
[libcurl_cv_lib_version_ok],
[
if test $_libcurl_version -ge $_libcurl_wanted ; then
libcurl_cv_lib_version_ok=yes
else
libcurl_cv_lib_version_ok=no
fi
])
fi
if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then
if test x"$LIBCURL_CPPFLAGS" = "x" ; then
LIBCURL_CPPFLAGS=`$_libcurl_config --cflags`
fi
if test x"$LIBCURL" = "x" ; then
LIBCURL=`$_libcurl_config --libs`
# This is so silly, but Apple actually has a bug in their
# curl-config script. Fixed in Tiger, but there are still
# lots of Panther installs around.
case "${host}" in
powerpc-apple-darwin7*)
LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'`
;;
esac
fi
# All curl-config scripts support --feature
_libcurl_features=`$_libcurl_config --feature`
# Is it modern enough to have --protocols? (7.12.4)
if test $_libcurl_version -ge 461828 ; then
_libcurl_protocols=`$_libcurl_config --protocols`
fi
else
_libcurl_try_link=no
fi
unset _libcurl_wanted
fi
if test $_libcurl_try_link = yes ; then
# we didn't find curl-config, so let's see if the user-supplied
# link line (or failing that, "-lcurl") is enough.
LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"}
AC_CACHE_CHECK([whether libcurl is usable],
[libcurl_cv_lib_curl_usable],
[
_libcurl_save_cppflags=$CPPFLAGS
CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS"
_libcurl_save_libs=$LIBS
LIBS="$LIBCURL $LIBS"
AC_LINK_IFELSE(AC_LANG_PROGRAM([#include <curl/curl.h>],[
/* Try and use a few common options to force a failure if we are
missing symbols or can't link. */
int x;
curl_easy_setopt(NULL,CURLOPT_URL,NULL);
x=CURL_ERROR_SIZE;
x=CURLOPT_WRITEFUNCTION;
x=CURLOPT_FILE;
x=CURLOPT_ERRORBUFFER;
x=CURLOPT_STDERR;
x=CURLOPT_VERBOSE;
]),libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
CPPFLAGS=$_libcurl_save_cppflags
LIBS=$_libcurl_save_libs
unset _libcurl_save_cppflags
unset _libcurl_save_libs
])
if test $libcurl_cv_lib_curl_usable = yes ; then
# Does curl_free() exist in this version of libcurl?
# If not, fake it with free()
_libcurl_save_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
_libcurl_save_libs=$LIBS
LIBS="$LIBS $LIBCURL"
AC_CHECK_FUNC(curl_free,,
AC_DEFINE(curl_free,free,
[Define curl_free() as free() if our version of curl lacks curl_free.]))
CPPFLAGS=$_libcurl_save_cppflags
LIBS=$_libcurl_save_libs
unset _libcurl_save_cppflags
unset _libcurl_save_libs
AC_DEFINE(HAVE_LIBCURL,1,
[Define to 1 if you have a functional curl library.])
AC_SUBST(LIBCURL_CPPFLAGS)
AC_SUBST(LIBCURL)
for _libcurl_feature in $_libcurl_features ; do
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1])
eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes
done
if test "x$_libcurl_protocols" = "x" ; then
# We don't have --protocols, so just assume that all
# protocols are available
_libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT"
if test x$libcurl_feature_SSL = xyes ; then
_libcurl_protocols="$_libcurl_protocols HTTPS"
# FTPS wasn't standards-compliant until version
# 7.11.0
if test $_libcurl_version -ge 461568; then
_libcurl_protocols="$_libcurl_protocols FTPS"
fi
fi
fi
for _libcurl_protocol in $_libcurl_protocols ; do
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
done
else
unset LIBCURL
unset LIBCURL_CPPFLAGS
fi
fi
unset _libcurl_try_link
unset _libcurl_version_parse
unset _libcurl_config
unset _libcurl_feature
unset _libcurl_features
unset _libcurl_protocol
unset _libcurl_protocols
unset _libcurl_version
unset _libcurl_ldflags
fi
if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
# This is the IF-NO path
ifelse([$4],,:,[$4])
else
# This is the IF-YES path
ifelse([$3],,:,[$3])
fi
unset _libcurl_with
])dnl

View File

@ -63,7 +63,7 @@
#define D(x) /* nothing */
#endif
#include <curl/curl.h>
#include <libykclient.h>
#ifndef PAM_EXTERN
#ifdef PAM_STATIC
@ -73,32 +73,6 @@
#endif
#endif
struct MemoryStruct {
char *memory;
size_t size;
};
static size_t
curl_callback (void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)data;
if (mem->memory)
mem->memory = realloc (mem->memory, mem->size + realsize + 1);
else
mem->memory = malloc (mem->size + realsize + 1);
if (mem->memory)
{
memcpy(&(mem->memory[mem->size]), ptr, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
}
return realsize;
}
PAM_EXTERN int
pam_sm_authenticate (pam_handle_t * pamh,
int flags, int argc, const char** argv)
@ -114,20 +88,12 @@ pam_sm_authenticate (pam_handle_t * pamh,
int id = -1;
int debug = 0;
int alwaysok = 0;
CURL *curl = NULL;
CURLcode res;
char *url;
const char *url_template = "http://api.yubico.com/wsapi/verify?id=%d&otp=%s";
struct MemoryStruct chunk = { NULL, 0 };
char *status;
char *user_agent = NULL;
yubikey_client_t ykc;
for (i = 0; i < argc; i++)
{
if (strncmp (argv[i], "id=", 3) == 0)
sscanf (argv[i], "id=%d", &id);
if (strncmp (argv[i], "url=", 4) == 0)
url_template = argv[i] + 4;
if (strcmp (argv[i], "debug") == 0)
debug = 1;
if (strcmp (argv[i], "alwaysok") == 0)
@ -140,9 +106,7 @@ pam_sm_authenticate (pam_handle_t * pamh,
D (("flags %d argc %d", flags, argc));
for (i = 0; i < argc; i++)
D (("argv[%d]=%s", i, argv[i]));
D (("id=%d", id));
D (("url=%s", url_template));
D (("debug=%d", debug));
D (("alwaysok=%d", alwaysok));
}
@ -208,67 +172,29 @@ pam_sm_authenticate (pam_handle_t * pamh,
}
}
curl = curl_easy_init ();
if (!curl)
ykc = yubikey_client_init ();
if (!ykc)
{
if (debug)
D (("curl_easy_init() failed"));
D (("yubikey_client_init() failed"));
retval = PAM_AUTHINFO_UNAVAIL;
goto done;
}
asprintf (&url, url_template, id, password);
if (!url)
{
retval = PAM_BUF_ERR;
goto done;
}
curl_easy_setopt (curl, CURLOPT_URL, url);
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curl_callback);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&chunk);
asprintf (&user_agent, "%s/%s", PACKAGE, PACKAGE_VERSION);
if (user_agent)
curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent);
curl_easy_perform (curl);
yubikey_client_set_info (ykc, id, 0, NULL);
rc = yubikey_client_request (ykc, password);
if (debug)
D (("server response (%d): %.*s", chunk.size, chunk.size, chunk.memory));
D (("libyubikey-client return value (%d): %s", rc,
yubikey_client_strerror (rc)));
if (chunk.size == 0 || chunk.memory == NULL)
if (rc != YUBIKEY_CLIENT_OK)
{
if (debug)
D (("did not receive anything from server"));
retval = PAM_SERVICE_ERR;
goto done;
}
status = strstr (chunk.memory, "status=");
if (!status)
{
if (debug)
D (("no status in server response"));
retval = PAM_SERVICE_ERR;
goto done;
}
if (strchr (status, '\r'))
*strchr (status, '\r') = '\0';
if (strchr (status, '\n'))
*strchr (status, '\n') = '\0';
if (debug)
D (("server status (%d): %s", strlen (status), status));
if (strcmp (status, "status=OK") != 0)
{
if (debug)
D (("status not ok"));
retval = PAM_SERVICE_ERR;
goto done;
}
yubikey_client_done (&ykc);
retval = PAM_SUCCESS;
@ -276,13 +202,9 @@ done:
if (alwaysok && retval != PAM_SUCCESS)
{
if (debug)
D (("alwaysok needed for %d", retval));
D (("alwaysok needed (otherwise return with %d)", retval));
retval = PAM_SUCCESS;
}
if (curl)
curl_easy_cleanup (curl);
if (user_agent)
free (user_agent);
pam_set_data (pamh, "yubico_setcred_return", (void *) retval, NULL);
if (debug)
D (("done. [%s]", pam_strerror (pamh, retval)));