<commit_before>package org.lantern.privacy;

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.codec.binary.Base64;
import org.freedesktop.Secret.Collection;
import org.freedesktop.Secret.Item;
import org.freedesktop.Secret.Pair;
import org.freedesktop.Secret.Prompt;
import org.freedesktop.Secret.Secret;
import org.freedesktop.Secret.Service;
import org.freedesktop.Secret.Session;
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.DBusSigHandler;
import org.freedesktop.dbus.DBusSignal;
import org.freedesktop.dbus.Path;
import org.freedesktop.dbus.Variant;
import org.freedesktop.dbus.exceptions.DBusException;
import org.lantern.LanternUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * SecretServiceLocalCipherProvider
 *
 * This is a LocalCipherProvider that uses
 * the DBUS "Secret Service" API to store a local key
 * used to encrypt/decrypt local data.
 *
 */
public class SecretServiceLocalCipherProvider extends AbstractAESLocalCipherProvider {

    private static final String BUS_NAME = "org.freedesktop.secrets";
    private static final String SERVICE_PATH = "/org/freedesktop/secrets";
    private static final String ALGORITHM_PLAIN = "plain";
    private static final String COLLECTION_PATH = "/org/freedesktop/secrets/aliases/default";
    private static final String NO_OBJECT = "/";
    private static final String SECRET_LABEL_PROPERTY = "org.freedesktop.Secret.Item.Label";
    private static final String SECRET_ATTRIBUTES_PROPERTY = "org.freedesktop.Secret.Item.Attributes";
    private static final String SECRET_ATTR_NAME = "lanternId";
    private static final String SECRET_ATTR_VALUE = "org.lantern.SecretServiceLocalCipherProvider";
    private static final String LANTERN_KEY_LABEL = "Lantern Local Privacy";
    private static final String SECRET_CONTENT_TYPE = "text/plain; charset=utf8";

    private static final Logger LOG = LoggerFactory.getLogger(SecretServiceLocalCipherProvider.class);

    public SecretServiceLocalCipherProvider() {
        super();
    }

    public SecretServiceLocalCipherProvider(final File validatorFile, final File cipherParamsFile) {
        super(validatorFile, cipherParamsFile);
    }

    public static boolean secretServiceAvailable() {
        DBusConnection conn = null;
        try {
            LOG.debug("Checking for Secret Service API availability...");
            conn = DBusConnection.getConnection(DBusConnection.SESSION);
            final Service secretService = conn.getRemoteObject(
                BUS_NAME, SERVICE_PATH, Service.class);
            final Pair<Variant, Path> result = 
                secretService.OpenSession(ALGORITHM_PLAIN, new Variant(""));
            if (NO_OBJECT.equals(result.b.getPath())) {
                LOG.info("Failed to negotiate plain session with Secret Service API.");
                return false;
            }
            else {
                final Session session = conn.getRemoteObject(
                    BUS_NAME, result.b.getPath(), Session.class);
                session.Close();
            }
            
            LOG.debug("Found Secret Service API.");
            return true;
        } catch (final Exception e) {
            LOG.debug("Could not connect to Secret Service API at:"+SERVICE_PATH, e);
            return false;
        } catch (final UnsatisfiedLinkError error) {
            if (LanternUtils.isDevMode()) {
                LOG.error("Could not load so file? Testing");
                return false;
            } else {
                LOG.error("CAN'T HAVE UNENCRYPTED FILES IN PRODUCTION!!");
                System.exit(1);
                return false;
            }
        } finally {
            closeConnection(conn);
        }
    }

    private static void closeConnection(final DBusConnection conn) {
        if (conn != null) {
            try {
                conn.disconnect();
            } catch (Exception e) {
                LOG.error("Error closing DBus connection {}", e);
            }
        }
    }

