SHA256
1
0
forked from pool/pam_kwallet

Accepting request 518277 from KDE:Frameworks5

Plasma 5.10.5 (forwarded request 518189 from Vogtinator)

OBS-URL: https://build.opensuse.org/request/show/518277
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/pam_kwallet?expand=0&rev=13
This commit is contained in:
Dominique Leuenberger 2017-08-23 09:55:23 +00:00 committed by Git OBS Bridge
commit 9bdabe4b58
8 changed files with 357 additions and 9 deletions

162
0001-Several-cleanups.patch Normal file
View File

@ -0,0 +1,162 @@
From a6369519e080b741fea731ab42bb19e84c6e6fdb Mon Sep 17 00:00:00 2001
From: Fabian Vogt <fabian@ritter-vogt.de>
Date: Thu, 3 Aug 2017 09:02:14 +0200
Subject: [PATCH 1/3] Several cleanups
- No cppcheck warnings anymore
- Use snprintf everywhere
- Avoid pointless multiplication with sizeof(char)
- Avoid memory leaks
---
pam_kwallet.c | 44 ++++++++++++++++++++++++++++++++------------
1 file changed, 32 insertions(+), 12 deletions(-)
diff --git a/pam_kwallet.c b/pam_kwallet.c
index d88c5e0..cba57e7 100644
--- a/pam_kwallet.c
+++ b/pam_kwallet.c
@@ -151,13 +151,14 @@ static int set_env(pam_handle_t *pamh, const char *name, const char *value)
//We do not return because pam_putenv might work
}
- char *pamEnv = malloc(strlen(name) + strlen(value) + 2); //2 is for = and \0
+ size_t pamEnvSize = strlen(name) + strlen(value) + 2; //2 is for = and \0
+ char *pamEnv = malloc(pamEnvSize);
if (!pamEnv) {
pam_syslog(pamh, LOG_WARNING, "%s: Impossible to allocate memory for pamEnv", logPrefix);
return -1;
}
- sprintf (pamEnv, "%s=%s", name, value);
+ snprintf (pamEnv, pamEnvSize, "%s=%s", name, value);
int ret = pam_putenv(pamh, pamEnv);
free(pamEnv);
@@ -240,6 +241,11 @@ cleanup:
return result;
}
+static void cleanup_free(pam_handle_t *pamh, void *ptr, int error_status)
+{
+ free(ptr);
+}
+
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
pam_syslog(pamh, LOG_INFO, "%s: pam_sm_authenticate\n", logPrefix);
@@ -297,14 +303,17 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, cons
return PAM_IGNORE;
}
- char *key = malloc(sizeof(char) * KWALLET_PAM_KEYSIZE);
- if (kwallet_hash(password, userInfo, key) != 0) {
+ char *key = malloc(KWALLET_PAM_KEYSIZE);
+ if (!key || kwallet_hash(password, userInfo, key) != 0) {
+ free(key);
pam_syslog(pamh, LOG_ERR, "%s: Fail into creating the hash", logPrefix);
return PAM_IGNORE;
}
- result = pam_set_data(pamh, kwalletPamDataKey, key, NULL);
+ result = pam_set_data(pamh, kwalletPamDataKey, key, cleanup_free);
+
if (result != PAM_SUCCESS) {
+ free(key);
pam_syslog(pamh, LOG_ERR, "%s: Impossible to store the hashed password: %s", logPrefix
, pam_strerror(pamh, result));
return PAM_IGNORE;
@@ -385,9 +394,8 @@ cleanup:
static int better_write(int fd, const char *buffer, int len)
{
size_t writtenBytes = 0;
- int result;
while(writtenBytes < len) {
- result = write(fd, buffer + writtenBytes, len - writtenBytes);
+ int result = write(fd, buffer + writtenBytes, len - writtenBytes);
if (result < 0) {
if (errno != EAGAIN && errno != EINTR) {
return -1;
@@ -450,6 +458,7 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha
if (result != PAM_SUCCESS) {
pam_syslog(pamh, LOG_ERR, "%s: Impossible to set %s env, %s",
logPrefix, envVar, pam_strerror(pamh, result));
+ free(fullSocket);
return;
}
@@ -459,12 +468,15 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha
if (strlen(fullSocket) > sizeof(local.sun_path)) {
pam_syslog(pamh, LOG_ERR, "%s: socket path %s too long to open",
logPrefix, fullSocket);
+ free(fullSocket);
return;
}
strcpy(local.sun_path, fullSocket);
+ free(fullSocket);
+ fullSocket = NULL;
unlink(local.sun_path);//Just in case it exists from a previous login
- pam_syslog(pamh, LOG_INFO, "%s: final socket path: %s", logPrefix, fullSocket);
+ pam_syslog(pamh, LOG_INFO, "%s: final socket path: %s", logPrefix, local.sun_path);
size_t len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(envSocket, (struct sockaddr *)&local, len) == -1) {
@@ -477,7 +489,7 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha
return;
}
- if (chown(fullSocket, userInfo->pw_uid, userInfo->pw_gid) == -1) {
+ if (chown(local.sun_path, userInfo->pw_uid, userInfo->pw_gid) == -1) {
pam_syslog(pamh, LOG_INFO, "%s: Couldn't change ownership of the socket", logPrefix);
return;
}
@@ -655,7 +667,8 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key)
#else
char *fixpath = "share/apps/kwallet/kdewallet.salt";
#endif
- char *path = (char*) malloc(strlen(userInfo->pw_dir) + strlen(kdehome) + strlen(fixpath) + 3);//3 == / and \0
+ size_t pathSize = strlen(userInfo->pw_dir) + strlen(kdehome) + strlen(fixpath) + 3;//3 == /, / and \0
+ char *path = (char*) malloc(pathSize);
sprintf(path, "%s/%s/%s", userInfo->pw_dir, kdehome, fixpath);
struct stat info;
@@ -666,21 +679,26 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key)
FILE *fd = fopen(path, "r");
if (fd == NULL) {
syslog(LOG_ERR, "%s: Couldn't open file: %s because: %d-%s", logPrefix, path, errno, strerror(errno));
+ free(path);
return 1;
}
- salt = (char*) malloc(sizeof(char) * KWALLET_PAM_SALTSIZE);
+ salt = (char*) malloc(KWALLET_PAM_SALTSIZE);
memset(salt, '\0', KWALLET_PAM_SALTSIZE);
fread(salt, KWALLET_PAM_SALTSIZE, 1, fd);
fclose(fd);
}
+ free(path);
+
if (salt == NULL) {
syslog(LOG_ERR, "%s-kwalletd: Couldn't create or read the salt file", logPrefix);
return 1;
}
gcry_error_t error;
+
error = gcry_control(GCRYCTL_INIT_SECMEM, 32768, 0);
if (error != 0) {
+ free(salt);
syslog(LOG_ERR, "%s-kwalletd: Can't get secure memory: %d", logPrefix, error);
return 1;
}
@@ -691,5 +709,7 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key)
GCRY_KDF_PBKDF2, GCRY_MD_SHA512,
salt, KWALLET_PAM_SALTSIZE,
KWALLET_PAM_ITERATIONS,KWALLET_PAM_KEYSIZE, key);
- return 0;
+
+ free(salt);
+ return (int) error; // gcry_kdf_derive returns 0 on success
}
--
2.13.2

