[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [ksecrets] /: Working on api tests
From: Valentin Rusu <kde () rusu ! info>
Date: 2015-08-12 15:30:42
Message-ID: E1ZPXzG-0007WM-BC () scm ! kde ! org
[Download RAW message or body]
Git commit 19576a02138dd21beaf943b4d4a400b188ebc9c4 by Valentin Rusu.
Committed on 12/08/2015 at 15:29.
Pushed by vrusu into branch 'master'.
Working on api tests
M +7 -1 autotests/api/ksecretsservice-test.cpp
M +1 -1 src/runtime/ksecrets_store/CMakeLists.txt
R +43 -30 src/runtime/ksecrets_store/ksecrets_credentials.cpp [from: \
src/runtime/ksecrets_store/ksecrets_credentials.c - 078% similarity] M +1 -1 \
src/runtime/ksecrets_store/ksecrets_credentials.h M +136 -95 \
src/runtime/pam-ksecrets/pam_ksecrets.c
http://commits.kde.org/ksecrets/19576a02138dd21beaf943b4d4a400b188ebc9c4
diff --git a/autotests/api/ksecretsservice-test.cpp b/autotests/api/ksecretsservice-test.cpp
index c16c424..27d967f 100644
--- a/autotests/api/ksecretsservice-test.cpp
+++ b/autotests/api/ksecretsservice-test.cpp
@@ -48,6 +48,7 @@ KSecretServiceTest::KSecretServiceTest(QObject* parent)
KSecrets::CollectionPtr collection;
KSharedConfig::Ptr sharedConfig;
+QString secretsFilePath;
void KSecretServiceTest::initTestCase()
{
@@ -58,6 +59,11 @@ void KSecretServiceTest::initTestCase()
QStandardPaths::setTestModeEnabled(true);
sharedConfig = KSharedConfig::openConfig(QLatin1String("ksecretsrc"));
+ secretsFilePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
+ QVERIFY(QDir::home().mkpath(secretsFilePath));
+ secretsFilePath += QLatin1Literal("/ksecrets-test.data");
+ qDebug() << "secrets store path: " << secretsFilePath;
+
setupKeyring();
collection = KSecrets::Service::findCollection(
@@ -170,7 +176,7 @@ void KSecretServiceTest::setupKeyring()
QVERIFY(-1 == key);
/* now go setup user's keyring */
- QVERIFY(kss_set_credentials(testUser.constData(), testPass.constData()));
+ QVERIFY(kss_set_credentials(testUser.constData(), testPass.constData(), \
secretsFilePath.toLocal8Bit().constData()));
// the right keys should be present into the kernel keyring
key = request_key("user", KEYNAME_ENCRYPTING, 0, KEY_SPEC_SESSION_KEYRING);
diff --git a/src/runtime/ksecrets_store/CMakeLists.txt \
b/src/runtime/ksecrets_store/CMakeLists.txt index 82b5ad1..36fd30d 100644
--- a/src/runtime/ksecrets_store/CMakeLists.txt
+++ b/src/runtime/ksecrets_store/CMakeLists.txt
@@ -9,7 +9,7 @@ ecm_setup_version(${KF5_VERSION} VARIABLE_PREFIX KSECRETS_BACKEND
PACKAGE_VERSION_FILE \
"${CMAKE_CURRENT_BINARY_DIR}/KF5SecretsStoreConfigVersion.cmake")
set(ksecrets_store_SRC
- ksecrets_credentials.c
+ ksecrets_credentials.cpp
ksecrets_store.cpp)
add_library(ksecrets_store SHARED ${ksecrets_store_SRC})
diff --git a/src/runtime/ksecrets_store/ksecrets_credentials.c \
b/src/runtime/ksecrets_store/ksecrets_credentials.cpp similarity index 78%
rename from src/runtime/ksecrets_store/ksecrets_credentials.c
rename to src/runtime/ksecrets_store/ksecrets_credentials.cpp
index 155796a..96e4107 100644
--- a/src/runtime/ksecrets_store/ksecrets_credentials.c
+++ b/src/runtime/ksecrets_store/ksecrets_credentials.cpp
@@ -18,6 +18,7 @@
* Boston, MA 02110-1301, USA.
*/
#include "ksecrets_credentials.h"
+#include "ksecrets_store.h"
#include <unistd.h>
#include <errno.h>
@@ -28,7 +29,9 @@
#include <linux/limits.h>
#include <pwd.h>
#include <string.h>
+extern "C" {
#include <keyutils.h>
+}
#define GCRPYT_NO_DEPRECATED
#include <gcrypt.h>
@@ -42,14 +45,16 @@
#define KSECRETS_ITERATIONS 50000
/* these functions are implemented in config.cpp next to this file */
-extern const char* prepare_secret_file_location(const char*);
-extern const char* get_keyname_encrypting();
-extern const char* get_keyname_mac();
+extern "C" const char* prepare_secret_file_location(const char*);
+extern "C" const char* get_keyname_encrypting();
+extern "C" const char* get_keyname_mac();
-#define false 0
-#define true 1
+#define FALSE 0
+#define TRUE 1
+#define UNUSED(x) (void)(x)
-int kss_init_gcry()
+extern "C"
+int KSECRETS_STORE_EXPORT kss_init_gcry()
{
syslog(KSS_LOG_DEBUG, "ksecrets: setting-up grypt library");
if (!gcry_check_version(GCRYPT_REQUIRED_VERSION)) {
@@ -69,14 +74,15 @@ int kss_init_gcry()
return 1;
}
-int kss_derive_keys(const char* salt, const char* password, char* encryption_key, char* \
mac_key, size_t keySize) +extern "C"
+int KSECRETS_STORE_EXPORT kss_derive_keys(const char* salt, const char* password, char* \
encryption_key, char* mac_key, size_t keySize) {
gpg_error_t gcryerr;
syslog(KSS_LOG_INFO, "kss_set_credentials: attempting keys generation");
if (0 == password) {
syslog(KSS_LOG_INFO, "NULL password given. ksecrets will not be available.");
- return false;
+ return FALSE;
}
/* generate both encryption and MAC key in one go */
@@ -84,24 +90,25 @@ int kss_derive_keys(const char* salt, const char* password, char* \
encryption_key
gcryerr = gcry_kdf_derive(password, strlen(password), GCRY_KDF_ITERSALTED_S2K, \
GCRY_MD_SHA512, salt, 8, KSECRETS_ITERATIONS, 2 * keySize, keys); if (gcryerr) {
syslog(KSS_LOG_ERR, "key derivation failed: code 0x%0x: %s/%s", gcryerr, \
gcry_strsource(gcryerr), gcry_strerror(gcryerr));
- return false;
+ return FALSE;
}
memcpy(encryption_key, keys, keySize);
memcpy(mac_key, keys + keySize, keySize);
syslog(KSS_LOG_INFO, "successuflly generated ksecrets keys from user password.");
- return true;
+ return TRUE;
}
-int kss_store_keys(const char* encryption_key, const char* mac_key, size_t keySize)
+extern "C"
+int KSECRETS_STORE_EXPORT kss_store_keys(const char* encryption_key, const char* mac_key, \
size_t keySize) {
key_serial_t ks;
const char* key_name = get_keyname_encrypting();
ks = add_key("user", key_name, encryption_key, keySize, KEY_SPEC_SESSION_KEYRING);
if (-1 == ks) {
syslog(KSS_LOG_ERR, "ksecrets: cannot store encryption key in kernel keyring: errno=%d \
(%m)", errno);
- return false;
+ return FALSE;
}
syslog(KSS_LOG_DEBUG, "ksecrets: encrpyting key now in kernel keyring with id %d and desc \
%s", ks, key_name);
@@ -109,10 +116,10 @@ int kss_store_keys(const char* encryption_key, const char* mac_key, \
size_t keySi
ks = add_key("user", key_name, mac_key, keySize, KEY_SPEC_SESSION_KEYRING);
if (-1 == ks) {
syslog(KSS_LOG_ERR, "ksecrets: cannot store mac key in kernel keyring: errno=%d (%m)", \
errno);
- return false;
+ return FALSE;
}
syslog(KSS_LOG_DEBUG, "ksecrets: mac key now in kernel keyring with id %d and desc %s", \
ks, key_name);
- return true;
+ return TRUE;
}
int kss_keys_already_there()
@@ -121,61 +128,67 @@ int kss_keys_already_there()
key = request_key("user", get_keyname_encrypting(), 0, KEY_SPEC_SESSION_KEYRING);
if (-1 == key) {
syslog(KSS_LOG_DEBUG, "request_key failed with errno %d (%m), so assuming ksecrets not \
yet loaded", errno);
- return false;
+ return FALSE;
}
syslog(KSS_LOG_DEBUG, "ksecrets: keys already in keyring");
- return true;
+ return TRUE;
}
-int kss_set_credentials(const char* user_name, const char* password)
+extern "C"
+int KSECRETS_STORE_EXPORT kss_set_credentials(const char* user_name, const char* password, \
const char* path) {
- syslog(KSS_LOG_DEBUG, "kss_set_credentials for %s", user_name);
+ UNUSED(user_name);
if (kss_keys_already_there())
- return true;
+ return TRUE;
+ KSecretsStore secretsStore;
+ auto setupres = secretsStore.setup(path, password);
- return true;
+ return setupres.get() ? 1 : 0;
}
-int kss_delete_credentials()
+extern "C"
+int KSECRETS_STORE_EXPORT kss_delete_credentials()
{
syslog(KSS_LOG_INFO, "kss_delete_credentials");
key_serial_t key;
key = request_key("user", get_keyname_encrypting(), 0, KEY_SPEC_SESSION_KEYRING);
if (-1 == key) {
syslog(KSS_LOG_DEBUG, "request_key failed with errno %d (%m), cannot purge encrypting \
key", errno);
- return false;
+ return FALSE;
}
long res = keyctl(KEYCTL_REVOKE, key);
if (-1 == res) {
syslog(KSS_LOG_DEBUG, "removing key failed with errno %d (%m), cannot purge encrypting \
key", errno);
- return false;
+ return FALSE;
}
key = request_key("user", get_keyname_mac(), 0, KEY_SPEC_SESSION_KEYRING);
if (-1 == key) {
syslog(KSS_LOG_DEBUG, "request_key failed with errno %d (%m), cannot purge mac key", \
errno);
- return false;
+ return FALSE;
}
res = keyctl(KEYCTL_REVOKE, key);
if (-1 == res) {
syslog(KSS_LOG_DEBUG, "removing key failed with errno %d (%m), cannot purge mac key", \
errno);
- return false;
+ return FALSE;
}
- return true;
+ return TRUE;
}
-int kss_can_change_password()
+extern "C"
+int KSECRETS_STORE_EXPORT kss_can_change_password()
{
/* nothing to do for the moment */
syslog(KSS_LOG_INFO, "kss_can_change_password");
- return true;
+ return TRUE;
}
-int kss_change_password(const char* new_password)
+extern "C"
+int KSECRETS_STORE_EXPORT kss_change_password(const char* new_password)
{
syslog(LOG_INFO, "kss_change_password");
- return true;
+ return TRUE;
}
/* vim: tw=220 ts=4
*/
diff --git a/src/runtime/ksecrets_store/ksecrets_credentials.h \
b/src/runtime/ksecrets_store/ksecrets_credentials.h index 0242a24..2b979b5 100644
--- a/src/runtime/ksecrets_store/ksecrets_credentials.h
+++ b/src/runtime/ksecrets_store/ksecrets_credentials.h
@@ -27,7 +27,7 @@
extern "C" {
#endif
-int kss_set_credentials(const char* user_name, const char* password);
+int kss_set_credentials(const char* user_name, const char* password, const char* path);
int kss_delete_credentials();
diff --git a/src/runtime/pam-ksecrets/pam_ksecrets.c b/src/runtime/pam-ksecrets/pam_ksecrets.c
index eaf8f21..bb97632 100644
--- a/src/runtime/pam-ksecrets/pam_ksecrets.c
+++ b/src/runtime/pam-ksecrets/pam_ksecrets.c
@@ -9,133 +9,174 @@
#include <security/pam_ext.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+#include <linux/limits.h>
+#include <string.h>
#define UNUSED(x) (void)(x)
const char* password;
-/* these extern functions are implemented in ksecrets_store_bridge.cpp */
-extern int kss_set_credentials(const char*, const char*);
-extern int kss_delete_credentials();
-extern int kss_can_change_password();
-extern int kss_change_password(const char*);
-
PAM_EXTERN int pam_sm_authenticate(
pam_handle_t* pamh, int flags, int argc, const char** argv)
{
- pam_syslog(pamh, LOG_INFO, "pam_sm_authenticate flags=%X", flags);
- UNUSED(flags);
- UNUSED(argc);
- UNUSED(argv);
-
- password = 0;
- int result = pam_get_item(pamh, PAM_AUTHTOK, (const void**)&password);
- if (result != PAM_SUCCESS) {
- pam_syslog(pamh, LOG_ERR, "Couldn't get password %s",
- pam_strerror(pamh, result));
- }
-
- /* this module does not participate to the user authentication process */
- return PAM_IGNORE;
+ pam_syslog(pamh, LOG_INFO, "pam_sm_authenticate flags=%X", flags);
+ UNUSED(flags);
+ UNUSED(argc);
+ UNUSED(argv);
+
+ password = 0;
+ int result = pam_get_item(pamh, PAM_AUTHTOK, (const void**)&password);
+ if (result != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "Couldn't get password %s",
+ pam_strerror(pamh, result));
+ }
+
+ /* this module does not participate to the user authentication process */
+ return PAM_IGNORE;
}
+/**
+ * The module PAM module configuration should specify the location of the
+ * secrets file. The location should contain only the part of the path
+ * relative to the user's $HOME directory. So, if you'd like to have secrets
+ * managed in, say, $HOME/owncloud/ksecrets.data then the pam configuration
+ * file should contain something like this:
+ *
+ * auth required pam_ksecrets.so owncloud/ksecrets.data
+ *
+ * As you may have guessed, the configuration will be the same for all the
+ * users, and that cannot be changed from one user to another, at least not in
+ * this version of pam_ksecrets.
+ *
+ * If nothing is specified, then the default path will be
+ * $HOME/.local/share/ksecrets/ksecrets.data
+ *
+ * The location should point to an actual file. If it's a symlink, then the
+ * store handling routine will fail.
+ */
PAM_EXTERN int pam_sm_setcred(
pam_handle_t* pamh, int flags, int argc, const char** argv)
{
- UNUSED(argc);
- UNUSED(argv);
- pam_syslog(pamh, LOG_INFO, "pam_sm_setcred flags=%X", flags);
- if (flags & PAM_ESTABLISH_CRED) {
- if (0 == password)
- return PAM_CRED_UNAVAIL;
-
- const char* user_name;
- user_name = 0;
- int result = pam_get_item(pamh, PAM_USER, (const void**)&user_name);
- if (result != PAM_SUCCESS) {
- pam_syslog(pamh, LOG_ERR, "Couldn't get password %s",
- pam_strerror(pamh, result));
+ UNUSED(argc);
+ UNUSED(argv);
+ pam_syslog(pamh, LOG_INFO, "pam_sm_setcred flags=%X", flags);
+ if (flags & PAM_ESTABLISH_CRED) {
+ if (0 == password)
+ return PAM_CRED_UNAVAIL;
+
+ const char* user_name;
+ user_name = 0;
+ int result = pam_get_item(pamh, PAM_USER, (const void**)&user_name);
+ if (result != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "Couldn't get password %s",
+ pam_strerror(pamh, result));
+ return PAM_CRED_UNAVAIL;
+ }
+
+ struct passwd *pwd;
+ pwd = getpwnam(user_name);
+ if (pwd == 0) {
+ pam_syslog(pamh, LOG_ERR, "Couldn't get user passwd info %d (%m)", errno);
+ return PAM_CRED_ERR;
+ }
+
+ char secrets_path[PATH_MAX];
+ memset(secrets_path, 0, sizeof(secrets_path)/sizeof(secrets_path[0]));
+ strncpy(secrets_path, pwd->pw_dir, PATH_MAX);
+ static const char *defaultPath = ".local/share/ksecrets/ksecrets.data";
+ if (argc == 1 && argv[0] != 0) {
+ strncat(secrets_path, argv[0], PATH_MAX - strlen(secrets_path) -1);
+ } else {
+ strncat(secrets_path, defaultPath, PATH_MAX - strlen(secrets_path) -1);
+ }
+ pam_syslog(pamh, LOG_INFO, "ksecrets: setting secrets path to %s", secrets_path);
+
+ if (!kss_set_credentials(user_name, password, secrets_path)) {
+ pam_syslog(
+ pamh, LOG_ERR, "ksecrets credentials could not be set.");
+ return PAM_CRED_ERR;
+ }
+ return PAM_SUCCESS;
}
- if (!kss_set_credentials(user_name, password)) {
- pam_syslog(pamh, LOG_ERR, "ksecrets credentials could not be set.");
- return PAM_CRED_ERR;
+ if (flags & PAM_DELETE_CRED) {
+ kss_delete_credentials();
}
- return PAM_SUCCESS;
- }
- if (flags & PAM_DELETE_CRED) {
- kss_delete_credentials();
- }
- return PAM_IGNORE;
+ return PAM_IGNORE;
}
PAM_EXTERN int pam_sm_open_session(
pam_handle_t* pamh, int flags, int argc, const char** argv)
{
- UNUSED(pamh);
- UNUSED(flags);
- UNUSED(argc);
- UNUSED(argv);
- /* not used */
- return PAM_IGNORE;
+ UNUSED(pamh);
+ UNUSED(flags);
+ UNUSED(argc);
+ UNUSED(argv);
+ /* not used */
+ return PAM_IGNORE;
}
PAM_EXTERN int pam_sm_close_session(
pam_handle_t* pamh, int flags, int argc, const char** argv)
{
- UNUSED(pamh);
- UNUSED(flags);
- UNUSED(argc);
- UNUSED(argv);
- /* not used */
- return PAM_SUCCESS;
+ UNUSED(pamh);
+ UNUSED(flags);
+ UNUSED(argc);
+ UNUSED(argv);
+ /* not used */
+ return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_chauthtok(
pam_handle_t* pamh, int flags, int argc, const char** argv)
{
- UNUSED(argc);
- UNUSED(argv);
- pam_syslog(pamh, LOG_INFO, "pam_sm_chauthtok flags=%X", flags);
-
- if (flags & PAM_PRELIM_CHECK) {
- pam_syslog(pamh, LOG_INFO, "pam_sm_chauthtok preliminary check");
- if (kss_can_change_password()) {
- return PAM_SUCCESS;
- }
- else {
- pam_syslog(pamh, LOG_ERR, "pam_sm_chauthtok prelimnary check failed "
- "because ksecrets cannot be locked");
- return PAM_AUTHTOK_LOCK_BUSY;
- }
- }
-
- if (flags & PAM_UPDATE_AUTHTOK) {
- pam_syslog(pamh, LOG_INFO,
- "pam_sm_chauthtok attempt updating ksecret service key");
-
- const char* password;
- password = 0;
- int result = pam_get_item(pamh, PAM_AUTHTOK, (const void**)&password);
- if (result != PAM_SUCCESS) {
- pam_syslog(pamh, LOG_ERR, "Couldn't get password %s",
- pam_strerror(pamh, result));
- return PAM_IGNORE;
- }
-
- if (0 == password) {
- pam_syslog(
- pamh, LOG_WARNING, "pam_sm_authenticate got NULL password! ");
- return PAM_AUTHTOK_ERR;
+ UNUSED(argc);
+ UNUSED(argv);
+ pam_syslog(pamh, LOG_INFO, "pam_sm_chauthtok flags=%X", flags);
+
+ if (flags & PAM_PRELIM_CHECK) {
+ pam_syslog(pamh, LOG_INFO, "pam_sm_chauthtok preliminary check");
+ if (kss_can_change_password()) {
+ return PAM_SUCCESS;
+ }
+ else {
+ pam_syslog(pamh, LOG_ERR,
+ "pam_sm_chauthtok prelimnary check failed "
+ "because ksecrets cannot be locked");
+ return PAM_AUTHTOK_LOCK_BUSY;
+ }
}
- if (kss_change_password(password))
- return PAM_SUCCESS;
- else {
- pam_syslog(pamh, LOG_ERR, "ksecrets service failed to update the keys. "
- "Aborting password change.");
- return PAM_AUTHTOK_ERR;
+ if (flags & PAM_UPDATE_AUTHTOK) {
+ pam_syslog(pamh, LOG_INFO,
+ "pam_sm_chauthtok attempt updating ksecret service key");
+
+ const char* password;
+ password = 0;
+ int result = pam_get_item(pamh, PAM_AUTHTOK, (const void**)&password);
+ if (result != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "Couldn't get password %s",
+ pam_strerror(pamh, result));
+ return PAM_IGNORE;
+ }
+
+ if (0 == password) {
+ pam_syslog(
+ pamh, LOG_WARNING, "pam_sm_authenticate got NULL password! ");
+ return PAM_AUTHTOK_ERR;
+ }
+
+ if (kss_change_password(password))
+ return PAM_SUCCESS;
+ else {
+ pam_syslog(pamh, LOG_ERR,
+ "ksecrets service failed to update the keys. "
+ "Aborting password change.");
+ return PAM_AUTHTOK_ERR;
+ }
}
- }
- return PAM_IGNORE;
+ return PAM_IGNORE;
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic