pax_global_header00006660000000000000000000000064124653024310014512gustar00rootroot0000000000000052 comment=a0f7323d223bb0835cfb139f05a272f8826ee954 pidgin-gnome-keyring-2.0/000077500000000000000000000000001246530243100153765ustar00rootroot00000000000000pidgin-gnome-keyring-2.0/.gitignore000066400000000000000000000000211246530243100173570ustar00rootroot00000000000000gnome-keyring.so pidgin-gnome-keyring-2.0/Makefile000066400000000000000000000013251246530243100170370ustar00rootroot00000000000000TARGET = gnome-keyring SECRETFLAGS = `pkg-config --libs --cflags libsecret-1` PURPLEFLAGS = `pkg-config --cflags purple` VERSION = $(shell cat VERSION) ifeq ($(strip $(VERSION)),) VERSION = `git describe --tags` endif all: ${TARGET}.so clean: rm -f ${TARGET}.so ${TARGET}_*.tar.gz pidgin-${TARGET}_*.* *.pyc rm -rf pidgin-${TARGET}-* ${TARGET}.so: ${TARGET}.c ${CC} ${CFLAGS} ${LDFLAGS} -Wall -I. -g -O2 ${TARGET}.c -o ${TARGET}.so -shared -fPIC -DPIC -ggdb ${PURPLEFLAGS} ${SECRETFLAGS} -DVERSION=\"${VERSION}\" install: ${TARGET}.so mkdir -p ${DESTDIR}/usr/lib/purple-2/ cp ${TARGET}.so ${DESTDIR}/usr/lib/purple-2/ install_local: ${TARGET}.so mkdir -p ~/.purple/plugins cp ${TARGET}.so ~/.purple/plugins/ pidgin-gnome-keyring-2.0/README.md000066400000000000000000000007341246530243100166610ustar00rootroot00000000000000# pidgin-gnome-keyring Pidgin usually stores passwords as plaintext. This plugin instead saves all passwords to the system keyring, which some would argue is a more secure form of password storage. After the plugin is enabled, whenever an account with a pidgin-stored password signs on, its password will automatically be saved to the keyring and removed from the plaintext accounts.xml file. The plugin is available as a ppa for Ubuntu: ```ppa:pidgin-gnome-keyring/ppa``` pidgin-gnome-keyring-2.0/deb_control000066400000000000000000000014261246530243100176160ustar00rootroot00000000000000Source: pidgin-gnome-keyring Section: universe/net Priority: optional Maintainer: Ali Ebrahim Build-Depends: debhelper (>= 9), pkg-config, libsecret-1-dev, libpurple-dev Standards-Version: 3.9.5 Homepage: https://github.com/aebrahim/pidgin-gnome-keyring/ Vcs-git: https://github.com/aebrahim/pidgin-gnome-keyring.git Vcs-Browser: https://github.com/aebrahim/pidgin-gnome-keyring/ Package: pidgin-gnome-keyring Architecture: any Depends: ${misc:Depends}, libsecret-1-0, libpurple0 Description: integrates pidgin (and libpurple) with the system keyring Pidgin usually stores passwords as plaintext with the "save password" function. This plugin instead saves all passwords to the system keyring, which some would argue is a more secure form of password storage. pidgin-gnome-keyring-2.0/deb_copyright000066400000000000000000000022321246530243100201420ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: pidgin-gnome-keyring Upstream-Contact: Ali Ebrahim Source: https://github.com/aebrahim/pidgin-gnome-keyring Files: * Copyright: 2015 Ali Ebrahim License: GPL-2.0+ Files: debian/* Copyright: 2015 Ali Ebrahim License: GPL-2.0+ License: GPL-2.0+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". pidgin-gnome-keyring-2.0/gnome-keyring.c000066400000000000000000000253311246530243100203210ustar00rootroot00000000000000#define PURPLE_PLUGINS #ifndef VERSION #define VERSION "experimental" #endif #include #include #include #include #include #include #include #include /* function prototypes */ static void keyring_password_store(PurpleAccount *account, gchar *password); static void sign_in_cb(PurpleAccount *account, gpointer data); static void keyring_password_find_cb(GObject *source, GAsyncResult *res, gpointer data); static void keyring_password_store_cb(GObject *source, GAsyncResult *res, gpointer data); static void connecting_cb(PurpleAccount *account, gpointer data); static void memory_clearing_function(PurpleAccount *account); static PurplePluginPrefFrame * get_pref_frame(PurplePlugin *plugin); /* function definitions */ /* function called when the plugin starts */ static gboolean plugin_load(PurplePlugin *plugin) { GList *accountsList; void *accountshandle = purple_accounts_get_handle(); /* notFound will be a list of accounts not found * in the keyring */ GList *notFound = NULL; GList *notFound_iter; /* The first thing to do is set all the passwords. * This part is purposely written to be locking. If pidgin * tries to connect without a password it will result in annoying * prompts */ for (accountsList = purple_accounts_get_all(); accountsList != NULL; accountsList = accountsList->next) { PurpleAccount *account = (PurpleAccount *)accountsList->data; gchar *password; GError *error = NULL; /* if the password exists in the keyring, set it in pidgin */ password = secret_password_lookup_sync(SECRET_SCHEMA_COMPAT_NETWORK, NULL, &error, "user", account->username, "protocol", account->protocol_id, NULL); if (error != NULL) { fprintf(stderr, "lookup_sync error in plugin_load: %s\n", error->message); g_error_free(error); } else if (password != NULL) { /* set the account to not remember passwords */ purple_account_set_remember_password(account, FALSE); /* temporarily set a fake password, then the real one */ purple_account_set_password(account, "fakedoopdeedoop"); purple_account_set_password(account, password); secret_password_free(password); } else { /* add to the list of accounts not found in the keyring */ notFound = g_list_append(notFound, account); } } /* for the acccounts which were not found in the keyring */ for (notFound_iter = g_list_first(notFound); notFound_iter != NULL; notFound_iter = notFound_iter->next) { PurpleAccount *account = (PurpleAccount *)notFound_iter->data; /* if the password was saved by libpurple before then * save it in the keyring, and tell libpurple to forget it */ if (purple_account_get_remember_password(account)) { gchar *password = g_strdup(account->password); keyring_password_store(account, password); purple_account_set_remember_password(account, FALSE); /* temporarily set a fake password, then the real one again */ purple_account_set_password(account, "fakedoopdeedoop"); purple_account_set_password(account, password); g_free(password); } } /* done with the notFound, so free it */ g_list_free(notFound); /* create a signal which monitors whenever an account signs in, * so that the callback function can store/update the password */ purple_signal_connect(accountshandle, "account-signed-on", plugin, PURPLE_CALLBACK(sign_in_cb), NULL); /* create a signal which monitors whenever an account tries to connect * so that the callback can make sure the password is set in pidgin */ purple_signal_connect(accountshandle, "account-connecting", plugin, PURPLE_CALLBACK(connecting_cb), NULL); /* at this point, the plugin is set up */ return TRUE; } /* callback to whenever an account is signed in */ static void sign_in_cb(PurpleAccount *account, gpointer data) { /* Get the password. * The callback will check to see if it is already * saved in the keyring. * This will be run every time an account signs in. */ secret_password_lookup(SECRET_SCHEMA_COMPAT_NETWORK, NULL, keyring_password_find_cb, account, "user", account->username, "protocol", account->protocol_id, NULL); } /* callback to gnome keyring password finder * Will sync the password between the keyring and pidgin */ static void keyring_password_find_cb(GObject *source, GAsyncResult *res, gpointer data) { GError *error = NULL; gchar *password = secret_password_lookup_finish(res, &error); PurpleAccount *account = (PurpleAccount *)data; gboolean remember = purple_account_get_remember_password(account); /* set the purple account to not remember passwords */ purple_account_set_remember_password(account, FALSE); /* if the password was not found in the keyring * and the password exists in pidgin * and the password was set to be remembered */ if (error != NULL) { fprintf(stderr, "lookup_finish error in find_cb: %s\n", error->message); g_error_free(error); return; } if (password == NULL && account->password != NULL && remember) { /* copy it from pidgin to the keyring */ keyring_password_store(account, account->password); return; } /* if the stored passwords do not match */ if (password != NULL) { if (account->password != NULL && strcmp(password, account->password) != 0) { /* update the keyring with the pidgin password */ keyring_password_store(account, account->password); secret_password_free(password); return; } secret_password_free(password); } /* if this code is excecuted, it means that keyring_password_store was * not called, so the memory_clearing_function needs to be called now */ memory_clearing_function(account); } /* store a password in the keyring */ static void keyring_password_store(PurpleAccount *account, gchar *password) { secret_password_store( SECRET_SCHEMA_COMPAT_NETWORK, purple_prefs_get_string("/plugins/core/gnome-keyring/keyring_name"), "pidgin account password", password, NULL, keyring_password_store_cb, account, "user", account->username, "protocol", account->protocol_id, NULL); } /* this is mainly here for stability issues because the program may * crash if there is no callback function. * It does not actually do anything */ static void keyring_password_store_cb(GObject *source, GAsyncResult *res, gpointer data) { GError *error = NULL; secret_password_store_finish(res, &error); if (error != NULL) { fprintf(stderr, "store_finish error in store_cb: %s\n", error->message); g_error_free(error); } else { PurpleAccount *account = (PurpleAccount *)data; memory_clearing_function(account); } return; } static void memory_clearing_function(PurpleAccount *account) { gboolean clear_memory = purple_prefs_get_bool( "/plugins/core/gnome-keyring/clear_memory"); if (clear_memory) { if (account->password != NULL) { g_free(account->password); account->password = NULL; } } } /* callback to whenever a function tries to connect * this needs to ensure that there is a password * this may happen if the password was disabled, then later re-enabled */ static void connecting_cb(PurpleAccount *account, gpointer data) { if (account->password == NULL) { gchar *password; GError *error = NULL; password = secret_password_lookup_sync(SECRET_SCHEMA_COMPAT_NETWORK, NULL, &error, "user", account->username, "protocol", account->protocol_id, NULL); if (error != NULL) { fprintf(stderr, "lookup_sync error in connectinb_cb: %s\n", error->message); g_error_free(error); } else if (password != NULL) { purple_account_set_password(account, password); secret_password_free(password); } } } static gboolean plugin_unload(PurplePlugin *plugin) { /* disconnect from signals */ void *accounts_handle = purple_accounts_get_handle(); purple_signal_disconnect(accounts_handle, "account-signed-on", plugin, NULL); purple_signal_disconnect(accounts_handle, "account-connecting", plugin, NULL); return TRUE; } static PurplePluginUiInfo prefs_info = { get_pref_frame, 0, NULL, NULL, NULL, NULL, NULL }; static PurplePluginPrefFrame * get_pref_frame(PurplePlugin *plugin) { PurplePluginPrefFrame *frame = purple_plugin_pref_frame_new(); gchar *label = g_strdup_printf("Clear plaintext passwords from memory"); PurplePluginPref *pref = purple_plugin_pref_new_with_name_and_label( "/plugins/core/gnome-keyring/clear_memory", label); purple_plugin_pref_frame_add(frame, pref); purple_plugin_pref_frame_add(frame, purple_plugin_pref_new_with_name_and_label( "/plugins/core/gnome-keyring/keyring_name", "Keyring name" ) ); return frame; } static PurplePluginInfo info = { PURPLE_PLUGIN_MAGIC, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_PLUGIN_STANDARD, NULL, 0, NULL, PURPLE_PRIORITY_HIGHEST, "core-gnome-keyring", "Password Keyring", VERSION, "Save pidgin passwords to the system keyring instead of as plaintext", "Save pidgin passwords to the system keyring instead of as plaintext", "Ali Ebrahim", "https://github.com/aebrahim/pidgin-gnome-keyring/", plugin_load, plugin_unload, NULL, NULL, NULL, &prefs_info, NULL, NULL, NULL, NULL, NULL }; static void init_plugin(PurplePlugin *plugin) { purple_prefs_add_none("/plugins/core/gnome-keyring"); purple_prefs_add_bool("/plugins/core/gnome-keyring/clear_memory", FALSE); purple_prefs_add_string("/plugins/core/gnome-keyring/keyring_name", SECRET_COLLECTION_DEFAULT); } PURPLE_INIT_PLUGIN(gnome-keyring, init_plugin, info) pidgin-gnome-keyring-2.0/make_package.py000077500000000000000000000047601246530243100203520ustar00rootroot00000000000000#!/usr/bin/env python """helps automate building the package""" import shutil import os from subprocess import check_output from pygit2 import Repository, GIT_SORT_TIME import xml.dom.minidom import re import time # declare strings up here ubuntunames = ["trusty", "utopic", "vivid"] author_name = "Ali Ebrahim" email = "ali.ebrahim314@gmail.com" basename = "pidgin-gnome-keyring" installdir = "/usr/lib/purple-2/" version = check_output(["git", "describe"]).strip() for ubuntuname in ubuntunames: version_str = version + "~" + ubuntuname package_version_str = version_str + "-1" dirname = basename + "-" + version_str tarname = basename + "_" + version_str + ".orig" debname = dirname + "/debian/" print debname if os.path.isdir(dirname): os.system("rm -rf " + dirname) os.mkdir(dirname) os.mkdir(debname) shutil.copy2("gnome-keyring.c", dirname) # copy everything in Makefile except for the install part at the end shutil.copy2("Makefile", dirname + "/Makefile") with open(dirname + "/VERSION", "w") as outfile: outfile.write(version) shutil.make_archive(tarname, "gztar", root_dir=dirname) # run dh_make os.system("cd %s; dh_make -s -c gpl2 --createorig -y -a -e %s" % (dirname, email)) # remove extra files and copy source files os.system("cd %s; rm -rf *.ex *.EX README*" % debname) shutil.copy2("deb_control", debname+"control") shutil.copy2("deb_copyright", debname+"copyright") # make the dirs and install files os.system("echo '%s' > %sdirs" % (installdir, debname)) os.system("echo 'gnome-keyring.so %s' > %sinstall" % (installdir, debname)) # write the changelog changelog = open(debname + "changelog", "w") repo = Repository(".") for commit in repo.walk(repo.head.target, GIT_SORT_TIME): changelog.write("%s (%s) %s; urgency=low\n\n" % (basename, package_version_str, ubuntuname)) for commit_line in commit.message.split("\n"): if len(commit_line) > 0: changelog.write(" " + commit_line + "\n") changelog.write("\n") date = time.strftime("%a, %d %b %Y %X", time.gmtime(commit.commit_time)) offset = "%+0.04d" % (commit.commit_time_offset / 60 * 1000) changelog.write(" -- %s <%s> %s %s\n" % (author_name, email, date, offset)) changelog.close() # call debuild os.system("cd %s; debuild -S -sa" % dirname) pidgin-gnome-keyring-2.0/pidgin-gnome-keyring.svg000066400000000000000000001022631246530243100221460ustar00rootroot00000000000000 image/svg+xml