View File

@ -0,0 +1,38 @@
From a8153375a5006f5ca766b58a1a8f488699314a74 Mon Sep 17 00:00:00 2001
From: Fabian Vogt <fabian@ritter-vogt.de>
Date: Thu, 3 Aug 2017 09:27:10 +0200
Subject: [PATCH 2/3] Avoid dropping privileges by initializing gcrypt secmem
It's a documented side effect that initialization of secure memory in gcrypt
drops privileges if getuid() != geteuid(). This results in breaking setuid
callers, like sudo or su.
---
pam_kwallet.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/pam_kwallet.c b/pam_kwallet.c
index cba57e7..dc61115 100644
--- a/pam_kwallet.c
+++ b/pam_kwallet.c
@@ -696,12 +696,18 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key)
gcry_error_t error;
+ /* We cannot call GCRYCTL_INIT_SECMEM as it drops privileges if getuid() != geteuid().
+ * PAM modules are in many cases executed through setuid binaries, which this call
+ * would break.
+ * It was never effective anyway as neither key nor passphrase are in secure memory,
+ * which is a prerequisite for secure operation...
error = gcry_control(GCRYCTL_INIT_SECMEM, 32768, 0);
if (error != 0) {
free(salt);
syslog(LOG_ERR, "%s-kwalletd: Can't get secure memory: %d", logPrefix, error);
return 1;
}
+ */
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
--
2.13.2

View File

@ -0,0 +1,72 @@
From f5f27799e1b6875be7f34edac3a9f98a2b550b2c Mon Sep 17 00:00:00 2001
From: Fabian Vogt <fabian@ritter-vogt.de>
Date: Thu, 3 Aug 2017 09:50:30 +0200
Subject: [PATCH 3/3] Check for a graphical session
Avoid running if it detects a text session. This can be overridden by adding
"force_run" as argument.
---
pam_kwallet.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/pam_kwallet.c b/pam_kwallet.c
index dc61115..34bc045 100644
--- a/pam_kwallet.c
+++ b/pam_kwallet.c
@@ -72,6 +72,7 @@ const static char *kwalletd = NULL;
const static char *socketPath = NULL;
const static char *kwalletPamDataKey = NULL;
const static char *logPrefix = NULL;
+static int force_run = 0;
#ifdef KWALLET5
const static char *envVar = "PAM_KWALLET5_LOGIN";
@@ -98,6 +99,8 @@ static void parseArguments(int argc, const char **argv)
kwalletd = argv[x] + 9;
} else if (strstr(argv[x], "socketPath=") != NULL) {
socketPath= argv[x] + 11;
+ } else if (strcmp(argv[x], "force_run") == 0) {
+ force_run = 1;
}
}
#ifdef KWALLET5
@@ -241,6 +244,24 @@ cleanup:
return result;
}
+static int is_graphical_session(pam_handle_t *pamh)
+{
+ //Detect a graphical session
+ const char *pam_tty = NULL, *pam_xdisplay = NULL,
+ *xdg_session_type = NULL, *display = NULL;
+
+ pam_get_item(pamh, PAM_TTY, (const void**) &pam_tty);
+#ifdef PAM_XDISPLAY
+ pam_get_item(pamh, PAM_XDISPLAY, (const void**) &pam_xdisplay);
+#endif
+ xdg_session_type = get_env(pamh, "XDG_SESSION_TYPE");
+
+ return (pam_xdisplay && strlen(pam_xdisplay) != 0)
+ || (pam_tty && pam_tty[0] == ':')
+ || (xdg_session_type && strcmp(xdg_session_type, "x11") == 0)
+ || (xdg_session_type && strcmp(xdg_session_type, "wayland") == 0);
+}
+
static void cleanup_free(pam_handle_t *pamh, void *ptr, int error_status)
{
free(ptr);
@@ -537,6 +558,11 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, cons
parseArguments(argc, argv);
+ if (!force_run && !is_graphical_session(pamh)) {
+ pam_syslog(pamh, LOG_INFO, "%s: not a graphical session, skipping. Use force_run parameter to ignore this.", logPrefix);
+ return PAM_IGNORE;
+ }
+
int result;
result = pam_set_data(pamh, "sm_open_session", "1", NULL);
if (result != PAM_SUCCESS) {
--
2.13.2

7
baselibs.conf Normal file
View File

@ -0,0 +1,7 @@
pam_kwallet
requires "pam_kwallet = <version>"
supplements "packageand(pam_kwallet:pam-<targettype>)"
post "%if 0%{?suse_version} >= 1330"
post "%{_sbindir}/pam-config -a --kwallet5 || :"
post "%endif"
post ":"

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0227751c8f68970e184c2e723796bf11966ae045b904e7a6b07d1e4b9e7729ea
size 17912

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c42e444c9c85dc5bbc60bbd666d20ea72162ddd38dc18254c47c48a0ca404073
size 17908

View File

@ -1,3 +1,34 @@
-------------------------------------------------------------------
Tue Aug 22 19:11:31 CEST 2017 - fabian@ritter-vogt.de
- Update to 5.10.5
* New bugfix release
* For more details please see:
* https://www.kde.org/announcements/plasma-5.10.5.php
- Changes since 5.10.4:
* None
- Enable pam-config integration on TW
-------------------------------------------------------------------
Wed Aug 9 08:39:00 UTC 2017 - fabian@ritter-vogt.de
- Add various patches (pending upstream review) to fix several
issues:
* 0001-Several-cleanups.patch
* 0002-Avoid-dropping-privileges-by-initializing-gcrypt-sec.patch
* 0003-Check-for-a-graphical-session.patch
-------------------------------------------------------------------
Wed Aug 2 08:48:28 UTC 2017 - fabian@ritter-vogt.de
- Split into pam_kwallet and pam_kwallet common to allow -32bit pkg
necessary for pam-config integration
- Add baselibs.conf for -32bit pkg
- Register with pam-config automatically (boo#1029942)
- Only use pam-config on TW, where it will be available soon
- Disable pam-config for now, kwallet-pam needs some upstream
discussions first before it's viable to use...
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Jul 18 16:14:48 CEST 2017 - fabian@ritter-vogt.de Tue Jul 18 16:14:48 CEST 2017 - fabian@ritter-vogt.de

View File

@ -17,28 +17,50 @@
Name: pam_kwallet Name: pam_kwallet
Version: 5.10.4 Version: 5.10.5
Release: 0 Release: 0
Summary: A PAM Module for kwallet signing Summary: A PAM Module for KWallet signing
License: LGPL-2.1 and GPL-2.0+ and GPL-3.0 License: LGPL-2.1 and GPL-2.0+ and GPL-3.0
Group: System/GUI/KDE Group: System/GUI/KDE
Url: http://www.kde.org/ Url: http://www.kde.org/
Source: http://download.kde.org/stable/plasma/%{version}/kwallet-pam-%{version}.tar.xz Source0: http://download.kde.org/stable/plasma/%{version}/kwallet-pam-%{version}.tar.xz
Source1: baselibs.conf
# PATCH-FIX-UPSTREAM
Patch1: 0001-Several-cleanups.patch
# PATCH-FIX-UPSTREAM
Patch2: 0002-Avoid-dropping-privileges-by-initializing-gcrypt-sec.patch
# PATCH-FIX-UPSTREAM
Patch3: 0003-Check-for-a-graphical-session.patch
BuildRequires: extra-cmake-modules >= 1.2.0 BuildRequires: extra-cmake-modules >= 1.2.0
BuildRequires: kf5-filesystem BuildRequires: kf5-filesystem
BuildRequires: libgcrypt-devel >= 1.5.0 BuildRequires: libgcrypt-devel >= 1.5.0
BuildRequires: pam-devel BuildRequires: pam-devel
BuildRequires: socat BuildRequires: socat
BuildRequires: xz BuildRequires: xz
Requires: kwalletd5 Requires: %{name}-common = %{version}
Requires: socat %if 0%{?suse_version} >= 1330
Requires(postun): coreutils pam pam-config
%endif
%description %description
This PAM module allows you to automatically open your kwallet This PAM module allows you to automatically open your kwallet
when signing into your account. when signing into your account.
%package common
Summary: Support files for the KWallet PAM module
Group: System/GUI/KDE
Requires: kwalletd5
Requires: socat
%description common
This package contains support files used by the KWallet PAM
module.
%prep %prep
%setup -q -n kwallet-pam-%{version} %setup -q -n kwallet-pam-%{version}
%patch1 -p1
%patch2 -p1
%patch3 -p1
%build %build
%cmake_kf5 -d build -- -DLIBEXEC_INSTALL_DIR=%{_kf5_libexecdir} -DCMAKE_INSTALL_PREFIX=/ %cmake_kf5 -d build -- -DLIBEXEC_INSTALL_DIR=%{_kf5_libexecdir} -DCMAKE_INSTALL_PREFIX=/
@ -47,11 +69,27 @@ when signing into your account.
%install %install
%kf5_makeinstall -C build %kf5_makeinstall -C build
%if 0%{?suse_version} >= 1330
# Due to boo#728586 it is necessary to duplicate this in the 32bit variant.
# So you need to edit baselibs.conf if you change this.
%post
%{_sbindir}/pam-config -a --kwallet5 || :
%postun
if [ "$1" = "0" ]; then
%{_sbindir}/pam-config -d --kwallet5 || :
fi
%endif
%files %files
%defattr(-,root,root) %defattr(-,root,root)
%doc COPYING* %doc COPYING*
/%{_lib}/security/pam_kwallet5.so
%files common
%defattr(-,root,root)
%doc COPYING*
%config %{_kf5_configdir}/autostart/pam_kwallet_init.desktop %config %{_kf5_configdir}/autostart/pam_kwallet_init.desktop
%{_kf5_libexecdir}/pam_kwallet_init %{_kf5_libexecdir}/pam_kwallet_init
/%{_lib}/security/pam_kwallet5.so
%changelog %changelog