jaromail

a commandline tool to easily and privately handle your e-mail
git clone git://parazyd.org/jaromail.git
Log | Files | Refs | Submodules | README

commit 07089619b2d0e2a6a86df600c88e71a38a4e9fdd
parent 3acb6ce9fbc3d99d1bd14e8d6a9da44cc1bb6cd2
Author: Jaromil <jaromil@dyne.org>
Date:   Sun,  3 Jun 2012 18:06:32 +0200

password handling using gnome-keyring on GNU systems

Diffstat:
Mbuild-gnu.sh | 12++++++------
Minstall.sh | 1+
Msrc/gnome-keyring/jaro-gnome-keyring.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/jaro | 95++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
4 files changed, 151 insertions(+), 31 deletions(-)

diff --git a/build-gnu.sh b/build-gnu.sh @@ -27,12 +27,12 @@ case $distro in gcc -Os -static -o fetchaddr fetchaddr.o helpers.o rfc2047.o rfc822.o; cd - > /dev/null echo - # echo "gnome-keyring" - # cd src/gnome-keyring - # [ -x jaro-gnome-keyring ] || \ - # gcc `pkg-config --cflags --libs glib-2.0 gnome-keyring-1` \ - # -O2 -o jaro-gnome-keyring jaro-gnome-keyring.c - # cd - > /dev/null + echo "gnome-keyring" + cd src/gnome-keyring +# [ -x jaro-gnome-keyring ] || \ + gcc `pkg-config --cflags --libs glib-2.0 gnome-keyring-1` \ + -O2 -o jaro-gnome-keyring jaro-gnome-keyring.c + cd - > /dev/null echo "Done compiling." echo "Now run ./install.sh and Jaro Mail will be ready in ~/Mail" echo "or \"./install.sh path\" to install it somewhere else." diff --git a/install.sh b/install.sh @@ -244,6 +244,7 @@ for mod in ${lbdb_modules}; do done cp src/lbdb/dotlock $WORKDIR/.lbdb/ cp src/lbdb/fetchaddr $WORKDIR/.lbdb/ +cp src/gnome-keyring/jaro-gnome-keyring $WORKDIR/bin/ chmod +x $WORKDIR/.lbdb/* ln -sf $WORKDIR/.lbdb/lbdb-fetchaddr $WORKDIR/bin/ ln -sf $WORKDIR/.lbdb/lbdbq $WORKDIR/bin/ diff --git a/src/gnome-keyring/jaro-gnome-keyring.c b/src/gnome-keyring/jaro-gnome-keyring.c @@ -1,3 +1,26 @@ +/* Jaro Mail gnome keyring handler + + Originally from some Gnome example code, slightly modified + + Copyright (C) 2012 Denis Roio <jaromil@dyne.org> + + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Public License as published + * by the Free Software Foundation; either version 3 of the License, + * or (at your option) any later version. + * + * This source code 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. + * Please refer to the GNU Public License for more details. + * + * You should have received a copy of the GNU Public License along with + * this source code; if not, write to: + * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -36,7 +59,7 @@ error(const char *err, ...) va_end(params); } -static void +static int get_password(git_credential_t *cred) { GnomeKeyringResult keyres; @@ -50,13 +73,34 @@ get_password(git_credential_t *cred) "username", cred->username, NULL); if (keyres != GNOME_KEYRING_RESULT_OK) { - return; + return 1; } - g_printf("password=%s\n", pass); + g_printf("%s\n", pass); gnome_keyring_free_password(pass); + return 0; } -static void +static int +check_password(git_credential_t *cred) +{ + GnomeKeyringResult keyres; + gchar *pass = NULL; + + keyres = gnome_keyring_find_password_sync(&git_schema, + &pass, + "protocol", cred->protocol, + "host", cred->host, + "path", cred->path, + "username", cred->username, + NULL); + if (keyres != GNOME_KEYRING_RESULT_OK) { + return 1; + } + gnome_keyring_free_password(pass); + return 0; +} + +static int store_password(git_credential_t *cred) { gchar desc[1024]; @@ -65,7 +109,7 @@ store_password(git_credential_t *cred) /* Only store complete credentials */ if (!cred->protocol || !cred->host || !cred->username || !cred->password) - return; + return 1; g_snprintf(desc, sizeof(desc), "Git %s", cred->host); keyres = gnome_keyring_store_password_sync(&git_schema, @@ -79,11 +123,12 @@ store_password(git_credential_t *cred) NULL); if (keyres != GNOME_KEYRING_RESULT_OK) { error("failed to store password"); - return; + return 1; } + return 0; } -static void +static int erase_password(git_credential_t *cred) { GnomeKeyringResult keyres; @@ -96,8 +141,9 @@ erase_password(git_credential_t *cred) NULL); if (keyres != GNOME_KEYRING_RESULT_OK) { error("failed to delete password"); - return; + return 1; } + return 0; } static int @@ -147,6 +193,7 @@ int main(int argc, const char **argv) { git_credential_t cred = {0}; + int res = 0; if (argc < 2) { error("Usage: git credential-gnomekeyring <get|store|erase>"); @@ -159,15 +206,18 @@ main(int argc, const char **argv) } if (strcmp(argv[1], "get") == 0) { - get_password(&cred); + res = get_password(&cred); + } + if (strcmp(argv[1], "check") == 0) { + res = check_password(&cred); } else if (strcmp(argv[1], "store") == 0) { - store_password(&cred); + res = store_password(&cred); } else if (strcmp(argv[1], "erase") == 0) { - erase_password(&cred); + res = erase_password(&cred); } clear_credential(&cred); - return 0; + return res; } diff --git a/src/jaro b/src/jaro @@ -222,9 +222,10 @@ ask_password() { func "Looking for password in keyring: $1 @ $2" security find-internet-password -a $1 -s $2 > /dev/null if [ $? != 0 ]; then # its a new password - password=`pin_entry $1 @ $2` - act "New password set for $1 @ $2" - security add-internet-password -a $1 -s $2 -w "${password}" + new_password + { test $? = 0 } && { + error "Password input aborted." + return 1 } else act "Using saved password for $1 @ $2" password=`security find-internet-password -a $1 -s $2 -g \ @@ -232,20 +233,70 @@ ask_password() { fi return 0 ;; + ##################################### GNU) + func "Looking for password in keyring: $1 @ $2" + echo "protocol=${type}\npath=jaromail/${email}\nusername=${login}\nhost=${host}\n\n" | $WORKDIR/bin/jaro-gnome-keyring check + if [ $? != 0 ]; then # its a new password + new_password + { test $? = 0 } && { + error "Password input aborted." + return 1 } + else # password found into gnome keyring + act "Using saved password for $1 @ $2" + password=`echo "protocol=${type}\npath=jaromail/${email}\nusername=${login}\nhost=${host}\n\n" | $WORKDIR/bin/jaro-gnome-keyring get` + fi + return 0 + ;; + *) + error "Unknown system, can't figure out how to handle passwords" + return 1 + esac +} + +new_password() { + case $OS in + MAC) + password=`pin_entry $1 $2` + act "New password set for $1 @ $2" + security add-internet-password -a $1 -s $2 -w "${password}" + # TODO: erase and error codes + ;; + GNU) + notice "Setting a new password for $login @ $host" password=`pin_entry $login $host` if [ "$password" != "" ]; then + cat <<EOF | $WORKDIR/bin/jaro-gnome-keyring store +protocol=${type} +path=jaromail/${email} +username=${login} +host=${host} +password=${password} +EOF + { test $? != 0 } && { + unset password + error "Error saving password in Gnome keyring" + return 1 } return 0 else - return 1 - fi + cat <<EOF | $WORKDIR/bin/jaro-gnome-keyring erase +protocol=${type} +path=jaromail/${email} +username=${login} +host=${host} +EOF + { test $? != 0 } && { + error "Error accessing password in Gnome keyring" + return 1 } + act "No new password given, old password erased." + return 0 + fi ;; *) error "Unknown system, can't figure out how to handle passwords" return 1 esac } - switch_identity() { if [ "$name" != "" ]; then act "switch to identity: $name <$login>" @@ -304,8 +355,9 @@ maildirmake() { read_account() { typeset -al all - if [ -z $1 ]; then type="*" - + if [ -z $1 ]; then + type=`echo $account | cut -d. -f1` + account=`echo $account | cut -d. -f2` else type=$1 # smtp, imap, pop ... file prefixes" fi @@ -313,12 +365,14 @@ read_account() { for a in `find $WORKDIR/Accounts -name "$type.$account*"`; do all+=($a); done if [ ${#all} = 0 ]; then error "No $type account found: $account" + error "Refine your argument using 'type.account'" + error "For instance: imap.default or smtp.default" return 1 elif [ ${#all} != 1 ]; then error "Too many $type accounts named $account" act -n "" for i in ${=all}; do echo -n "`basename ${i}` "; done - echo; error "Refine your account keyword" + echo; error "Refine your account keyword using -a option" return 1 fi @@ -557,11 +611,10 @@ fetch() { notice "Fetching mails for $name" ask_password $login $host - if [ $? != 0 ]; then + { test $? != 0 } && { error "Error retrieving password for $login on $host" - unset password all - return 1 - fi + unset password all; return 1 + } newlock $WORKDIR/tmp/$host.fetch cat <<EOF > $WORKDIR/tmp/$host.fetch @@ -663,6 +716,10 @@ send() { ask_password $login $host + { test $? != 0 } && { + error "Error retrieving password for $login on $host" + unset password all; return 1 + } newlock $WORKDIR/tmp/$host.send cat <<EOF > $WORKDIR/tmp/$host.send @@ -733,6 +790,12 @@ peek() { sleep 2 # escape at sign in login ilogin=`echo $login | sed 's/@/\\@/'` + ask_password $login $host + { test $? != 0 } && { + error "Error retrieving password for $login on $host" + unset password all; return 1 + } + mutt -F $MUTTDIR/rc -f ${iproto}://${ilogin}@${host}${folder} # TODO automatic input of password in mutt return $? @@ -1142,6 +1205,8 @@ Options: Maintenance commands: + passwd reset password for the account in use + update refresh configurations queue add a mail into outbox @@ -1190,6 +1255,7 @@ main() subcommands_opts[merge]="" subcommands_opts[filter]="" + subcommands_opts[passwd]="" subcommands_opts[cert]="" subcommands_opts[source]="" @@ -1290,6 +1356,9 @@ main() merge) merge ${PARAM} ;; filter) filter ${PARAM} ;; + passwd) read_account; + { test $? = 0 } && { new_password ${PARAM} } + ;; cert) cert ${PARAM} ;; 'source') CLEANEXIT=0; return 0 ;;