diff options
author | Mattias Andrée <maandree@member.fsf.org> | 2015-12-13 15:37:35 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@member.fsf.org> | 2015-12-13 15:37:35 +0100 |
commit | d3ef160b44bd6ab93be2d3fea13f4496cfb0cf81 (patch) | |
tree | ce132758305b1d3695aec606a1a75db7aa776d63 | |
parent | update scrotty (diff) | |
download | aur-packages-d3ef160b44bd6ab93be2d3fea13f4496cfb0cf81.tar.gz aur-packages-d3ef160b44bd6ab93be2d3fea13f4496cfb0cf81.tar.bz2 aur-packages-d3ef160b44bd6ab93be2d3fea13f4496cfb0cf81.tar.xz |
add shadow-libpassphrase
Signed-off-by: Mattias Andrée <maandree@member.fsf.org>
Diffstat (limited to '')
-rw-r--r-- | shadow-libpassphrase/0001-Use-libpassphrase-when-entering-passwords.patch | 460 | ||||
-rw-r--r-- | shadow-libpassphrase/0002-Make-libpassphrase-optional.patch | 144 | ||||
-rw-r--r-- | shadow-libpassphrase/LICENSE | 31 | ||||
-rw-r--r-- | shadow-libpassphrase/PKGBUILD | 163 | ||||
-rw-r--r-- | shadow-libpassphrase/chgpasswd | 4 | ||||
-rw-r--r-- | shadow-libpassphrase/chpasswd | 6 | ||||
-rw-r--r-- | shadow-libpassphrase/defaults.pam | 6 | ||||
-rw-r--r-- | shadow-libpassphrase/lastlog.tmpfiles | 1 | ||||
-rw-r--r-- | shadow-libpassphrase/login.defs | 208 | ||||
-rw-r--r-- | shadow-libpassphrase/newusers | 6 | ||||
-rw-r--r-- | shadow-libpassphrase/passwd | 4 | ||||
-rw-r--r-- | shadow-libpassphrase/shadow-strncpy-usage.patch | 25 | ||||
-rw-r--r-- | shadow-libpassphrase/shadow.install | 9 | ||||
-rw-r--r-- | shadow-libpassphrase/shadow.service | 10 | ||||
-rw-r--r-- | shadow-libpassphrase/shadow.timer | 7 | ||||
-rw-r--r-- | shadow-libpassphrase/useradd.defaults | 9 | ||||
-rw-r--r-- | shadow-libpassphrase/xstrdup.patch | 9 |
17 files changed, 1102 insertions, 0 deletions
diff --git a/shadow-libpassphrase/0001-Use-libpassphrase-when-entering-passwords.patch b/shadow-libpassphrase/0001-Use-libpassphrase-when-entering-passwords.patch new file mode 100644 index 0000000..226f4b5 --- /dev/null +++ b/shadow-libpassphrase/0001-Use-libpassphrase-when-entering-passwords.patch @@ -0,0 +1,460 @@ +From d5074436f7d8f9666fe1e6aac6d732ea62d182c8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= <maandree@member.fsf.org> +Date: Sat, 5 Dec 2015 21:09:45 +0100 +Subject: [PATCH 1/2] Use libpassphrase when entering passwords. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +libpassphrase can be compiled so that it can display +the strength of the password, including telling the +user that she is using a common passphrase. + +As a bonus, libpassphrase can be configured to do +something else then just be slient without echoes. + +Signed-off-by: Mattias Andrée <maandree@member.fsf.org> +--- + ChangeLog | 10 ++++++++ + README | 1 + + lib/Makefile.am | 6 +++-- + lib/pwauth.c | 6 +++-- + lib/xgetpass.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/xgetpass.h | 35 ++++++++++++++++++++++++++++ + libmisc/pam_pass.c | 40 +++++++++++++++++++++++++++++++- + src/gpasswd.c | 6 +++-- + src/newgrp.c | 4 +++- + src/passwd.c | 8 ++++--- + src/sulogin.c | 6 +++-- + 11 files changed, 176 insertions(+), 13 deletions(-) + create mode 100644 lib/xgetpass.c + create mode 100644 lib/xgetpass.h + +diff --git a/ChangeLog b/ChangeLog +index 23cd5ae..bc43385 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,13 @@ ++2015-12-05 Mattias Andrée <maandree@member.fsf.org> ++ ++ * lib/xgetpass.c: Add ability to use libpassphrase>=1449331105 instead of getpass. ++ * libmisc/pam_pass.c: Use xgetpass instead of misc_conv when entering (not retyping) the new password. ++ * lib/pwauth.c: Replace getpass with xgetpass. ++ * src/gpasswd.c: Likewise. ++ * src/newgrp.c: Likewise. ++ * src/passwd.c: Likewise. ++ * src/sulogin.c: Likewise. ++ + 2014-05-09 Christian Perrier <bubulle@debian.org> + + * Include patches only included in Debian for 4.2 +diff --git a/README b/README +index e531de6..5c27142 100644 +--- a/README ++++ b/README +@@ -87,6 +87,7 @@ Leonard N. Zubkoff <lnz@dandelion.com> + Luca Berra <bluca@www.polimi.it> + Lukáš Kuklínek <lkukline@redhat.com> + Lutz Schwalowsky <schwalow@mineralogie.uni-hamburg.de> ++Mattias Andrée <maandree@member.fsf.org> + Marc Ewing <marc@redhat.com> + Martin Bene <mb@sime.com> + Martin Mares <mj@gts.cz> +diff --git a/lib/Makefile.am b/lib/Makefile.am +index 6db86cd..3fa3817 100644 +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -5,7 +5,7 @@ DEFS = + + noinst_LTLIBRARIES = libshadow.la + +-libshadow_la_LDFLAGS = -version-info 0:0:0 ++libshadow_la_LDFLAGS = -version-info 0:0:0 -lpassphrase + + libshadow_la_SOURCES = \ + commonio.c \ +@@ -53,7 +53,9 @@ libshadow_la_SOURCES = \ + shadowio.h \ + shadowmem.c \ + spawn.c \ +- utent.c ++ utent.c \ ++ xgetpass.c \ ++ xgetpass.h + + if WITH_TCB + libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h +diff --git a/lib/pwauth.c b/lib/pwauth.c +index 9e24fbf..6775465 100644 +--- a/lib/pwauth.c ++++ b/lib/pwauth.c +@@ -3,6 +3,7 @@ + * Copyright (c) 1996 - 2000, Marek Michałkiewicz + * Copyright (c) 2003 - 2006, Tomasz Kłoczko + * Copyright (c) 2008 - 2009, Nicolas François ++ * Copyright (c) 2015 , Mattias Andrée + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -45,6 +46,7 @@ + #include "defines.h" + #include "pwauth.h" + #include "getdef.h" ++#include "xgetpass.h" + #ifdef SKEY + #include <skey.h> + #endif +@@ -161,7 +163,7 @@ int pw_auth (const char *cipher, + #endif + + snprintf (prompt, sizeof prompt, cp, user); +- clear = getpass (prompt); ++ clear = xgetpass (prompt, 0); + if (NULL == clear) { + static char c[1]; + +@@ -194,7 +196,7 @@ int pw_auth (const char *cipher, + * -- AR 8/22/1999 + */ + if ((0 != retval) && ('\0' == input[0]) && use_skey) { +- clear = getpass (prompt); ++ clear = xgetpass (prompt, 0); + if (NULL == clear) { + static char c[1]; + +diff --git a/lib/xgetpass.c b/lib/xgetpass.c +new file mode 100644 +index 0000000..a44ffc0 +--- /dev/null ++++ b/lib/xgetpass.c +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (c) 2015 , Mattias Andrée ++ * All rights reserved. ++ * ++ * 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, this list of conditions and the following disclaimer. ++ * 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 copyright holders or contributors may not be used to ++ * endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * ``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 COPYRIGHT ++ * HOLDERS OR CONTRIBUTORS 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. ++ */ ++ ++#include <config.h> ++ ++#ident "$Id$" ++ ++#include <unistd.h> ++#include <passphrase.h> ++#include <fcntl.h> ++#include <errno.h> ++#include <stdio.h> ++ ++char *xgetpass (const char *prompt, int is_new) ++{ ++ int fd, saved_errno; ++ char *pass; ++ ++ fd = open ("/dev/tty", O_RDWR); ++ if (-1 == fd) { ++ return NULL; ++ } ++ ++ passphrase_disable_echo1 (fd); ++ fprintf (stderr, "%s", prompt); ++ fflush (stderr); ++ pass = passphrase_read2 (fd, is_new ++ ? PASSPHRASE_READ_NEW | ++ PASSPHRASE_READ_SCREEN_FREE ++ : PASSPHRASE_READ_EXISTING); ++ saved_errno = errno; ++ passphrase_reenable_echo1 (fd); ++ errno = saved_errno; ++ return pass; ++ ++ /* ++ return getpass (prompt); ++ (void) is_new; ++ */ ++} ++ +diff --git a/lib/xgetpass.h b/lib/xgetpass.h +new file mode 100644 +index 0000000..b1abbb0 +--- /dev/null ++++ b/lib/xgetpass.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (c) 2015 , Mattias Andrée ++ * All rights reserved. ++ * ++ * 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, this list of conditions and the following disclaimer. ++ * 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 copyright holders or contributors may not be used to ++ * endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * ``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 COPYRIGHT ++ * HOLDERS OR CONTRIBUTORS 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. ++ */ ++ ++/* ++ * $Id$ ++ */ ++ ++ ++char *xgetpass (const char *prompt, int is_new); +diff --git a/libmisc/pam_pass.c b/libmisc/pam_pass.c +index a89bb2c..93029ec 100644 +--- a/libmisc/pam_pass.c ++++ b/libmisc/pam_pass.c +@@ -2,6 +2,7 @@ + * Copyright (c) 1997 - 1999, Marek Michałkiewicz + * Copyright (c) 2001 - 2005, Tomasz Kłoczko + * Copyright (c) 2008 , Nicolas François ++ * Copyright (c) 2015 , Mattias Andrée + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -42,22 +43,59 @@ + #include <stdio.h> + #include <stdlib.h> + #include <unistd.h> ++#include <string.h> + #include <sys/types.h> + #include "defines.h" + #include "pam_defs.h" + #include "prototypes.h" ++#include "xgetpass.h" ++ ++static int xgetpass_conv (int num_msg, const struct pam_message **msg, ++ struct pam_response **resp, void *appdata_ptr) ++{ ++ struct pam_response *response; ++ static int first_enter = 0; ++ int current; ++ int saved_errno; ++ ++ if ((num_msg != 1) || (msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)) ++ return conv.conv (num_msg, msg, resp, appdata_ptr); ++ ++ response = calloc((size_t)1, sizeof(struct pam_response)); ++ if (response == NULL) { ++ return PAM_CONV_ERR; ++ } ++ ++ current = strchr(msg[0]->msg, '(') != NULL; ++ first_enter ^= !current; ++ response->resp_retcode = 0; ++ response->resp = xgetpass (msg[0]->msg, first_enter & !current); ++ if (response->resp == NULL) { ++ saved_errno = errno; ++ free(response); ++ errno = saved_errno; ++ return PAM_CONV_ERR; ++ } ++ ++ *resp = response; ++ return PAM_SUCCESS; ++} ++ + + void do_pam_passwd (const char *user, bool silent, bool change_expired) + { + pam_handle_t *pamh = NULL; + int flags = 0, ret; ++ struct pam_conv conv_proper = conv; ++ ++ conv_proper.conv = xgetpass_conv; + + if (silent) + flags |= PAM_SILENT; + if (change_expired) + flags |= PAM_CHANGE_EXPIRED_AUTHTOK; + +- ret = pam_start ("passwd", user, &conv, &pamh); ++ ret = pam_start ("passwd", user, &conv_proper, &pamh); + if (ret != PAM_SUCCESS) { + fprintf (stderr, + _("passwd: pam_start() failed, error %d\n"), ret); +diff --git a/src/gpasswd.c b/src/gpasswd.c +index 8959a35..811a93d 100644 +--- a/src/gpasswd.c ++++ b/src/gpasswd.c +@@ -3,6 +3,7 @@ + * Copyright (c) 1996 - 2000, Marek Michałkiewicz + * Copyright (c) 2001 - 2006, Tomasz Kłoczko + * Copyright (c) 2007 - 2011, Nicolas François ++ * Copyright (c) 2015 , Mattias Andrée + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -46,6 +47,7 @@ + #include "groupio.h" + #include "nscd.h" + #include "prototypes.h" ++#include "xgetpass.h" + #ifdef SHADOWGRP + #include "sgroupio.h" + #endif +@@ -909,14 +911,14 @@ static void change_passwd (struct group *gr) + printf (_("Changing the password for group %s\n"), group); + + for (retries = 0; retries < RETRIES; retries++) { +- cp = getpass (_("New Password: ")); ++ cp = xgetpass (_("New Password: "), 1); + if (NULL == cp) { + exit (1); + } + + STRFCPY (pass, cp); + strzero (cp); +- cp = getpass (_("Re-enter new password: ")); ++ cp = xgetpass (_("Re-enter new password: "), 0); + if (NULL == cp) { + exit (1); + } +diff --git a/src/newgrp.c b/src/newgrp.c +index 49dd151..6ea3617 100644 +--- a/src/newgrp.c ++++ b/src/newgrp.c +@@ -3,6 +3,7 @@ + * Copyright (c) 1996 - 2000, Marek Michałkiewicz + * Copyright (c) 2001 - 2006, Tomasz Kłoczko + * Copyright (c) 2007 - 2008, Nicolas François ++ * Copyright (c) 2015 , Mattias Andrée + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -42,6 +43,7 @@ + #include "defines.h" + #include "getdef.h" + #include "prototypes.h" ++#include "xgetpass.h" + /*@-exitarg@*/ + #include "exitcodes.h" + +@@ -171,7 +173,7 @@ static void check_perms (const struct group *grp, + * get the password from her, and set the salt for + * the decryption from the group file. + */ +- cp = getpass (_("Password: ")); ++ cp = xgetpass (_("Password: "), 0); + if (NULL == cp) { + goto failure; + } +diff --git a/src/passwd.c b/src/passwd.c +index 3424f3b..c2cac67 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -3,6 +3,7 @@ + * Copyright (c) 1996 - 2000, Marek Michałkiewicz + * Copyright (c) 2001 - 2006, Tomasz Kłoczko + * Copyright (c) 2007 - 2011, Nicolas François ++ * Copyright (c) 2015 , Mattias Andrée + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -55,6 +56,7 @@ + #include "pwauth.h" + #include "pwio.h" + #include "shadowio.h" ++#include "xgetpass.h" + + /* + * exit status values +@@ -237,7 +239,7 @@ static int new_password (const struct passwd *pw) + */ + + if (!amroot && ('\0' != crypt_passwd[0])) { +- clear = getpass (_("Old password: ")); ++ clear = xgetpass (_("Old password: "), 1); + if (NULL == clear) { + return -1; + } +@@ -312,7 +314,7 @@ static int new_password (const struct passwd *pw) + + warned = false; + for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) { +- cp = getpass (_("New password: ")); ++ cp = xgetpass (_("New password: "), 1); + if (NULL == cp) { + memzero (orig, sizeof orig); + return -1; +@@ -339,7 +341,7 @@ static int new_password (const struct passwd *pw) + warned = true; + continue; + } +- cp = getpass (_("Re-enter new password: ")); ++ cp = xgetpass (_("Re-enter new password: "), 0); + if (NULL == cp) { + memzero (orig, sizeof orig); + return -1; +diff --git a/src/sulogin.c b/src/sulogin.c +index ccbf2c5..1296856 100644 +--- a/src/sulogin.c ++++ b/src/sulogin.c +@@ -3,6 +3,7 @@ + * Copyright (c) 1996 - 2000, Marek Michałkiewicz + * Copyright (c) 2002 - 2006, Tomasz Kłoczko + * Copyright (c) 2007 - 2010, Nicolas François ++ * Copyright (c) 2015 , Mattias Andrée + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -43,6 +44,7 @@ + #include "getdef.h" + #include "prototypes.h" + #include "pwauth.h" ++#include "xgetpass.h" + /*@-exitarg@*/ + #include "exitcodes.h" + +@@ -202,10 +204,10 @@ static RETSIGTYPE catch_signals (unused int sig) + */ + + /* get a password for root */ +- cp = getpass (_( ++ cp = xgetpass (_( + "\n" + "Type control-d to proceed with normal startup,\n" +-"(or give root password for system maintenance):")); ++"(or give root password for system maintenance): "), 0); + /* + * XXX - can't enter single user mode if root password is + * empty. I think this doesn't happen very often :-). But +-- +2.6.3 + diff --git a/shadow-libpassphrase/0002-Make-libpassphrase-optional.patch b/shadow-libpassphrase/0002-Make-libpassphrase-optional.patch new file mode 100644 index 0000000..86c3e1f --- /dev/null +++ b/shadow-libpassphrase/0002-Make-libpassphrase-optional.patch @@ -0,0 +1,144 @@ +From 5b110e7aaac8d20559eba96f2a9d0dbae2b83dc9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= <maandree@member.fsf.org> +Date: Mon, 7 Dec 2015 08:02:01 +0100 +Subject: [PATCH 2/2] Make libpassphrase optional +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Mattias Andrée <maandree@member.fsf.org> +--- + ChangeLog | 5 +++++ + configure.in | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/xgetpass.c | 16 +++++++++------- + 3 files changed, 64 insertions(+), 7 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index bc43385..fd7389b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2015-12-07 Mattias Andrée <maandree@member.fsf.org> ++ ++ * lib/xgetpass.c: Make libpassphrase optional. ++ * configure.in: Likewise. ++ + 2015-12-05 Mattias Andrée <maandree@member.fsf.org> + + * lib/xgetpass.c: Add ability to use libpassphrase>=1449331105 instead of getpass. +diff --git a/configure.in b/configure.in +index a55f125..b752e18 100644 +--- a/configure.in ++++ b/configure.in +@@ -253,6 +253,9 @@ AC_ARG_WITH(audit, + AC_ARG_WITH(libpam, + [AC_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])], + [with_libpam=$withval], [with_libpam=maybe]) ++AC_ARG_WITH(libpassphrase, ++ [AC_HELP_STRING([--with-libpassphrase], [use libpassphrase support @<:@default=yes if found@:>@])], ++ [with_libpassphrase=$withval], [with_libpassphrase=maybe]) + AC_ARG_WITH(selinux, + [AC_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])], + [with_selinux=$withval], [with_selinux=maybe]) +@@ -581,6 +584,52 @@ else + AC_MSG_RESULT(yes) + fi + ++AC_SUBST(LIBPASSPHRASE) ++if test "$with_libpassphrase" != "no"; then ++ dnl passphrase_read has always existed ++ AC_CHECK_LIB(passphrase, passphrase_read, ++ [passphrase_lib="yes"], [passphrase_lib="no"]) ++ if test "$passphrase_lib$with_libpassphrase" = "noyes" ; then ++ AC_MSG_ERROR(libpassphrase not found) ++ fi ++ ++ LIBPASSPHRASE="-lpassphrase" ++ passphrase_read2_function="no" ++ dnl passphrase_read2 was, along with other used functions, introduced in libpassphrase=1449331105 ++ ++ AC_CHECK_LIB(passphrase, passphrase_read2, ++ [passphrase_read2_function="yes"], []) ++ ++ if test "$passphrase_read2_function$with_libpassphrase" = "noyes" ; then ++ AC_MSG_ERROR(Only version 1449331105 and later of libpassphrase are supported) ++ fi ++ ++ passphrase_header_found=no ++ AC_CHECK_HEADERS(passphrase.h, ++ [ passphrase_header_found=yes ; break ], [], ++ [ #include <passphrase.h> ] ) ++ if test "$passphrase_header_found$with_libpassphrase" = "noyes" ; then ++ AC_MSG_ERROR(libpassphrase header not found) ++ fi ++ ++ if test "$passphrase_lib$passphrase_header_found$passphrase_read2_function" = "yesyesyes" ; then ++ with_libpassphrase="yes" ++ else ++ with_libpassphrase="no" ++ unset LIBPASSPHRASE ++ fi ++fi ++ ++if test "$with_libpassphrase" = "yes"; then ++ save_libs="$LIBS" ++ LIBS="$LIBS $LIBPASSPHRASE" ++ ++ AC_DEFINE(USE_LIBPASSPHRASE, 1, [Define to support libpassphrase]) ++ AM_CONDITIONAL(USE_LIBPASSPHRASE, [true]) ++else ++ AM_CONDITIONAL(USE_LIBPASSPHRASE, [false]) ++fi ++ + if test "$enable_acct_tools_setuid" != "no"; then + if test "$with_libpam" != "yes"; then + if test "$enable_acct_tools_setuid" = "yes"; then +@@ -670,6 +719,7 @@ echo + echo " auditing support: $with_audit" + echo " CrackLib support: $with_libcrack" + echo " PAM support: $with_libpam" ++echo " libpassphrase support: $with_libpassphrase" + if test "$with_libpam" = "yes"; then + echo " suid account management tools: $enable_acct_tools_setuid" + fi +diff --git a/lib/xgetpass.c b/lib/xgetpass.c +index a44ffc0..4efa33d 100644 +--- a/lib/xgetpass.c ++++ b/lib/xgetpass.c +@@ -32,13 +32,16 @@ + #ident "$Id$" + + #include <unistd.h> +-#include <passphrase.h> +-#include <fcntl.h> +-#include <errno.h> +-#include <stdio.h> ++#ifdef USE_LIBPASSPHRASE ++# include <passphrase.h> ++# include <fcntl.h> ++# include <errno.h> ++# include <stdio.h> ++#endif + + char *xgetpass (const char *prompt, int is_new) + { ++#ifdef USE_LIBPASSPHRASE + int fd, saved_errno; + char *pass; + +@@ -58,10 +61,9 @@ char *xgetpass (const char *prompt, int is_new) + passphrase_reenable_echo1 (fd); + errno = saved_errno; + return pass; +- +- /* ++#else + return getpass (prompt); + (void) is_new; +- */ ++#endif + } + +-- +2.6.3 + diff --git a/shadow-libpassphrase/LICENSE b/shadow-libpassphrase/LICENSE new file mode 100644 index 0000000..c5ab15a --- /dev/null +++ b/shadow-libpassphrase/LICENSE @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1990 - 1994, Julianne Frances Haugh + * Copyright (c) 1996 - 2000, Marek Michałkiewicz + * Copyright (c) 2001 - 2006, Tomasz Kłoczko + * Copyright (c) 2007 - 2009, Nicolas François + * All rights reserved. + * + * 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, this list of conditions and the following disclaimer. + * 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 copyright holders or contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 COPYRIGHT + * HOLDERS OR CONTRIBUTORS 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. + */ diff --git a/shadow-libpassphrase/PKGBUILD b/shadow-libpassphrase/PKGBUILD new file mode 100644 index 0000000..5242709 --- /dev/null +++ b/shadow-libpassphrase/PKGBUILD @@ -0,0 +1,163 @@ +# Maintainer: Mattias Andrée <`base64 -d`(bWFhbmRyZWUK)@member.fsf.org> +# Maintainer of the shadow package: Dave Reisner <dreisner@archlinux.org> +# Maintainer of the shadow package: Aaron Griffin <aaron@archlinux.org> + +_pkgname=shadow +pkgname=shadow-libpassphrase +pkgver=4.2.1 +pkgrel=1 +pkgdesc="Patched version of shadow that uses libpassphrase and can indicate the strenght of your new password" +arch=('i686' 'x86_64') +url='https://github.com/maandree/shadow' +license=('BSD') +groups=('base') +depends=('bash' 'pam' 'acl' 'libpassphrase>=1449331105') +makedepends=('pam' 'acl' 'libpassphrase>=1449331105') +optdepends=('passcheck: for password strenght meter') +conflicts=(shadow) +provides=('shadow=4.2.1') +backup=(etc/login.defs + etc/pam.d/{chage,passwd,shadow,useradd,usermod,userdel} + etc/pam.d/{chpasswd,newusers,groupadd,groupdel,groupmod} + etc/pam.d/{chgpasswd,groupmems} + etc/default/useradd) +options=(strip) +install='shadow.install' +source=("http://pkg-shadow.alioth.debian.org/releases/$_pkgname-$pkgver.tar.xz" + '0001-Use-libpassphrase-when-entering-passwords.patch' + '0002-Make-libpassphrase-optional.patch' + LICENSE + chgpasswd + chpasswd + defaults.pam + login.defs + newusers + passwd + shadow.{timer,service} + useradd.defaults + xstrdup.patch + shadow-strncpy-usage.patch + lastlog.tmpfiles) +sha1sums=('0917cbadd4ce0c7c36670e5ecd37bbed92e6d82d' + 08ac0b8cbcfaa9dbab5caec52aeab702e7869a0c + 8d163eb290c2a41009abb9f0e1f84cacb9febb78 + '33a6cf1e44a1410e5c9726c89e5de68b78f5f922' + '4ad0e059406a305c8640ed30d93c2a1f62c2f4ad' + '12427b1ca92a9b85ca8202239f0d9f50198b818f' + '0e56fed7fc93572c6bf0d8f3b099166558bb46f1' + 'bb3509087947d08bfb6e5d1b5c033856b9146ad9' + '12427b1ca92a9b85ca8202239f0d9f50198b818f' + '611be25d91c3f8f307c7fe2485d5f781e5dee75f' + 'a154a94b47a3d0c6c287253b98c0d10b861226d0' + 'e40fc20894e69a07fb0070b41f567d0c27133720' + '9ae93de5987dd0ae428f0cc1a5a5a5cd53583f19' + '6010fffeed1fc6673ad9875492e1193b1a847b53' + '21e12966a6befb25ec123b403cd9b5c492fe5b16' + 'f57ecde3f72b4738fad75c097d19cf46a412350f') + +prepare() { + cd "$_pkgname-$pkgver" + + patch -Np1 <"$srcdir/0001-Use-libpassphrase-when-entering-passwords.patch" + patch -Np1 <"$srcdir/0002-Make-libpassphrase-optional.patch" + + # need to offer these upstream + patch -Np1 <"$srcdir/xstrdup.patch" + patch -Np1 <"$srcdir/shadow-strncpy-usage.patch" + + # supress etc/pam.d/*, we provide our own + sed -i '/^SUBDIRS/s/pam\.d//' etc/Makefile.in +} + +build() { + cd "$_pkgname-$pkgver" + + libtoolize + aclocal + autoheader + autoconf + automake --add-missing + + ./configure \ + LIBS="-lcrypt" \ + --prefix=/usr \ + --bindir=/usr/bin \ + --sbindir=/usr/bin \ + --libdir=/usr/lib \ + --mandir=/usr/share/man \ + --sysconfdir=/etc \ + --without-libpam \ + --with-group-name-max-length=32 \ + --without-selinux \ + --with-libpassphrase + + make +} + +package() { + cd "$_pkgname-$pkgver" + + make DESTDIR="$pkgdir" install + + # license + install -Dm644 "$srcdir/LICENSE" "$pkgdir/usr/share/licenses/shadow/LICENSE" + + # useradd defaults + install -Dm644 "$srcdir/useradd.defaults" "$pkgdir/etc/default/useradd" + + # systemd timer + install -D -m644 "$srcdir/shadow.timer" "$pkgdir/usr/lib/systemd/system/shadow.timer" + install -D -m644 "$srcdir/shadow.service" $pkgdir/usr/lib/systemd/system/shadow.service + install -d -m755 "$pkgdir/usr/lib/systemd/system/multi-user.target.wants" + ln -s ../shadow.timer "$pkgdir/usr/lib/systemd/system/multi-user.target.wants/shadow.timer" + + # login.defs + install -Dm644 "$srcdir/login.defs" "$pkgdir/etc/login.defs" + + # PAM config - custom + install -dm755 "$pkgdir/etc/pam.d" + install -t "$pkgdir/etc/pam.d" -m644 "$srcdir"/{passwd,chgpasswd,chpasswd,newusers} + + # PAM config - from tarball + install -Dm644 etc/pam.d/groupmems "$pkgdir/etc/pam.d/groupmems" + + # we use the 'useradd' PAM file for other similar utilities + for file in chage groupadd groupdel groupmod shadow \ + useradd usermod userdel; do + install -Dm644 "$srcdir/defaults.pam" "$pkgdir/etc/pam.d/$file" + done + + # lastlog log file creation + install -Dm644 "$srcdir/lastlog.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/lastlog.conf" + + # Remove evil/broken tools + rm "$pkgdir"/usr/sbin/logoutd + + # Remove utilities provided by util-linux + rm \ + "$pkgdir"/usr/bin/{login,su,chsh,chfn,sg,nologin} \ + "$pkgdir"/usr/sbin/{vipw,vigr} + + # but we keep newgrp, as sg is really an alias to it + mv "$pkgdir"/usr/bin/{newgrp,sg} + + # ...and their many man pages + find "$pkgdir"/usr/share/man \ + '(' -name 'chsh.1' -o \ + -name 'chfn.1' -o \ + -name 'su.1' -o \ + -name 'logoutd.8' -o \ + -name 'login.1' -o \ + -name 'nologin.8' -o \ + -name 'vipw.8' -o \ + -name 'vigr.8' -o \ + -name 'newgrp.1' ')' \ + -delete + rmdir \ + "$pkgdir"/usr/share/man/{fi,id,zh_TW}/man1 \ + "$pkgdir"/usr/share/man/{fi,ko/man8} + + # move everything else to /usr/bin, because this isn't handled by ./configure + mv "$pkgdir"/usr/sbin/* "$pkgdir"/usr/bin + rmdir "$pkgdir/usr/sbin" +} diff --git a/shadow-libpassphrase/chgpasswd b/shadow-libpassphrase/chgpasswd new file mode 100644 index 0000000..8f49f5c --- /dev/null +++ b/shadow-libpassphrase/chgpasswd @@ -0,0 +1,4 @@ +#%PAM-1.0 +auth sufficient pam_rootok.so +account required pam_permit.so +password include system-auth diff --git a/shadow-libpassphrase/chpasswd b/shadow-libpassphrase/chpasswd new file mode 100644 index 0000000..5d44798 --- /dev/null +++ b/shadow-libpassphrase/chpasswd @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth sufficient pam_rootok.so +auth required pam_unix.so +account required pam_unix.so +session required pam_unix.so +password required pam_unix.so sha512 shadow diff --git a/shadow-libpassphrase/defaults.pam b/shadow-libpassphrase/defaults.pam new file mode 100644 index 0000000..a7bf8a4 --- /dev/null +++ b/shadow-libpassphrase/defaults.pam @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth sufficient pam_rootok.so +auth required pam_unix.so +account required pam_unix.so +session required pam_unix.so +password required pam_permit.so diff --git a/shadow-libpassphrase/lastlog.tmpfiles b/shadow-libpassphrase/lastlog.tmpfiles new file mode 100644 index 0000000..9c07b39 --- /dev/null +++ b/shadow-libpassphrase/lastlog.tmpfiles @@ -0,0 +1 @@ +f /var/log/lastlog 0644 root root diff --git a/shadow-libpassphrase/login.defs b/shadow-libpassphrase/login.defs new file mode 100644 index 0000000..5c88828 --- /dev/null +++ b/shadow-libpassphrase/login.defs @@ -0,0 +1,208 @@ +# +# /etc/login.defs - Configuration control definitions for the login package. +# +# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH. +# If unspecified, some arbitrary (and possibly incorrect) value will +# be assumed. All other items are optional - if not specified then +# the described action or option will be inhibited. +# +# Comment lines (lines beginning with "#") and blank lines are ignored. +# +# Modified for Linux. --marekm + +# +# Delay in seconds before being allowed another attempt after a login failure +# +FAIL_DELAY 3 + +# +# Enable display of unknown usernames when login failures are recorded. +# +LOG_UNKFAIL_ENAB no + +# +# Enable logging of successful logins +# +LOG_OK_LOGINS no + +# +# Enable "syslog" logging of su activity - in addition to sulog file logging. +# SYSLOG_SG_ENAB does the same for newgrp and sg. +# +SYSLOG_SU_ENAB yes +SYSLOG_SG_ENAB yes + +# +# If defined, either full pathname of a file containing device names or +# a ":" delimited list of device names. Root logins will be allowed only +# upon these devices. +# +CONSOLE /etc/securetty +#CONSOLE console:tty01:tty02:tty03:tty04 + +# +# If defined, all su activity is logged to this file. +# +#SULOG_FILE /var/log/sulog + +# +# If defined, file which maps tty line to TERM environment parameter. +# Each line of the file is in a format something like "vt100 tty01". +# +#TTYTYPE_FILE /etc/ttytype + +# +# If defined, the command name to display when running "su -". For +# example, if this is defined as "su" then a "ps" will display the +# command is "-su". If not defined, then "ps" would display the +# name of the shell actually being run, e.g. something like "-sh". +# +SU_NAME su + +# +# *REQUIRED* +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define both, MAIL_DIR takes precedence. +# QMAIL_DIR is for Qmail +# +#QMAIL_DIR Maildir +MAIL_DIR /var/spool/mail + +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# +# *REQUIRED* The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +ENV_SUPATH PATH=/usr/bin +ENV_PATH PATH=/usr/bin + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a "write" program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP to the group number and +# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign +# TTYPERM to either 622 or 600. +# +TTYGROUP tty +TTYPERM 0600 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# UMASK Default "umask" value. +# +# The ERASECHAR and KILLCHAR are used only on System V machines. +# The ULIMIT is used only if the system supports it. +# (now it works with setrlimit too; ulimit is in 512-byte units) +# +# Prefix these values with "0" to get octal, "0x" to get hexadecimal. +# +ERASECHAR 0177 +KILLCHAR 025 +UMASK 077 + +# +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +PASS_WARN_AGE 7 + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +SYS_UID_MIN 500 +SYS_UID_MAX 999 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +SYS_GID_MIN 500 +SYS_GID_MAX 999 + +# +# Max number of login retries if password is bad +# +LOGIN_RETRIES 5 + +# +# Max time in seconds for login +# +LOGIN_TIMEOUT 60 + +# +# Which fields may be changed by regular users using chfn - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +CHFN_RESTRICT rwh + +# +# List of groups to add to the user's supplementary group set +# when logging in on the console (as determined by the CONSOLE +# setting). Default is none. +# +# Use with caution - it is possible for users to gain permanent +# access to these groups, even when not logged in on the console. +# How to do it is left as an exercise for the reader... +# +#CONSOLE_GROUPS floppy:audio:cdrom + +# +# Should login be allowed if we can't cd to the home directory? +# Default in no. +# +DEFAULT_HOME yes + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# Enable setting of the umask group bits to be the same as owner bits +# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is +# the same as gid, and username is the same as the primary group name. +# +# This also enables userdel to remove user groups if no members exist. +# +USERGROUPS_ENAB yes + +# +# Controls display of the motd file. This is better handled by pam_motd.so +# so the declaration here is empty is suppress display by readers of this +# file. +# +MOTD_FILE + +# +# Hash shadow passwords with SHA512. +# +ENCRYPT_METHOD SHA512 diff --git a/shadow-libpassphrase/newusers b/shadow-libpassphrase/newusers new file mode 100644 index 0000000..5d44798 --- /dev/null +++ b/shadow-libpassphrase/newusers @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth sufficient pam_rootok.so +auth required pam_unix.so +account required pam_unix.so +session required pam_unix.so +password required pam_unix.so sha512 shadow diff --git a/shadow-libpassphrase/passwd b/shadow-libpassphrase/passwd new file mode 100644 index 0000000..ab56da4 --- /dev/null +++ b/shadow-libpassphrase/passwd @@ -0,0 +1,4 @@ +#%PAM-1.0 +#password required pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3 +#password required pam_unix.so sha512 shadow use_authtok +password required pam_unix.so sha512 shadow nullok diff --git a/shadow-libpassphrase/shadow-strncpy-usage.patch b/shadow-libpassphrase/shadow-strncpy-usage.patch new file mode 100644 index 0000000..5aba8fa --- /dev/null +++ b/shadow-libpassphrase/shadow-strncpy-usage.patch @@ -0,0 +1,25 @@ +diff -u shadow-4.1.5/src/usermod.c.orig shadow-4.1.5/src/usermod.c +--- shadow-4.1.5/src/usermod.c.orig 2012-02-13 08:19:43.792146449 -0500 ++++ shadow-4.1.5/src/usermod.c 2012-02-13 08:21:19.375114500 -0500 +@@ -182,7 +182,7 @@ + struct tm *tp; + + if (date < 0) { +- strncpy (buf, "never", maxsize); ++ strncpy (buf, "never", maxsize - 1); + } else { + time_t t = (time_t) date; + tp = gmtime (&t); +diff -u shadow-4.1.5/src/login.c.orig shadow-4.1.5/src/login.c +--- shadow-4.1.5/src/login.c.orig 2012-02-13 08:19:50.951994454 -0500 ++++ shadow-4.1.5/src/login.c 2012-02-13 08:21:04.490430937 -0500 +@@ -752,7 +752,8 @@ + _("%s login: "), hostn); + } else { + strncpy (loginprompt, _("login: "), +- sizeof (loginprompt)); ++ sizeof (loginprompt) - 1); ++ loginprompt[sizeof (loginprompt) - 1] = '\0'; + } + + retcode = pam_set_item (pamh, PAM_USER_PROMPT, loginprompt); diff --git a/shadow-libpassphrase/shadow.install b/shadow-libpassphrase/shadow.install new file mode 100644 index 0000000..14384c3 --- /dev/null +++ b/shadow-libpassphrase/shadow.install @@ -0,0 +1,9 @@ +post_upgrade() { + grpck -r >/dev/null 2>&1 + if [ $? -eq 2 ]; then + printf '%s\n' \ + "==> Warning: /etc/group or /etc/gshadow are inconsistent." \ + " Run 'grpck' to correct this." + fi + return 0 +} diff --git a/shadow-libpassphrase/shadow.service b/shadow-libpassphrase/shadow.service new file mode 100644 index 0000000..5c1c845 --- /dev/null +++ b/shadow-libpassphrase/shadow.service @@ -0,0 +1,10 @@ +[Unit] +Description=Verify integrity of password and group files + +[Service] +Type=oneshot +ExecStart=/usr/bin/pwck -r +ExecStart=/usr/bin/grpck -r +Nice=19 +IOSchedulingClass=best-effort +IOSchedulingPriority=7 diff --git a/shadow-libpassphrase/shadow.timer b/shadow-libpassphrase/shadow.timer new file mode 100644 index 0000000..9cc6baa --- /dev/null +++ b/shadow-libpassphrase/shadow.timer @@ -0,0 +1,7 @@ +[Unit] +Description=Daily verification of password and group files + +[Timer] +OnCalendar=daily +AccuracySec=12h +Persistent=true diff --git a/shadow-libpassphrase/useradd.defaults b/shadow-libpassphrase/useradd.defaults new file mode 100644 index 0000000..b800b17 --- /dev/null +++ b/shadow-libpassphrase/useradd.defaults @@ -0,0 +1,9 @@ +# useradd defaults file for ArchLinux +# original changes by TomK +GROUP=100 +HOME=/home +INACTIVE=-1 +EXPIRE= +SHELL=/bin/bash +SKEL=/etc/skel +CREATE_MAIL_SPOOL=no diff --git a/shadow-libpassphrase/xstrdup.patch b/shadow-libpassphrase/xstrdup.patch new file mode 100644 index 0000000..bce4342 --- /dev/null +++ b/shadow-libpassphrase/xstrdup.patch @@ -0,0 +1,9 @@ +--- shadow-4.1.2.1/libmisc/xmalloc.c 2008-08-30 21:55:44.000000000 -0500 ++++ shadow-4.1.2.1/libmisc/xmalloc.c.new 2008-08-30 21:55:36.000000000 -0500 +@@ -61,5 +61,6 @@ + + char *xstrdup (const char *str) + { ++ if(str == NULL) return NULL; + return strcpy (xmalloc (strlen (str) + 1), str); + } |