| /******************************************************************************* |
| * Copyright (c) 2017 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * LinuxPasswordProviderMessages.java |
| *******************************************************************************/ |
| #include <jni.h> |
| #include "keystoreLinuxNative.h" |
| #include <libsecret/secret.h> |
| #include <sys/types.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| const SecretSchema * |
| equinox_get_schema (void) |
| { |
| static const SecretSchema the_schema = { |
| "org.eclipse.equinox", SECRET_SCHEMA_NONE, |
| { |
| { NULL, 0 }, |
| } |
| }; |
| return &the_schema; |
| } |
| |
| #define EQUINOX_SCHEMA equinox_get_schema () |
| |
| static void unlock_secret_service(JNIEnv *env) |
| { |
| GError *error = NULL; |
| GList *l, *ul; |
| gchar* lbl; |
| gint nu; |
| //check that there is session dbus bus |
| GDBusConnection* dbusconnection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); |
| if (error != NULL) { |
| (*env)->ExceptionClear(env); |
| g_prefix_error(&error, "Unable to get DBus session bus: "); |
| (*env)->ThrowNew(env, (* env)->FindClass(env, "java/lang/SecurityException"), error->message); |
| g_error_free (error); |
| return; |
| } |
| SecretService* secretservice = secret_service_get_sync(SECRET_SERVICE_LOAD_COLLECTIONS, NULL, &error); |
| if (error != NULL) { |
| (*env)->ExceptionClear(env); |
| g_prefix_error(&error, "Unable to get secret service: "); |
| (*env)->ThrowNew(env, (* env)->FindClass(env, "java/lang/SecurityException"), error->message); |
| g_error_free (error); |
| return; |
| } |
| |
| SecretCollection* defaultcollection = secret_collection_for_alias_sync(secretservice, SECRET_COLLECTION_DEFAULT, SECRET_COLLECTION_NONE, NULL, &error); |
| if (error != NULL) { |
| (*env)->ExceptionClear(env); |
| g_prefix_error(&error, "Unable to get secret collection: "); |
| (*env)->ThrowNew(env, (* env)->FindClass(env, "java/lang/SecurityException"), error->message); |
| g_error_free (error); |
| return; |
| } |
| if (defaultcollection == NULL) { |
| (*env)->ExceptionClear(env); |
| (*env)->ThrowNew(env, (* env)->FindClass(env, "java/lang/SecurityException"), "Unable to find default secret collection"); |
| return; |
| } |
| |
| if (secret_collection_get_locked(defaultcollection)) |
| { |
| lbl = secret_collection_get_label(defaultcollection); |
| l = NULL; |
| l = g_list_append(l, defaultcollection); |
| nu = secret_service_unlock_sync(secretservice, l, NULL, &ul, &error); |
| g_list_free(l); |
| g_list_free(ul); |
| if (error != NULL) { |
| (*env)->ExceptionClear(env); |
| g_prefix_error(&error, "Unable to unlock: "); |
| (*env)->ThrowNew(env, (* env)->FindClass(env, "java/lang/SecurityException"), error->message); |
| g_error_free (error); |
| return; |
| } |
| |
| } |
| return; |
| } |
| |
| JNIEXPORT jboolean JNICALL Java_org_eclipse_equinox_internal_security_linux_LinuxPasswordProvider_canUnlock(JNIEnv *env, jobject this) { |
| |
| unlock_secret_service(env); |
| if ((*env)->ExceptionOccurred(env)) { |
| return JNI_FALSE; |
| } |
| return JNI_TRUE; |
| } |
| |
| JNIEXPORT jstring JNICALL Java_org_eclipse_equinox_internal_security_linux_LinuxPasswordProvider_getMasterPassword(JNIEnv *env, jobject this) { |
| GError *error = NULL; |
| jstring result; |
| |
| unlock_secret_service(env); |
| if ((*env)->ExceptionOccurred(env)) { |
| return NULL; |
| } |
| |
| gchar *password = secret_password_lookup_sync(EQUINOX_SCHEMA, NULL, &error, NULL); |
| |
| if (error != NULL) { |
| (*env)->ExceptionClear(env); |
| (*env)->ThrowNew(env, (* env)->FindClass(env, "java/lang/SecurityException"), error->message); |
| g_error_free (error); |
| return NULL; |
| } else if (password == NULL) { |
| (*env)->ExceptionClear(env); |
| (*env)->ThrowNew(env, (* env)->FindClass(env, "java/lang/SecurityException"), "Unable to find password"); |
| return NULL; |
| } else { |
| result = (*env)->NewStringUTF(env, password); |
| free(password); |
| return result; |
| } |
| } |
| |
| JNIEXPORT void JNICALL Java_org_eclipse_equinox_internal_security_linux_LinuxPasswordProvider_saveMasterPassword(JNIEnv *env, jobject this, jstring password) { |
| GError *error = NULL; |
| |
| unlock_secret_service(env); |
| if ((*env)->ExceptionOccurred(env)) { |
| return; |
| } |
| |
| const char *passwordUTF = (*env)->GetStringUTFChars(env, password, NULL); |
| secret_password_store_sync (EQUINOX_SCHEMA, SECRET_COLLECTION_DEFAULT, |
| "Equinox master password", passwordUTF, NULL, &error, |
| NULL); |
| |
| // free the UTF strings |
| (*env)->ReleaseStringUTFChars( env, password, passwordUTF ); |
| |
| if (error != NULL) { |
| (*env)->ExceptionClear(env); |
| (*env)->ThrowNew(env, (* env)->FindClass(env, "java/lang/SecurityException"), error->message); |
| g_error_free (error); |
| } |
| } |
| |