    @Override
    byte[] loadKeyData() throws IOException, GeneralSecurityException {
        DBusConnection conn = null;
        byte [] encodedKey = null;<commit_msg>Added stack trace<commit_after>package org.lantern.privacy;

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.codec.binary.Base64;
import org.freedesktop.Secret.Collection;
import org.freedesktop.Secret.Item;
import org.freedesktop.Secret.Pair;
import org.freedesktop.Secret.Prompt;
import org.freedesktop.Secret.Secret;
import org.freedesktop.Secret.Service;
import org.freedesktop.Secret.Session;
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.DBusSigHandler;
import org.freedesktop.dbus.DBusSignal;
import org.freedesktop.dbus.Path;
import org.freedesktop.dbus.Variant;
import org.freedesktop.dbus.exceptions.DBusException;
import org.lantern.LanternUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * SecretServiceLocalCipherProvider
 *
 * This is a LocalCipherProvider that uses
 * the DBUS "Secret Service" API to store a local key
 * used to encrypt/decrypt local data.
 *
 */
public class SecretServiceLocalCipherProvider extends AbstractAESLocalCipherProvider {

    private static final String BUS_NAME = "org.freedesktop.secrets";
    private static final String SERVICE_PATH = "/org/freedesktop/secrets";
    private static final String ALGORITHM_PLAIN = "plain";
    private static final String COLLECTION_PATH = "/org/freedesktop/secrets/aliases/default";
    private static final String NO_OBJECT = "/";
    private static final String SECRET_LABEL_PROPERTY = "org.freedesktop.Secret.Item.Label";
    private static final String SECRET_ATTRIBUTES_PROPERTY = "org.freedesktop.Secret.Item.Attributes";
    private static final String SECRET_ATTR_NAME = "lanternId";
    private static final String SECRET_ATTR_VALUE = "org.lantern.SecretServiceLocalCipherProvider";
    private static final String LANTERN_KEY_LABEL = "Lantern Local Privacy";
    private static final String SECRET_CONTENT_TYPE = "text/plain; charset=utf8";

    private static final Logger LOG = LoggerFactory.getLogger(SecretServiceLocalCipherProvider.class);

    public SecretServiceLocalCipherProvider() {
        super();
    }

    public SecretServiceLocalCipherProvider(final File validatorFile, final File cipherParamsFile) {
        super(validatorFile, cipherParamsFile);
    }

    public static boolean secretServiceAvailable() {
        DBusConnection conn = null;
        try {
            LOG.debug("Checking for Secret Service API availability...");
            conn = DBusConnection.getConnection(DBusConnection.SESSION);
            final Service secretService = conn.getRemoteObject(
                BUS_NAME, SERVICE_PATH, Service.class);
            final Pair<Variant, Path> result = 
                secretService.OpenSession(ALGORITHM_PLAIN, new Variant(""));
            if (NO_OBJECT.equals(result.b.getPath())) {
                LOG.info("Failed to negotiate plain session with Secret Service API.");
                return false;
            }
            else {
                final Session session = conn.getRemoteObject(
                    BUS_NAME, result.b.getPath(), Session.class);
                session.Close();
            }
            
            LOG.debug("Found Secret Service API.");
            return true;
        } catch (final Exception e) {
            LOG.debug("Could not connect to Secret Service API at:"+SERVICE_PATH, e);
            return false;
        } catch (final UnsatisfiedLinkError error) {
            if (LanternUtils.isDevMode()) {
                LOG.error("Could not load so file? Testing?", error);
                return false;
            } else {
                LOG.error("CAN'T HAVE UNENCRYPTED FILES IN PRODUCTION!!");
                System.exit(1);
                return false;
            }
        } finally {
            closeConnection(conn);
        }
    }

    private static void closeConnection(final DBusConnection conn) {
        if (conn != null) {
            try {
                conn.disconnect();
            } catch (Exception e) {
                LOG.error("Error closing DBus connection {}", e);
            }
        }
    }

    @Override
    byte[] loadKeyData() throws IOException, GeneralSecurityException {
        DBusConnection conn = null;
        byte [] encodedKey = null;
{'fraction_non_alphanumeric': 0.08922670191672175, 'fraction_numerical': 0.0013218770654329147, 'mean_word_length': 2.86999147485081, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4741991', 'n_tokens_mistral': 2550, 'n_tokens_neox': 2439, 'n_words': 604}