commit 6881b3d99d95e9549575491d0d6d3dcd1711b289
parent 7b066ed12bd1d2a02cb0054e1387cb41217b01af
Author: Jaromil <jaromil@dyne.org>
Date: Wed, 10 Apr 2013 12:55:32 +0200
new local keyring to save passwords
Diffstat:
2 files changed, 83 insertions(+), 33 deletions(-)
diff --git a/src/zlibs/accounts b/src/zlibs/accounts
@@ -51,6 +51,8 @@ list_accounts() {
# arg 1 : account type, es: imap or smtp
# -a defines which account name other than 'default'
+# results in the definition of global account variables:
+# name login host protocol port auth folders accountopt
read_account() {
typeset -al all
unset name email host login transport \
@@ -190,7 +192,7 @@ ask_password() {
func "Looking for password in keyring: $name"
###################
# USE GNOME KEYRING
- { test $GNOMEKEY = 1 } && {
+ if [ "$GNOMEKEY" = "1" ]; then
print "protocol=${type}\npath=jaromail/${email}\nusername=${login}\nhost=${host}\n\n" \
| $WORKDIR/bin/jaro-gnome-keyring check
if [ $? != 0 ]; then # its a new password
@@ -203,7 +205,15 @@ ask_password() {
password=`print "protocol=${type}\npath=jaromail/${email}\nusername=${login}\nhost=${host}\n\n" | $WORKDIR/bin/jaro-gnome-keyring get`
fi
return 0
- }
+ elif [ -r $WORKDIR/keyring ]; then
+ _hash=`print "$transport:$email:$host" | shasum`
+ lookup="`lookup_secret ${_hash}`"
+ { test "$lookup" = "" } || {
+ act "Using saved password for $email ($transport on $host)"
+ password="$lookup"
+ return 0
+ }
+ fi
####################
# USE PINENTRY ALONE
new_password
@@ -218,6 +228,16 @@ ask_password() {
esac
}
+lookup_secret() {
+ hash=$1
+ if [ "$2" = "" ]; then key=password
+ else key="$2"; fi
+ cat <<EOF | ${SQL} -column -batch $WORKDIR/keyring
+SELECT ${key} FROM secrets
+WHERE hash IS "${hash}";
+EOF
+}
+
new_password() {
notice "Setting a new password for $name"
password=`pin_entry $login $host`
@@ -277,8 +297,8 @@ EOF
else # password is blank or aborted
- # USE GNOME KEYRING
- { test $GNOMEKEY = 1 } && {
+ # save it into gnome keyring
+ if [ $GNOMEKEY = 1 ]; then
cat <<EOF | $WORKDIR/bin/jaro-gnome-keyring erase
protocol=${type}
@@ -291,8 +311,40 @@ EOF
return 1 }
act "No new password given, old password erased."
return 0
- }
+
+ else # save it into local keyring
+ { test -r $WORKDIR/keyring } || {
+ # make sure the local keyring exists
+ touch $WORKDIR/keyring
+ chmod 600 $WORKDIR/keyring
+ chown $_uid:$_gid $WORKDIR/keyring
+ cat <<EOF | ${SQL} -batch $WORKDIR/keyring
+CREATE TABLE secrets
+(
+ hash text collate unique,
+ password text collate
+);
+EOF
+ }
+ # calculate the hash for this entry
+ hash=`print "$transport:$email:$host" | shasum`
+ # check if the entry is already present
+ lookup="`lookup_secret ${hash} rowid`"
+ if [ "$lookup" = "" ]; then # new entry
+ cat <<EOF | ${SQL} -batch $WORKDIR/keyring
+INSERT INTO secrets (hash, password)
+VALUES ("${hash}", "${password}");
+EOF
+ act "saved new password in local keyring"
+ else # update entry
+ cat <<EOF | ${SQL} -batch $WORKDIR/keyring
+UPDATE secrets SET password="${password}" WHERE hash LIKE "${hash}";
+EOF
+ act "updated local keyring with new password"
+ fi
+ return 0
+ fi
return 1
fi
@@ -310,4 +362,4 @@ change_password() {
{ test $? = 0 } && { test $DRYRUN != 1 } && {
new_password }
-}-
\ No newline at end of file
+}
diff --git a/src/zlibs/email b/src/zlibs/email
@@ -89,7 +89,10 @@ fetch() {
{ test "$account" = "" } && {
fetchall; return $? }
+# setup global account variables
read_account ${account_type} ${account}
+# name login host protocol port auth folders accountopt
+
{ test $? != 0 } && {
error "Error on account entry: $account_type $account"
return 1
@@ -123,51 +126,48 @@ fetch() {
{ test $DRYRUN != 1 } && {
- tmp=$TMPDIR/$host.fetch.$RANDOM
- newlock $tmp
- cat <<EOF > $tmp
-poll $host with proto IMAP user "$login" there with password "$password"
-EOF
+ fmconf=("poll $host with proto IMAP user \"$login\" there with password \"$password\"")
+
unset password
if ! [ -z $accountopt ]; then # add option configuration
- print "${accountopt}" >> $tmp; fi
+ fmconf+=(" ${accountopt} "); fi
if ! [ -z $folders ]; then # add folder configuration
- print "folder ${folders}" >> $tmp; fi
+ fmconf+=(" folder ${folders} "); fi
+
+ fmconf+=(" ssl warnings 3600 and wants mda \"procmail -m $PROCMAILDIR/rc\" ")
- cat <<EOF >> $tmp
-ssl warnings 3600 and wants mda "procmail -m $PROCMAILDIR/rc"
-EOF
if [ "$cert" = "check" ]; then
- cat <<EOF >> $tmp
-sslcertck sslcertpath '$WORKDIR/certs'
-EOF
+ fmconf+=(" sslcertck sslcertpath '$WORKDIR/certs' ")
fi
- cat <<EOF >> $tmp
-antispam 571 550 501 554
-EOF
+
+
+ fmconf+=(" antispam 571 550 501 554 ")
+
# try login without doing anything
- fetchmail -c -f $tmp
+ print "$fmconf" | fetchmail -c -f -
+ res=$?
# examine result
- case $? in
+ case $ret in
1)
notice "No mails for $name"
- unlink $tmp
+ unset $fmconf
return 1
;;
2)
error "Invalid or unknown certificate for $host"
- unlink $tmp
+ unset $fmconf
return 1
;;
3)
error "Invalid password for user $login at $host"
- unlink $tmp
+ unset $fmconf
return 1
;;
- *) ;;
+ *)
+ func "fetchmail returns $ret" ;;
esac
# archive old procmail log
@@ -185,11 +185,10 @@ EOF
act "please wait while downloading mails..."
- cat $tmp | fetchmail -f $tmp
- # TODO: substitute this with cat conf | fetchmail -f -
- # to avoid writing the password in clear on filesystem
+ print " $fmconf " | fetchmail -f -
+
+ unset $fmconf
- unlink $tmp
unlink $addressbook_tmp
total=`mailstat -k $WORKDIR/log/procmail.log | tail -n1 | awk '{print $2}'`