From c8a87758388cb30ef9d7b2a58cfb52c13b7d37ba Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Thu, 1 Apr 2021 14:03:33 +0200 Subject: [PATCH 1/6] sql: add schema for yubikey_mapping --- yubikey_mapping.sql | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 yubikey_mapping.sql diff --git a/yubikey_mapping.sql b/yubikey_mapping.sql new file mode 100644 index 0000000..f2c792f --- /dev/null +++ b/yubikey_mapping.sql @@ -0,0 +1,9 @@ +# +# Table structure for table equiv of yubikey_mapping +# + +CREATE TABLE IF NOT EXISTS `otp`.`yubikey_mappings` ( + `otp_id` VARCHAR(12) NOT NULL , + `username` VARCHAR(64) NOT NULL , + PRIMARY KEY (`otp_id`(12)) + ); From 54c2104252fe8b14d2cb7c6d9257b01a4aa0fb1b Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Thu, 1 Apr 2021 14:07:54 +0200 Subject: [PATCH 2/6] ci: add database service for mysql builds --- .github/workflows/build_and_test.yml | 23 +++++++++++++++++++++++ tests/aux/build-and-test.sh | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 3ec8403..fecf1ae 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -22,17 +22,40 @@ jobs: - os: ubuntu-20.04 config_args: "" extra: "libldap2-dev libykpers-1-dev libnet-ldap-server-perl libmysqlclient-dev" + mysql: true - os: ubuntu-18.04 config_args: "" extra: "libldap2-dev libykpers-1-dev libnet-ldap-server-perl libmysqlclient-dev" + mysql: true - os: ubuntu-16.04 config_args: "" extra: "libldap2-dev libykpers-1-dev libnet-ldap-server-perl libmysqlclient-dev" + mysql: true + services: + mariadb: + image: mariadb:latest + ports: + - 3306 + env: + MYSQL_USER: user + MYSQL_PASSWORD: password + MYSQL_DATABASE: test + MYSQL_ROOT_PASSWORD: password + options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 steps: - uses: actions/checkout@v1 + - name: Setup Database + if: ${{ matrix.mysql }} + env: + MYSQL_PORT: ${{ job.services.mariadb.ports[3306] }} + run: | + while ! mysqladmin ping -h"127.0.0.1" -P"$MYSQL_PORT" --silent; do + sleep 1 + done - name: Build and test env: CONFIGURE_ARGS: ${{ matrix.config_args }} EXTRA: ${{ matrix.extra }} + MYSQL_PORT: ${{ job.services.mariadb.ports[3306] }} run: | tests/aux/build-and-test.sh diff --git a/tests/aux/build-and-test.sh b/tests/aux/build-and-test.sh index 3db2cbc..5a16b5b 100755 --- a/tests/aux/build-and-test.sh +++ b/tests/aux/build-and-test.sh @@ -7,7 +7,7 @@ autoreconf -i if [ "x$TRAVIS_OS_NAME" != "xosx" ]; then sudo add-apt-repository -y ppa:yubico/stable sudo apt-get update -qq || true - sudo apt-get install -qq -y --no-install-recommends libykclient-dev libpam0g-dev libyubikey-dev asciidoc docbook-xsl xsltproc libxml2-utils libmysqlclient-dev $EXTRA + sudo apt-get install -qq -y --no-install-recommends libykclient-dev libpam0g-dev libyubikey-dev asciidoc docbook-xsl xsltproc libxml2-utils $EXTRA else brew update brew install pkg-config From aa81bb8cd6f3d1e0d6818a50a500d22dd249b679 Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Thu, 1 Apr 2021 14:49:11 +0200 Subject: [PATCH 3/6] sql: add mysql_port configuration --- pam_yubico.8.txt | 3 +++ pam_yubico.c | 10 +++++++--- util.c | 3 ++- util.h | 4 +++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pam_yubico.8.txt b/pam_yubico.8.txt index 45bd6b7..625f677 100644 --- a/pam_yubico.8.txt +++ b/pam_yubico.8.txt @@ -119,6 +119,9 @@ Path of a system-wide directory where challenge-response files can be found for *mysql_server*=_mysqlserver_:: Hostname/Adress of mysql server. Example 10.0.0.1 +*mysql_port*=_mysqlport_:: +Network port of mysql server. + *mysql_user*=_mysqluser_:: User for accessing to the database. Strongly recommended to use a specific user with read only access. diff --git a/pam_yubico.c b/pam_yubico.c index 899dc5b..7cba801 100644 --- a/pam_yubico.c +++ b/pam_yubico.c @@ -135,6 +135,7 @@ struct cfg const char *yubi_attr; const char *yubi_attr_prefix; const char *mysql_server; + int mysql_port; const char *mysql_user; const char *mysql_password; const char *mysql_database; @@ -176,7 +177,7 @@ authorize_user_token (struct cfg *cfg, as an argument for this module. */ DBG ("Using Mariadb or Mysql Database"); - retval = check_user_token_mysql(cfg->mysql_server, cfg->mysql_user, cfg->mysql_password, cfg->mysql_database, username, otp_id, cfg->debug, cfg->debug_file); + retval = check_user_token_mysql(cfg->mysql_server, cfg->mysql_port, cfg->mysql_user, cfg->mysql_password, cfg->mysql_database, username, otp_id, cfg->debug, cfg->debug_file); #else DBG (("Trying to use MYSQL, but this function is not compiled in pam_yubico!!")); #endif @@ -892,9 +893,11 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) cfg->chalresp_path = argv[i] + 14; if (strncmp (argv[i], "mysql_server=", 13) == 0) cfg->mysql_server = argv[i] + 13; - if (strncmp (argv[i], "mysql_user=", 11) == 0) + if (strncmp (argv[i], "mysql_port=", 11) == 0) + sscanf (argv[i], "mysql_port=%u", &cfg->mysql_port); + if (strncmp (argv[i], "mysql_user=", 11) == 0) cfg->mysql_user = argv[i] + 11; - if (strncmp (argv[i], "mysql_password=", 15) == 0) + if (strncmp (argv[i], "mysql_password=", 15) == 0) cfg->mysql_password = argv[i] + 15; if (strncmp (argv[i], "mysql_database=", 15) == 0) cfg->mysql_database = argv[i] + 15; @@ -965,6 +968,7 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) DBG ("mode=%s", cfg->mode == CLIENT ? "client" : "chresp" ); DBG ("chalresp_path=%s", cfg->chalresp_path ? cfg->chalresp_path : "(null)"); DBG ("mysql_server=%s", cfg->mysql_server ? cfg->mysql_server : "(null)"); + DBG ("mysql_port=%d", cfg->mysql_port); DBG ("mysql_user=%s", cfg->mysql_user ? cfg->mysql_user : "(null)"); DBG ("mysql_database=%s", cfg->mysql_database ? cfg->mysql_database : "(null)"); diff --git a/util.c b/util.c index 5582aab..d157678 100644 --- a/util.c +++ b/util.c @@ -114,6 +114,7 @@ get_user_cfgfile_path(const char *common_path, const char *filename, const struc */ int check_user_token_mysql(const char *mysql_server, + int mysql_port, const char *mysql_user, const char *mysql_password, const char *mysql_database, @@ -152,7 +153,7 @@ check_user_token_mysql(const char *mysql_server, return retval; } - if(mysql_real_connect(con, mysql_server,mysql_user,mysql_password,mysql_database, 0, NULL, 0) == NULL) + if(mysql_real_connect(con, mysql_server,mysql_user,mysql_password,mysql_database, mysql_port, NULL, 0) == NULL) { if(verbose) D (debug_file, "Connection failed ..."); diff --git a/util.h b/util.h index fbf5397..3a36978 100644 --- a/util.h +++ b/util.h @@ -52,7 +52,9 @@ int get_user_cfgfile_path(const char *common_path, const char *filename, const struct passwd *user, char **fn); #ifdef HAVE_MYSQL -int check_user_token_mysql(const char *mysql_server,const char *mysql_user,const char *mysql_password,const char *mysql_database,const char *username,const char *otp_id,int verbose,FILE *debug_file); +int check_user_token_mysql(const char *mysql_server, int mysql_port, const char *mysql_user, + const char *mysql_password, const char *mysql_database, const char *username, const char *otp_id, int verbose, + FILE *debug_file); #endif int check_user_token(const char *authfile, const char *username, const char *otp_id, int verbose, FILE *debug_file); From 6c9595051542d86b8270596f323db89953d0b278 Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Tue, 6 Apr 2021 13:36:00 +0200 Subject: [PATCH 4/6] sql: more setup for sql tests --- .github/workflows/build_and_test.yml | 4 +++- tests/aux/auth_mapping.sql | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 tests/aux/auth_mapping.sql diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index fecf1ae..fd85e01 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -39,7 +39,7 @@ jobs: env: MYSQL_USER: user MYSQL_PASSWORD: password - MYSQL_DATABASE: test + MYSQL_DATABASE: otp MYSQL_ROOT_PASSWORD: password options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 steps: @@ -52,6 +52,8 @@ jobs: while ! mysqladmin ping -h"127.0.0.1" -P"$MYSQL_PORT" --silent; do sleep 1 done + mysql --user=user --password=password --host=127.0.0.1 --port=$MYSQL_PORT otp < yubikey_mapping.sql + mysql --user=user --password=password --host=127.0.0.1 --port=$MYSQL_PORT otp < tests/aux/auth_mapping.sql - name: Build and test env: CONFIGURE_ARGS: ${{ matrix.config_args }} diff --git a/tests/aux/auth_mapping.sql b/tests/aux/auth_mapping.sql new file mode 100644 index 0000000..57d2188 --- /dev/null +++ b/tests/aux/auth_mapping.sql @@ -0,0 +1,3 @@ +INSERT INTO yubikey_mappings (otp_id, username) VALUES ('vvincredible', 'foo'); +INSERT INTO yubikey_mappings (otp_id, username) VALUES ('cccccccfhcbe', 'test'); +INSERT INTO yubikey_mappings (otp_id, username) VALUES ('ccccccbchvth', 'test'); From 371d6048fed57da5ac36490c304f3ff6e60fe864 Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Tue, 6 Apr 2021 14:02:33 +0200 Subject: [PATCH 5/6] ci: always end tests with displaying logs --- .github/workflows/build_and_test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index fd85e01..bb3e9fa 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -61,3 +61,10 @@ jobs: MYSQL_PORT: ${{ job.services.mariadb.ports[3306] }} run: | tests/aux/build-and-test.sh + - name: Display logs + if: ${{ always() }} + run: | + for log in tests/*.log; do + echo $log + cat $log + done From 23fb773279ed0d4bedb1ef3cdd8840b1cf9acb9a Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Tue, 6 Apr 2021 13:48:42 +0200 Subject: [PATCH 6/6] sql: add test for mysql config --- tests/aux/build-and-test.sh | 7 ++++++- tests/pam_test.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/tests/aux/build-and-test.sh b/tests/aux/build-and-test.sh index 5a16b5b..08ec9b7 100755 --- a/tests/aux/build-and-test.sh +++ b/tests/aux/build-and-test.sh @@ -26,7 +26,12 @@ fi set -e -./configure $CONFIGURE_ARGS $COVERAGE +if [ ! -z $MYSQL_PORT ]; then + CFLAGS="-DTEST_MYSQL_PORT='\"${MYSQL_PORT}\"'" ./configure $CONFIGURE_ARGS $COVERAGE +else + ./configure $CONFIGURE_ARGS $COVERAGE +fi + make check check-doc-dist if [ "x$COVERAGE" != "x" ]; then gem install coveralls-lcov diff --git a/tests/pam_test.c b/tests/pam_test.c index d88dc70..e5ad855 100644 --- a/tests/pam_test.c +++ b/tests/pam_test.c @@ -56,6 +56,10 @@ pam_sm_authenticate (pam_handle_t * pamh, #define YKVAL_PORT2 "30559" #define LDAP_PORT "52825" +#ifndef TEST_MYSQL_PORT +#define TEST_MYSQL_PORT "3306" +#endif + #define YKVAL SRCDIR"/aux/ykval.pl" #define LDAP SRCDIR"/aux/ldap.pl" #define AUTHFILE SRCDIR"/aux/authfile" @@ -97,6 +101,17 @@ static const char *ldap_cfg2[] = { "debug" }; +static const char *mysql_cfg[] = { + "id=1", + "urllist=http://localhost:"YKVAL_PORT1"/wsapi/2/verify", + "mysql_server=127.0.0.1", + "mysql_port="TEST_MYSQL_PORT, + "mysql_user=user", + "mysql_password=password", + "mysql_database=otp", + "debug" +}; + static const struct data *test_get_data(void *id) { return &_data[(long)id]; } @@ -323,6 +338,14 @@ static int test_authenticate_ldap6(void) { return pam_sm_authenticate((pam_handle_t *)7, 0, sizeof(ldap_cfg) / sizeof(char*), ldap_cfg); } +static int test_authenticate_mysql1(void) { + return pam_sm_authenticate((pam_handle_t *)0, 0, sizeof(mysql_cfg) / sizeof(char*), mysql_cfg); +} + +static int test_fail_authenticate_mysql1(void) { + return pam_sm_authenticate((pam_handle_t *)1, 0, sizeof(mysql_cfg) / sizeof(char*), mysql_cfg); +} + static pid_t run_mock(const char *port, const char *type) { pid_t pid = fork(); if(pid == 0) { @@ -420,6 +443,16 @@ int main(void) { goto out; } #endif +#ifdef HAVE_MYSQL + if(test_authenticate_mysql1() != PAM_SUCCESS) { + ret = 2001; + goto out; + } + if(test_fail_authenticate_mysql1() != PAM_USER_UNKNOWN) { + ret = 2002; + goto out; + } +#endif out: kill(child, 9);