Projects
Eulaceura:Factory
pam
_service:obs_scm:add-sm3-crypt-support.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:add-sm3-crypt-support.patch of Package pam
From 59daac692a796fac4f241ec0ef358fd023b671ef Mon Sep 17 00:00:00 2001 From: modric <wangyu283@huawei.com> Date: Fri, 14 Jan 2022 11:46:20 +0800 Subject: [PATCH] add sm3 crypt support --- modules/pam_unix/pam_unix.8 | 9 +- modules/pam_unix/pam_unix.8.xml | 16 +++- modules/pam_unix/passverify.c | 5 +- modules/pam_unix/support.c | 4 +- modules/pam_unix/support.h | 6 +- xtests/Makefile.am | 6 +- xtests/tst-pam_unix5.c | 151 ++++++++++++++++++++++++++++++++ xtests/tst-pam_unix5.pamd | 5 ++ xtests/tst-pam_unix5.sh | 41 +++++++++ 9 files changed, 233 insertions(+), 10 deletions(-) create mode 100644 xtests/tst-pam_unix5.c create mode 100644 xtests/tst-pam_unix5.pamd create mode 100644 xtests/tst-pam_unix5.sh diff --git a/modules/pam_unix/pam_unix.8 b/modules/pam_unix/pam_unix.8 index 438717f..6f31c10 100644 --- a/modules/pam_unix/pam_unix.8 +++ b/modules/pam_unix/pam_unix.8 @@ -201,9 +201,16 @@ When a user changes their password next, encrypt it with the yescrypt algorithm\ function\&. .RE .PP +sm3 +.RS 4 +When a user changes their password next, encrypt it with the SM3 algorithm\&. The SM3 algorithm must be supported by the +\fBcrypt\fR(3) +function\&. +.RE +.PP rounds=n .RS 4 -Set the optional number of rounds of the SHA256, SHA512, blowfish, gost\-yescrypt, and yescrypt password hashing algorithms to +Set the optional number of rounds of the SHA256, SHA512, blowfish, gost\-yescrypt, yescrypt and SM3 password hashing algorithms to \fIn\fR\&. .RE .PP diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index dfc0427..7d61869 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.8.xml @@ -366,6 +366,20 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term> + sm3 + </term> + <listitem> + <para> + When a user changes their password next, + encrypt it with the SM3 algorithm. The + SM3 algorithm must be supported by the <citerefentry> + <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum> + </citerefentry> function. + </para> + </listitem> + </varlistentry> <varlistentry> <term> rounds=n @@ -373,7 +387,7 @@ <listitem> <para> Set the optional number of rounds of the SHA256, SHA512, - blowfish, gost-yescrypt, and yescrypt password hashing + blowfish, gost-yescrypt, yescrypt and SM3 password hashing algorithms to <replaceable>n</replaceable>. </para> diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 81b10d8..1aee153 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -445,6 +445,8 @@ PAMH_ARG_DECL(char * create_password_hash, algoid = "$5$"; } else if (on(UNIX_SHA512_PASS, ctrl)) { algoid = "$6$"; + } else if (on(UNIX_SM3_PASS, ctrl)) { + algoid = "$sm3$"; } else { /* must be crypt/bigcrypt */ char tmppass[9]; char *hashed; @@ -492,7 +494,8 @@ PAMH_ARG_DECL(char * create_password_hash, on(UNIX_GOST_YESCRYPT_PASS, ctrl) ? "gost_yescrypt" : on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" : on(UNIX_SHA256_PASS, ctrl) ? "sha256" : - on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid); + on(UNIX_SHA512_PASS, ctrl) ? "sha512" : + on(UNIX_SM3_PASS, ctrl) ? "sm3" : algoid); if(sp) { pam_overwrite_string(sp); } diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 043273d..4052868 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -99,7 +99,7 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, free (val); /* read number of rounds for crypt algo */ - if (rounds && (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl))) { + if (rounds && (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl) || on(UNIX_SM3_PASS, ctrl))) { val = pam_modutil_search_key(pamh, LOGIN_DEFS, "SHA_CRYPT_MAX_ROUNDS"); if (val) { @@ -194,7 +194,7 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, } else if (on(UNIX_BLOWFISH_PASS, ctrl)) { if (*rounds < 4 || *rounds > 31) *rounds = 5; - } else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) { + } else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl) || on(UNIX_SM3_PASS, ctrl)) { if ((*rounds < 1000) || (*rounds == INT_MAX)) { /* don't care about bogus values */ *rounds = 0; diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h index 8105400..b5712b5 100644 --- a/modules/pam_unix/support.h +++ b/modules/pam_unix/support.h @@ -101,10 +101,11 @@ typedef struct { #define UNIX_GOST_YESCRYPT_PASS 31 /* new password hashes will use gost-yescrypt */ #define UNIX_YESCRYPT_PASS 32 /* new password hashes will use yescrypt */ #define UNIX_NULLRESETOK 33 /* allow empty password if password reset is enforced */ +#define UNIX_SM3_PASS 34 /* new password hashes will use SM3 */ /* -------------- */ -#define UNIX_CTRLS_ 34 /* number of ctrl arguments defined */ +#define UNIX_CTRLS_ 35 /* number of ctrl arguments defined */ -#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)&&off(UNIX_GOST_YESCRYPT_PASS,ctrl)&&off(UNIX_YESCRYPT_PASS,ctrl)) +#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)&&off(UNIX_GOST_YESCRYPT_PASS,ctrl)&&off(UNIX_YESCRYPT_PASS,ctrl)&&off(UNIX_SM3_PASS,ctrl)) static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = { @@ -145,6 +146,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = /* UNIX_GOST_YESCRYPT_PASS */ {"gost_yescrypt", _ALL_ON_^(015660420000ULL), 04000000000, 1}, /* UNIX_YESCRYPT_PASS */ {"yescrypt", _ALL_ON_^(015660420000ULL), 010000000000, 1}, /* UNIX_NULLRESETOK */ {"nullresetok", _ALL_ON_, 020000000000, 0}, +/* UNIX_SM3_PASS */ {"sm3", _ALL_ON_^(015660420000ULL), 040000000000, 1}, }; #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) diff --git a/xtests/Makefile.am b/xtests/Makefile.am index acf9746..33693de 100644 --- a/xtests/Makefile.am +++ b/xtests/Makefile.am @@ -14,9 +14,9 @@ EXTRA_DIST = run-xtests.sh tst-pam_dispatch1.pamd tst-pam_dispatch2.pamd \ tst-pam_dispatch3.pamd tst-pam_dispatch4.pamd \ tst-pam_dispatch5.pamd \ tst-pam_unix1.pamd tst-pam_unix2.pamd tst-pam_unix3.pamd \ - tst-pam_unix4.pamd \ + tst-pam_unix4.pamd tst-pam_unix5.pamd \ tst-pam_unix1.sh tst-pam_unix2.sh tst-pam_unix3.sh \ - tst-pam_unix4.sh \ + tst-pam_unix4.sh tst-pam_unix5.sh \ access.conf tst-pam_access1.pamd tst-pam_access1.sh \ tst-pam_access2.pamd tst-pam_access2.sh \ tst-pam_access3.pamd tst-pam_access3.sh \ @@ -40,7 +40,7 @@ EXTRA_DIST = run-xtests.sh tst-pam_dispatch1.pamd tst-pam_dispatch2.pamd \ XTESTS = tst-pam_dispatch1 tst-pam_dispatch2 tst-pam_dispatch3 \ tst-pam_dispatch4 tst-pam_dispatch5 \ - tst-pam_unix1 tst-pam_unix2 tst-pam_unix3 tst-pam_unix4 \ + tst-pam_unix1 tst-pam_unix2 tst-pam_unix3 tst-pam_unix4 tst-pam_unix5 \ tst-pam_access1 tst-pam_access2 tst-pam_access3 \ tst-pam_access4 tst-pam_limits1 tst-pam_succeed_if1 \ tst-pam_group1 tst-pam_authfail tst-pam_authsucceed \ diff --git a/xtests/tst-pam_unix5.c b/xtests/tst-pam_unix5.c new file mode 100644 index 0000000..6e6e378 --- /dev/null +++ b/xtests/tst-pam_unix5.c @@ -0,0 +1,151 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Check password authtok. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <security/pam_appl.h> +#include <sys/types.h> +#include <pwd.h> +#include <unistd.h> + +/* A conversation function which uses an internally-stored value for + the responses. */ +static int +fake_conv (int num_msg, const struct pam_message **msgm, + struct pam_response **response, void *appdata_ptr) +{ + struct pam_response *reply; + int count; + + /* Sanity test. */ + if (num_msg <= 0) + return PAM_CONV_ERR; + + /* Allocate memory for the responses. */ + reply = calloc (num_msg, sizeof (struct pam_response)); + if (reply == NULL) + return PAM_CONV_ERR; + + /* Each prompt elicits the same response */ + for (count = 0; count < num_msg; ++count) + { + if (msgm[count]->msg_style == PAM_PROMPT_ECHO_OFF) + { + reply[count].resp_retcode = 0; + reply[count].resp = strdup(appdata_ptr); + } else { + reply[count].resp_retcode = 0; + reply[count].resp = strdup(""); + } + } + + /* Set the pointers in the response structure and return. */ + *response = reply; + return PAM_SUCCESS; +} + +static struct pam_conv conv = { + fake_conv, + NULL +}; + + +/* Check that errors of optional modules are ignored and that + required modules after a sufficient one are not executed. */ + +int +main(int argc, char *argv[]) +{ + pam_handle_t *pamh=NULL; + const char *user="tstpamunix"; + int retval; + int debug = 0; + int fail; + struct passwd *pwd; + + if (argc < 2 || (*argv[1] != 'f' && + *argv[1] != 'p')) + { + fprintf (stderr, "Need fail or pass argument.\n"); + return 2; + } + + fail = *argv[1] == 'f'; + + if (argc > 2 && strcmp (argv[2], "-d") == 0) + debug = 1; + + pwd = getpwnam (user); + + if (pwd == NULL) + { + if (debug) + fprintf (stderr, "unix5: Missing tstpamunix user.\n"); + return 2; + } + + conv.appdata_ptr = "zhangsan@123"; + retval = pam_start("tst-pam_unix5", user, &conv, &pamh); + if (retval != PAM_SUCCESS) + { + if (debug) + fprintf (stderr, "unix5: pam_start returned %d\n", retval); + return 1; + } + + retval = pam_chauthtok (pamh, PAM_SILENT); + if ((!fail && retval != PAM_SUCCESS) || (fail && retval == PAM_SUCCESS)) + { + if (debug) + fprintf (stderr, "unix5-1: pam_chauthtok returned %d\n", retval); + return 1; + } + + retval = pam_end (pamh,retval); + if (retval != PAM_SUCCESS) + { + if (debug) + fprintf (stderr, "unix5: pam_end returned %d\n", retval); + return 1; + } + return 0; +} diff --git a/xtests/tst-pam_unix5.pamd b/xtests/tst-pam_unix5.pamd new file mode 100644 index 0000000..4c77a6c --- /dev/null +++ b/xtests/tst-pam_unix5.pamd @@ -0,0 +1,5 @@ +#%PAM-1.0 +auth required pam_unix.so +account required pam_unix.so +password required pam_unix.so sm3 +session required pam_unix.so diff --git a/xtests/tst-pam_unix5.sh b/xtests/tst-pam_unix5.sh new file mode 100644 index 0000000..a6be19b --- /dev/null +++ b/xtests/tst-pam_unix5.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# testcase1 modify password, desire password encrypt with sm3 +/usr/sbin/useradd -p tstpamunix +# this run must successfully change the password +./tst-pam_unix5 pass +RET=$? +# verify tstpamunix hash algo +if test -z "$(nl /etc/shadow | sed -n '/tstpamunix:$sm3/p')"; then + /usr/sbin/userdel -r tstpamunix 2> /dev/null + exit 1 +fi +# testcase2 config valid rounds, desire password encrypt with sm3 and rounds +sed -i 's/password.*/& rounds=6666/g' /etc/pam.d/tst-pam_unix5 +./tst-pam_unix5 pass +RET=$? +if test -z "$(nl /etc/shadow | sed -n '/tstpamunix:$sm3$rounds=6666/p')"; then + /usr/sbin/userdel -r tstpamunix 2> /dev/null + exit 1 +fi + +# testcase3 config rounds=999, desire password encrypt with sm3, but without rounds +sed -i 's/rounds=6666/rounds=999/g' /etc/pam.d/tst-pam_unix5 +./tst-pam_unix5 pass +RET=$? +if test -z "$(nl /etc/shadow | sed -n '/tstpamunix:$sm3/p')"; then + /usr/sbin/userdel -r tstpamunix 2> /dev/null + exit 1 +fi + +# testcase4 config rounds=10000000, desire password encrypt with sm3, but with rounds=9999999 +sed -i 's/rounds=999/rounds=10000000/g' /etc/pam.d/tst-pam_unix5 +./tst-pam_unix5 pass +RET=$? +if test -z "$(nl /etc/shadow | sed -n '/tstpamunix:$sm3$rounds=9999999/p')"; then + /usr/sbin/userdel -r tstpamunix 2> /dev/null + exit 1 +fi + +/usr/sbin/userdel -r tstpamunix 2> /dev/null +exit $RET -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2