From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:32 +0000 (-0700) Subject: Add vgauth smoketest X-Git-Tag: stable-10.2.0~277 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03b89a4c99f257e724d90eff5c15560a4f9f2919;p=thirdparty%2Fopen-vm-tools.git Add vgauth smoketest Provide the vgauth smoketest so open-vm-tools builders can validate VGAUthservice. --- diff --git a/open-vm-tools/configure.ac b/open-vm-tools/configure.ac index 363c76d97..117cf9765 100644 --- a/open-vm-tools/configure.ac +++ b/open-vm-tools/configure.ac @@ -1531,6 +1531,7 @@ AC_CONFIG_FILES([ \ vgauth/lib/Makefile \ namespacetool/Makefile \ vgauth/cli/Makefile \ + vgauth/test/Makefile \ vgauth/service/Makefile \ libguestlib/Makefile \ libguestlib/vmguestlib.pc \ diff --git a/open-vm-tools/vgauth/Makefile.am b/open-vm-tools/vgauth/Makefile.am index e246dcded..22d92efc6 100644 --- a/open-vm-tools/vgauth/Makefile.am +++ b/open-vm-tools/vgauth/Makefile.am @@ -19,3 +19,4 @@ SUBDIRS = SUBDIRS += lib SUBDIRS += cli SUBDIRS += service +SUBDIRS += test diff --git a/open-vm-tools/vgauth/test/Makefile.am b/open-vm-tools/vgauth/test/Makefile.am new file mode 100644 index 000000000..92259a755 --- /dev/null +++ b/open-vm-tools/vgauth/test/Makefile.am @@ -0,0 +1,45 @@ +################################################################################ +### Copyright (C) 2014-2017 VMware, Inc. All rights reserved. +### +### This program is free software; you can redistribute it and/or modify +### it under the terms of version 2 of the GNU General Public License as +### published by the Free Software Foundation. +### +### 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +################################################################################ + +bin_PROGRAMS = vmware-vgauth-smoketest + +vmware_vgauth_smoketest_SOURCES = +vmware_vgauth_smoketest_SOURCES += main.c + +vmware_vgauth_smoketest_CPPFLAGS = +vmware_vgauth_smoketest_CPPFLAGS += -DVMTOOLS_USE_GLIB +vmware_vgauth_smoketest_CPPFLAGS += @GLIB2_CPPFLAGS@ +vmware_vgauth_smoketest_CPPFLAGS += -I$(top_srcdir)/libvmtools +vmware_vgauth_smoketest_CPPFLAGS += -I$(top_srcdir)/vgauth/public +vmware_vgauth_smoketest_CPPFLAGS += -I$(top_srcdir)/vgauth/common + +vmware_vgauth_smoketest_LDADD = +vmware_vgauth_smoketest_LDADD += @VMTOOLS_LIBS@ +vmware_vgauth_smoketest_LDADD += @GLIB2_LIBS@ +vmware_vgauth_smoketest_LDADD += @GTHREAD_LIBS@ +vmware_vgauth_smoketest_LDADD += @SSL_LIBS@ +vmware_vgauth_smoketest_LDADD += ../lib/libvgauth.la + +if HAVE_ICU + vmware_vgauth_smoketest_LDADD += @ICU_LIBS@ + vmware_vgauth_smoketest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXX) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +else + vmware_vgauth_smoketest_LINK = $(LINK) +endif diff --git a/open-vm-tools/vgauth/test/README.txt b/open-vm-tools/vgauth/test/README.txt new file mode 100644 index 000000000..ae1d8a462 --- /dev/null +++ b/open-vm-tools/vgauth/test/README.txt @@ -0,0 +1,37 @@ + * The VGAuthService smoke test. + * + * This does some very basic vgauth effort to verify that it + * properly validates SAML tokens. This verifies that vgauth + * was built and installed properly. + * + * This uses a built-in SAML token with a 1000 year lifetime, + * to avoid any issues with the XML security library on the signing + * side. + * + * This test must be run as root on the same system as VGAuthService. + * This test should only be run in a test environment, since it + * will clear out any existing aliases. + * + * To use: + * - start VGAuthService (/usr/bin/VGAuithService -s ) + * - run the smoketest + * + * + * Steps: + * - clear out any existing aliases + * - add an alias using the built-in cert + * - validate the SAML token + * + * Possible reasons for failure: + * - VGAuthService wasn't started + * - VGAuthService failed to start up properly + * - unable to find support files (schemas) + * - unable to access various files/directories + * - parts of xmlsec1 missing (openssl crypto lib missing) + * - SAML verification failed to init (xmlsec1 build issues) + * - token fails to validate + * - this test was run after 12/18/3015 + * - xmlsec1-config lies about how xmlsec1 was built + * some packages leave out -DXMLSEC_NO_SIZE_T, + * which can make some data structures a different size + * than in the library diff --git a/open-vm-tools/vgauth/test/main.c b/open-vm-tools/vgauth/test/main.c new file mode 100644 index 000000000..eb89017df --- /dev/null +++ b/open-vm-tools/vgauth/test/main.c @@ -0,0 +1,489 @@ +/********************************************************* + * Copyright (C) 2016-2017 VMware, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + *********************************************************/ + +/** + * @file main.c + * + * The VGAuthService smoke test. + * + * This does some very basic vgauth effort to verify that it + * properly validates SAML tokens. + * + * This uses a built-in SAML token with a 1000 year lifetime, + * to avoid any issues with the XML security library on the signing + * side. + * + * This test must be run as root on the same system as VGAuthService. + * This test should only be run in a test environment, since it + * will clear out any existing aliases. + * + * Steps: + * - clear out any existing aliases + * - add an alias using the built-in cert + * - validate the SAML token + * + * Possible reasons for failure: + * - VGAuthService wasn't started + * - VGAuthService failed to start up properly + * - unable to find support files (schemas) + * - unable to access various files/directories + * - parts of xmlsec1 missing (openssl crypto lib missing) + * - SAML verification failed to init (xmlsec1 build issues) + * - token fails to validate + * - this test was run after 12/18/3015 + * - xmlsec1-config lies about how xmlsec1 was built + * some packages leave out -DXMLSEC_NO_SIZE_T, + * which can make some data structures a different size + * than in the library + */ + +#include +#include +#include +#ifndef _WIN32 +#include +#include +#endif +#include + +#include "VGAuthBasicDefs.h" +#include "VGAuthAlias.h" +#include "VGAuthAuthentication.h" +#include "VGAuthCommon.h" +#include "VGAuthError.h" +#include "VGAuthLog.h" +#include "VGAuthUtil.h" + +static gchar *appName; + +#define ALIAS_USER_NAME "root" +#define SUBJECT_NAME "SmokeSubject" +#define COMMENT "Smoke comment" + +#define MAKE_PEM_FROM_BASE64(base64) \ + "-----BEGIN CERTIFICATE-----\n" \ + base64 \ + "-----END CERTIFICATE-----\n" +/* + * Self-signed smoketest cert. + * + * Not Before: Aug 16 22:29:21 2016 GMT + * Not After : Dec 18 22:29:21 3015 GMT + * + */ +#define SMOKETEST_CERT_BASE64 \ +"MIIDZTCCAk2gAwIBAgIJALuLD4JnajhkMA0GCSqGSIb3DQEBBQUAMEgxCzAJBgNV\n" \ +"BAYTAlhYMRMwEQYDVQQIDApTbW9rZVN0YXRlMRIwEAYDVQQHDAlTbW9rZUNpdHkx\n" \ +"EDAOBgNVBAoMB1Ntb2tlQ28wIBcNMTYwODE2MjIyOTIxWhgPMzAxNTEyMTgyMjI5\n" \ +"MjFaMEgxCzAJBgNVBAYTAlhYMRMwEQYDVQQIDApTbW9rZVN0YXRlMRIwEAYDVQQH\n" \ +"DAlTbW9rZUNpdHkxEDAOBgNVBAoMB1Ntb2tlQ28wggEiMA0GCSqGSIb3DQEBAQUA\n" \ +"A4IBDwAwggEKAoIBAQDcRD+tNhOwxtEDDhnwQ94Qn+eEI4Nh6zXBP5CfnbMIHYo0\n" \ +"1tzxLWOaJsN8/WoHy2cbeQkXGiGHpzuJIndhkL3XZpRdKTLIw95EVJkChYJi8ZUl\n" \ +"LnaLIPsG1bpVOSuf+0qGcRyoItXBlvvYMZ5JAdUncHYnJ2NAbvqZVIH0sSafupzv\n" \ +"w5txeQ7ufIcCzHYzSIFiX82CVMq/xuSQULVAZXoIfjNqMlwhYQn/EiSFb+y3kUa+\n" \ +"xDzNWNyzv4H+7/6C+qz2KxTUbBEKT/lsuIVYVJ5R+1vZ2MnGkqsz8ELttXk0tAK+\n" \ +"pfUAg7ugOhpF2rdvNOt4874Kkdj8a2It/JKqN3kBAgMBAAGjUDBOMB0GA1UdDgQW\n" \ +"BBR9OuZuejgPVz64LWnhOfO1d6u0dTAfBgNVHSMEGDAWgBR9OuZuejgPVz64LWnh\n" \ +"OfO1d6u0dTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCZ91zS4zKZ\n" \ +"uQv5rXn/zJtJ7d1pWnywh26n5bBlNQS3N7nAQPG5fvK2MB2rztE45Anq056YcYL7\n" \ +"TTDDDPz9dGndThGyusHbzO/lV7UHCQUzMr0joItxrQoX7/4OPBMyARBLAE5wRa85\n" \ +"uXm0D/Z6AAKJLz30yaQ+kBwTlIVhJFFhQv2zGZ3vB7CN0zNAZ/4s6lo+ejHj4Dhc\n" \ +"PFsUDwWnqqp9iqZMX3vxp3BEuxUsSzXtuwBytvWcS/6i1LUl41obD4RNxZ3llQTN\n" \ +"+uXVUFTTt0NgCbMJq5G8Nz4ziyjgxT94tB/AMwRmJzPSvew3vGMFhF7Fm0Z3Oxn5\n" \ +"kWMiikdSCME8\n" + + +const char *smoketestPEMCert = MAKE_PEM_FROM_BASE64(SMOKETEST_CERT_BASE64); + +const char *smoketestBase64Cert = SMOKETEST_CERT_BASE64; + +/* + * Token + */ + +static const gchar *token = +"\n" +"https://sso.eng.vmware.com\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"w0kRFhuuzMenlkrfZttAweUTHcyRsQtHRn2L01Rmsa4=\n" +"\n" +"\n" +"B54Qp2fO+YyMPK/6gYzCDigLZdOO3vEu8getiKB4a8s14ySoH6aQtq/RjgNSW8jr\n" +"yNox9NRxc8ipBXC/noF8UBw6sUPpxsifMabWdMb9XvoZKufdDDrYKxQ4LwGjKF9y\n" +"i2dO/Saw8kZ8CQKYvbNt0KkMqbQZNtDtM6AVAobWXuZioYyphQSJ6YZVwJnLh6wv\n" +"sI0DgBqjFI91pID4n4N4SZq+tr2u8wcepnSIcmFNZ+BVdy7TKnjqTnjaDCG0Y0Uk\n" +"P5wtWOAVpqTGMmTDpVwAtKfs089tDw/doGds+FIAXd6oR2eECo9j7SOm0i0V9pEn\n" +"/nIe1Di7JNVJfl9V+g/bfA==\n" +"\n" +"\n" +"MIIDZTCCAk2gAwIBAgIJALuLD4JnajhkMA0GCSqGSIb3DQEBBQUAMEgxCzAJBgNV\n" +"BAYTAlhYMRMwEQYDVQQIDApTbW9rZVN0YXRlMRIwEAYDVQQHDAlTbW9rZUNpdHkx\n" +"EDAOBgNVBAoMB1Ntb2tlQ28wIBcNMTYwODE2MjIyOTIxWhgPMzAxNTEyMTgyMjI5\n" +"MjFaMEgxCzAJBgNVBAYTAlhYMRMwEQYDVQQIDApTbW9rZVN0YXRlMRIwEAYDVQQH\n" +"DAlTbW9rZUNpdHkxEDAOBgNVBAoMB1Ntb2tlQ28wggEiMA0GCSqGSIb3DQEBAQUA\n" +"A4IBDwAwggEKAoIBAQDcRD+tNhOwxtEDDhnwQ94Qn+eEI4Nh6zXBP5CfnbMIHYo0\n" +"1tzxLWOaJsN8/WoHy2cbeQkXGiGHpzuJIndhkL3XZpRdKTLIw95EVJkChYJi8ZUl\n" +"LnaLIPsG1bpVOSuf+0qGcRyoItXBlvvYMZ5JAdUncHYnJ2NAbvqZVIH0sSafupzv\n" +"w5txeQ7ufIcCzHYzSIFiX82CVMq/xuSQULVAZXoIfjNqMlwhYQn/EiSFb+y3kUa+\n" +"xDzNWNyzv4H+7/6C+qz2KxTUbBEKT/lsuIVYVJ5R+1vZ2MnGkqsz8ELttXk0tAK+\n" +"pfUAg7ugOhpF2rdvNOt4874Kkdj8a2It/JKqN3kBAgMBAAGjUDBOMB0GA1UdDgQW\n" +"BBR9OuZuejgPVz64LWnhOfO1d6u0dTAfBgNVHSMEGDAWgBR9OuZuejgPVz64LWnh\n" +"OfO1d6u0dTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCZ91zS4zKZ\n" +"uQv5rXn/zJtJ7d1pWnywh26n5bBlNQS3N7nAQPG5fvK2MB2rztE45Anq056YcYL7\n" +"TTDDDPz9dGndThGyusHbzO/lV7UHCQUzMr0joItxrQoX7/4OPBMyARBLAE5wRa85\n" +"uXm0D/Z6AAKJLz30yaQ+kBwTlIVhJFFhQv2zGZ3vB7CN0zNAZ/4s6lo+ejHj4Dhc\n" +"PFsUDwWnqqp9iqZMX3vxp3BEuxUsSzXtuwBytvWcS/6i1LUl41obD4RNxZ3llQTN\n" +"+uXVUFTTt0NgCbMJq5G8Nz4ziyjgxT94tB/AMwRmJzPSvew3vGMFhF7Fm0Z3Oxn5\n" +"kWMiikdSCME8\n" +"\n" +"\n" +"\n" +"\n" +"SmokeSubject\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"https://sp.example.com/SAML2\n" +"\n" +"\n" +"\n" +"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport\n" +"\n" +"\n" +"\n" +"\n" +"member\n" +"staff\n" +"\n" +"\n" +"\n" +; + + +/* + ****************************************************************************** + * Usage -- */ /** + * + * Usage message for smoke test + * + ****************************************************************************** + */ + +static void +Usage(void) +{ + fprintf(stderr, "Usage: %s\n", appName); + exit(-1); +} + + +/* + ****************************************************************************** + * Log -- */ /** + * + * Error message logging function. + * + * @param[in] logDomain The glib logging domain, which is set by the + * various glib components and vgauth itself. + * @param[in] logLevel The severity of the message. + * @param[in] msg The error message. + * @param[in] userData Any userData specified in the call to + * VGAuth_SetLogHandler() (unused) + * + ****************************************************************************** + */ + +static void +Log(const char *logDomain, + int logLevel, + const char *msg, + void *userData) +{ + g_printerr("%s[%d]: %s", logDomain, logLevel, msg); +} + + +/* + ****************************************************************************** + * CleanAliases -- */ /** + * + * Clears out the alias store for the given user, and the map file. + * + * @param[in] ctx VGAuth context + * @param[in] userName The user whose alias store is to be cleaned. + * + * @return A SAMl token on success, NULL failure. + * + ****************************************************************************** + */ + +static VGAuthError +CleanAliases(VGAuthContext *ctx, + const gchar *userName) +{ + VGAuthError err; + int num; + int i; + VGAuthMappedAlias *maList; + VGAuthUserAlias *uaList; + + // clear out mapped aliaes + err = VGAuth_QueryMappedAliases(ctx, 0, NULL, &num, &maList); + if (err != VGAUTH_E_OK) { + g_printerr("VGAuth_QueryMappedAliases() failed "VGAUTHERR_FMT64"\n", + err); + return err; + } + + for (i = 0; i < num; i++) { + err = VGAuth_RemoveAliasByCert(ctx, maList[i].userName, + maList[i].pemCert, 0, NULL); + if (err != VGAUTH_E_OK) { + g_printerr("VGAuth_RemoveAliasByCert() failed "VGAUTHERR_FMT64"\n", + err); + return err; + } + } + VGAuth_FreeMappedAliasList(num, maList); + err = VGAuth_QueryMappedAliases(ctx, 0, NULL, &num, &maList); + if (err != VGAUTH_E_OK || num != 0) { + g_printerr("sitll have mapped aliases or " + "VGAuth_QueryMappedAliases() failed "VGAUTHERR_FMT64"\n", + err); + return err; + } + + // clear out user aliases + err = VGAuth_QueryUserAliases(ctx, userName, 0, NULL, + &num, &uaList); + if (err != VGAUTH_E_OK) { + g_printerr("VGAuth_QueryUserAliases() failed "VGAUTHERR_FMT64"\n", + err); + return err; + } + for (i = 0; i < num; i++) { + err = VGAuth_RemoveAliasByCert(ctx, userName, + uaList[i].pemCert, 0, NULL); + if (err != VGAUTH_E_OK) { + g_printerr("VGAuth_RemoveAliasByCert() failed "VGAUTHERR_FMT64"\n", + err); + return err; + } + } + + err = VGAuth_QueryUserAliases(ctx, userName, 0, NULL, + &num, &uaList); + if (err != VGAUTH_E_OK || num != 0) { + g_printerr("aliases left or VGAuth_QueryUserAliases() failed " + VGAUTHERR_FMT64"\n", + err); + return err; + } + + return err; +} + + +/* + ****************************************************************************** + * AddAlias -- */ /** + * + * Generates a SAMl token with a given Subject. + * + * @param[in] ctx VGAuth context + * @param[in] cert The certificate for the alias. + * @param[in] user The user whose alias store is to be updated. + * @param[in] subject The Subject for the alias. + * @param[in] comment The Comment for the alias. + * + * @return A SAMl token on success, NULL failure. + * + ****************************************************************************** + */ + +static VGAuthError +AddAlias(VGAuthContext *ctx, + const gchar *cert, + const gchar *user, + const gchar *subject, + const gchar *comment) +{ + VGAuthError err; + VGAuthAliasInfo ai; + + ai.subject.type = VGAUTH_SUBJECT_NAMED; + ai.subject.val.name = (gchar *)subject; + ai.comment = (gchar *)comment; + err = VGAuth_AddAlias(ctx, user, FALSE, cert, &ai, 0, NULL); + if (err != VGAUTH_E_OK) { + g_printerr("VGAuth_AddAlias() failed "VGAUTHERR_FMT64"\n", + err); + return err; + } + + return err; +} + + +/* + ****************************************************************************** + * ValidateToken -- */ /** + * + * Validates a SAMl token. + * + * @param[in] ctx VGAuth context + * @param[in] userName The user associated with the token. + * @param[in] token A SAML token. + * + * @return VGAUTH_E_OK on success, an error on failure. + * + ****************************************************************************** + */ + +static VGAuthError +ValidateToken(VGAuthContext *ctx, + const gchar *userName, + const gchar *token) +{ + VGAuthError err; + VGAuthExtraParams extraParams[1]; + VGAuthUserHandle *userHandle = NULL; + VGAuthAliasInfo *retAi = NULL; + char *retSamlSubject = NULL; + char *retUserName = NULL; + + /* + * Use info-only -- its all we need. + */ + extraParams[0].name = VGAUTH_PARAM_VALIDATE_INFO_ONLY; + extraParams[0].value = VGAUTH_PARAM_VALUE_TRUE; + err = VGAuth_ValidateSamlBearerToken(ctx, + token, + userName, + 1, + extraParams, + &userHandle); + if (VGAUTH_E_OK != err) { + g_printerr("Failed to validate token"); + goto done; + } + + err = VGAuth_UserHandleUsername(ctx, userHandle, &retUserName); + if (VGAUTH_E_OK != err) { + g_printerr("Failed to get username off handle"); + goto done; + } + err = VGAuth_UserHandleSamlData(ctx, + userHandle, + &retSamlSubject, + &retAi); + if (VGAUTH_E_OK != err) { + g_printerr("Failed to get SAML subject data off handle"); + goto done; + } + printf("Token details: user: %s (expected %s) subject: %s (expected %s)\n", + retUserName, ALIAS_USER_NAME, retSamlSubject, SUBJECT_NAME); + +done: + VGAuth_UserHandleFree(userHandle); + g_free(retUserName); + g_free(retSamlSubject); + VGAuth_FreeAliasInfo(retAi); + return err; +} + + +/* + ****************************************************************************** + * main -- */ /** + * + * Main entry point. + * + * @param[in] argc Number of command line arguments. + * @param[in] argv The command line arguments. + * + * @return 0 if the operation ran successfully, -1 if there was an error during + * execution. + * + ****************************************************************************** + */ + +int +main(int argc, + char *argv[]) +{ + VGAuthError err; + VGAuthContext *ctx; + + appName = g_path_get_basename(argv[0]); + if (argc != 1) { + Usage(); + } + + VGAuth_SetLogHandler(Log, NULL, 0, NULL); + + err = VGAuth_Init(appName, 0, NULL, &ctx); + if (VGAUTH_E_OK != err) { + g_printerr("Failed to init VGAuth"); + return -1; + } + + // make sure we start with a clean slate + err = CleanAliases(ctx, ALIAS_USER_NAME); + if (VGAUTH_E_OK != err) { + g_printerr("Failed to clean alias store"); + return -1; + } + + err = AddAlias(ctx, smoketestPEMCert, + ALIAS_USER_NAME, SUBJECT_NAME, COMMENT); + if (VGAUTH_E_OK != err) { + g_printerr("Failed to add alias"); + return -1; + } + + err = ValidateToken(ctx, ALIAS_USER_NAME, token); + if (VGAUTH_E_OK != err) { + g_printerr("Failed to validate SAML token"); + return -1; + } + + printf("PASSED!\n"); + + // make sure we end with a clean slate + err = CleanAliases(ctx, ALIAS_USER_NAME); + if (VGAUTH_E_OK != err) { + g_printerr("Failed to clean alias store"); + return -1; + } + + VGAuth_Shutdown(ctx); + g_free(appName); + return 0; +}