commit 22cb9f38bbd02be39310c63ec847b5a1ece9da7e
parent 82ede1c06ce4d3c0666832de2b1f48cab58fbc90
Author: Jaromil <jaromil@dyne.org>
Date:   Fri,  2 May 2014 14:39:30 +0200
fixes to keyring handling and configuration checks for gnu systems
Diffstat:
5 files changed, 319 insertions(+), 261 deletions(-)
diff --git a/src/jaro b/src/jaro
@@ -180,6 +180,10 @@ else
     exit 1
 fi
 
+ACCOUNTS="$MAILDIRS/Accounts"
+KEYRING="$MAILDIRS/Keyring"
+addressbook="$MAILDIRS/Addressbook"
+
 # temporary directory
 TMPDIR="$MAILDIRS/tmp/jaromil.$USER"
 case $OS in
@@ -190,6 +194,20 @@ case $OS in
 	    TMPDIR=/dev/shm/tmp.jaromail.$USER
 	    TMPRAM=1
 	}
+
+	# backward compatibility tests for old paths in JaroMail <1.3
+	{ test -d $WORKDIR/Accounts } && { test ! -d $ACCOUNTS } && {
+	    act "Updating accounts location: $ACCOUNTS"
+	    cp -ra $WORKDIR/Accounts $ACCOUNTS }
+
+	{ test -r "$WORKDIR/keyring" } && { test ! -r "$KEYRING" } && {
+	    act "Updating keyring location: $KEYRING"
+	    cp $WORKDIR/keyring "$KEYRING" }
+
+	{ test -r $WORKDIR/addressbook } && { test ! -r $addressbook } && {
+	    act "Updating addressbook location: $addressbook"
+	    cp $WORKDIR/addressbook $addressbook }
+
 	;;
     MAC)
 	mount | grep 'JaroTmp' > /dev/null
@@ -201,38 +219,25 @@ case $OS in
 	;;
 esac
 
+# use the TMP in RAM if possible, for acceleration
 { test $TMPRAM = 1 } && {
     act "Using temporary directory in volatile RAM" }
 
-
 # make sure we have a temp dir
 ${=mkdir} "$TMPDIR"
 { test $? != 0 } && {
     error "Cannot create temporary directory: $TMPDIR"
     return 1 }
 
-# make sure we have an addressbook
-# use the one in RAM if present, for acceleration
 hostname=$(hostname) # gather the current hostname
 
+# make sure we have a directory for account configurations
+{ test -d $ACCOUNTS } || { mkdir -p $ACCOUNTS }
 
-ACCOUNTS="$MAILDIRS/Accounts"
-KEYRING="$MAILDIRS/Keyring"
-addressbook="$MAILDIRS/Addressbook"
-
-# backward compatibility tests for old paths in JaroMail <1.3
-{ test -r $WORKDIR/Accounts } && { test ! -r $ACCOUNTS } && {
-    act "Updating accounts location: $ACCOUNTS"
-    cp -r $WORKDIR/Accounts $ACCOUNTS }
-
-{ test -r $WORKDIR/keyring } && { test ! -r $KEYRING } && {
-    act "Updating keyring location: $KEYRING"
-    cp $WORKDIR/keyring $KEYRING }
-
-{ test -r $WORKDIR/addressbook } && { test ! -r $addressbook } && {
-    act "Updating addressbook location: $addressbook"
-    cp $WORKDIR/addressbook $addressbook }
+# make sure we have a local keyring in case system-wide not found
+{ test -r "$KEYRING" } || { create_keyring "$KEYRING" }
 
+# make sure we have an addressbook
 addressbook_tmp=$TMPDIR/${USER}.${hostname}.addressbook
 { test -r "$addressbook" } || { create_addressbook }
 { test -r "$addressbook_tmp" } && { addressbook="$addressbook_tmp" }
@@ -244,6 +249,30 @@ PROCMAILDIR=$MAILDIRS/.procmail
 MUTTDIR=$MAILDIRS/.mutt
 
 
+# make sure we have Filters.txt Applications.txt Mutt.txt
+if ! [ -r $MAILDIRS/Filters.txt ]; then
+    cp -v doc/Filters.txt $MAILDIRS/Filters.txt
+    act "Default filters created"
+else
+    error "Existing configuration $MAILDIRS/Filters.txt skipped"
+fi
+
+if ! [ -r $MAILDIRS/Applications.txt ]; then
+    cp -v doc/Applications.txt $MAILDIRS/Applications.txt
+    act "Default helper applications settings created"
+else
+    error "Existing configuration $MAILDIRS/Applications.txt skipped"
+fi
+
+
+if ! [ -r $MAILDIRS/Mutt.txt ]; then
+    cp -v doc/Mutt.txt $MAILDIRS/Mutt.txt
+    act "Default Mutt configuration template created"
+else
+    error "Existing configuration $MAILDIRS/Mutt.txt skipped"
+fi
+
+
 # use gnome-keyring for passwords on GNU systems
 GNOMEKEY=0
 { test $GNOME_KEYRING_CONTROL } && {
@@ -326,10 +355,10 @@ check_bin() {
     done
 
     # make sure a gnupg dir exists
-    { test -r $HOME/.gnupg/pubring.gpg } || {                                               
-        mkdir -p $HOME/.gnupg                                                           
-        touch $HOME/.gnupg/pubring.gpg
-        touch $HOME/.gnupg/secring.gpg
+    { test -r $HOME/.gnupg/pubring.gpg } || {
+	mkdir -p $HOME/.gnupg
+	touch $HOME/.gnupg/pubring.gpg
+	touch $HOME/.gnupg/secring.gpg
     }
 
     # which find command to use
@@ -338,7 +367,7 @@ check_bin() {
 	MAC) find="gfind -O3" ;;
 	*) find="find"
     esac
-    
+
     # which wipe command to use
     if command -v wipe > /dev/null; then
 	rm="wipe -f -s -q -R /dev/urandom"
@@ -442,15 +471,15 @@ a pipe | in front indicate they take an email body from stdin
 account names correspond to the filenames, i.e. imap.default
 
  fetch    downloads emails locally from an $account on-line
-          option "keep" (default) to avoid deleting from servers
+	  option "keep" (default) to avoid deleting from servers
 
  send     send all emails queued in outbox/ to an smtp.$account
 
  peek     connect to an imap.$account with ncurses terminal mutt
-          remote folders supported. use to delete without download
+	  remote folders supported. use to delete without download
 
  passwd   set account passwords in the OS native keyring
-          or into a simple, file based, gpg encrypted database.
+	  or into a simple, file based, gpg encrypted database.
 
 |queue    queue a mail in outbox/ for send
 
@@ -462,7 +491,7 @@ maildirs are directories of mails downloaded in Mail/
  open     open a maildir folder (can use -R for read-only)
 
  backup  (mairix)  move mails from a maildir to another one
-          match mails to move based on date ranges or strings
+	  match mails to move based on date ranges or strings
 
  rmdupes  remove all duplicated e-mails into a maildir
 
@@ -572,7 +601,7 @@ main()
 		act "try -h for help"
 		CLEANEXIT=0
 	}
-    	return $exitcode
+	return $exitcode
     fi
 
     argv=(${oldstar})
diff --git a/src/zlibs/accounts b/src/zlibs/accounts
@@ -4,7 +4,7 @@
 #
 # a tool to easily and privately handle your e-mail communication
 #
-# Copyleft (C) 2010-2012 Denis Roio <jaromil@dyne.org>
+# Copyleft (C) 2010-2014 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
@@ -156,228 +156,3 @@ read_account() {
     return 0
 }
 
-
-# we use pinentry
-# comes from gpg project and is secure
-# it also conveniently uses the right toolkit
-pin_entry() {
-    	cat <<EOF | pinentry 2>/dev/null | awk '/^D / { sub(/^D /, ""); print }'
-OPTION ttyname=$TTY
-OPTION lc-ctype=$LANG
-SETTITLE Type your password
-SETDESC Type the password for $1 @ $2
-SETPROMPT Password:
-GETPIN
-EOF
-}
-
-
-# retrieve a password for user @ domain
-# put it in variable password
-# up to the caller to unset it after use
-ask_password() {
-    case $OS in
-	MAC)
-            func "Looking for password in Mac/OSX keyring for $email on $host over $type"
-	    security find-internet-password \
-		-c JARO -a $email -s $host \
-		-p $transport -P $port > /dev/null
-	    if [ $? != 0 ]; then # its a new password
-		new_password
-		{ test $? != 0 } && {
-		    error "Password input aborted."
-		    return 1 }
-	    else
-		password=`security find-internet-password -c JARO -a $email -s $host -p $transport -P $port -g 2>&1| awk '/^password:/ { print $2 }' | sed -e 's/"//g'`
-	    fi
-	    return 0
-	    ;;
-	#####################################
-	GNU)
-	    ###################
-	    # USE GNOME KEYRING
-	    if [ "$GNOMEKEY" = "1" ]; then
-                func "Looking for password in Gnome keyring for $email on $host over $type"
-		func "path: jaromail/${type}/${email}"
-
-		print "protocol=${type}\npath=jaromail/${type}/${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=`print "protocol=${type}\npath=jaromail/${type}/${email}\nusername=${login}\nhost=${host}\n\n" | $WORKDIR/bin/jaro-gnome-keyring get`
-		fi
-		return 0
-	    elif [ -r $KEYRING ]; then
-                func "Looking for password in local keyring for $type account $account on $host"
-		func "new pass hash for: $type:$login:$host"
-		_hash=`print "$type:$login:$host" | shasum | awk '{print $1}'`
-		lookup="`lookup_secret ${_hash}`"
-		{ test "$lookup" = "" } || {
-		    act "Saved password found for $email ($transport on $host)"
-		    notice "Type the password to unlock this keyring entry:"
-		    password="`print $lookup | base64 -d | gpg -d --cipher-algo AES256 --openpgp --no-options`"
-		    { test "$?" = 0 } || { error "Incorrect password to unlock local keyring entry, operation aborted."; return 1 }
-		    return 0
-		}
-	    fi
-	    ####################
-	    # USE PINENTRY ALONE
-	    new_password
-	    { test $? != 0 } && {
-		error "Password input aborted."
-		return 1 }
-	    return 0
-	    ;;
-	*)
-	    error "Unknown system, can't figure out how to handle passwords"
-	    return 1
-    esac
-}
-
-lookup_secret() {
-    _hash=$1
-    if [ "$2" = "" ]; then key=password
-    else key="$2"; fi
-    cat <<EOF | ${SQL} -column -batch $KEYRING
-SELECT ${key} FROM secrets
-WHERE hash IS "${_hash}";
-EOF
-}
-
-new_password() {
-    notice "Setting a new password for $type account $account on $host"
-    act "please enter password for username '$login'"
-    password=`pin_entry $login $host`
-    res=0
-    case $OS in
-	MAC)
-	    if [ "$password" != "" ]; then
-
-		security delete-internet-password \
-		    -c JARO -a $email -s $host \
-		    -p $transport -P $port > /dev/null
-
-		security add-internet-password \
-		    -c JARO -a $email -s $host \
-		    -p $transport -P $port -w "${password}"
-
-		if [ $? != 0 ]; then
-		    error "Error adding password to keyring."
-		else
-		    act "New password saved in keyring"
-		fi
-		return 0
-
-	    else
-		error "No password given, operation aborted"
-		return 1
-
-		# we are not deleting passwords anymore
-		security delete-internet-password \
-		    -c JARO -a $email -s $host \
-		    -p $transport -P $port > /dev/null
-		res=$?; unset password
-		{ test $res != 0 } && {
-		    echo
-		    error "Error deleting password from keyring."
-		    return 1 }
-		act "No new password given, old password erased."
-		return 0
-		#########
-
-	    fi
-	    ;;
-	GNU)
-	    if [ "$password" != "" ]; then # password was written
-
-		# USE GNOME KEYRING
-		if [ "$GNOMEKEY" = "1" ]; then
-		    act "using gnome-keyring password storage"
-		    func "path: jaromail/${type}/${email}"
-		    cat <<EOF | $WORKDIR/bin/jaro-gnome-keyring store
-protocol=${type}
-path=jaromail/${type}/${email}
-username=${login}
-host=${host}
-password=${password}
-EOF
-		    { test $? != 0 } && { error "Error saving password in Gnome keyring" }
-
-		else # save it into local keyring
-
-		    { test -r $KEYRING } || {
-		    # make sure the local keyring exists 
-			touch $KEYRING
-			chmod 600 $KEYRING
-			chown $_uid:$_gid $KEYRING
-			cat <<EOF | ${SQL} -batch $KEYRING
-CREATE TABLE secrets
-(
-  hash		text unique,
-  password	text 
-);
-EOF
-		    }
-		    # calculate the hash for this entry
-		    _hash=`print "$type:$login:$host" | shasum | awk '{print $1}'`
-		    # check if the entry is already present
-		    func "new pass hash for: $type:$login:$host"
-		    lookup="`lookup_secret ${_hash} rowid`"
-		    notice "Select the password to lock this keyring entry:"
-		    _password="`print $password | gpg -c --cipher-algo AES256 --openpgp --no-options | base64`"
-		    if [ "$lookup" = "" ]; then # new entry
-			cat <<EOF | ${SQL} -batch $KEYRING
-INSERT INTO secrets (hash, password)
-VALUES ("${_hash}", "${_password}");
-EOF
-			act "saved new password in local keyring"
-		    else # update entry
-			cat <<EOF | ${SQL} -batch $KEYRING
-UPDATE secrets SET password="${_password}" WHERE hash LIKE "${_hash}";
-EOF
-			act "updated local keyring with new password"
-		    fi
-		fi
-
-		return 0
-
-	    else # password is blank or aborted
-
-		# save it into gnome keyring
-		if [ $GNOMEKEY = 1 ]; then
-
-		    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
-		# TODO: delete from local keyring
-
-	    fi
-	    ;;
-	*)
-	    error "Unknown system, can't figure out how to handle passwords"
-	    return 1
-    esac
-}
-
-change_password() {
-
-    read_account ${=PARAM}
-
-    { test $? = 0 } && { test $DRYRUN != 1 } && {
-	new_password }
-
-}
diff --git a/src/zlibs/addressbook b/src/zlibs/addressbook
@@ -27,11 +27,11 @@ ADDRESSBOOK=$MAILDIRS/Addressbook
 # Jaro Brother DB
 create_addressbook() {
     func "create addressbook"
-    { test -r "$ADDRESSBOOK" } && {
-	error "Addressbook already exists: $ADDRESSBOOK"
+    { test -r "$1" } && {
+	error "Addressbook already exists: $1"
 	return 1
     }
-    cat <<EOF | ${SQL} -batch $ADDRESSBOOK
+    cat <<EOF | ${SQL} -batch "$1"
 CREATE TABLE whitelist
 (
   email   text collate nocase unique,
@@ -47,8 +47,8 @@ EOF
 	error "Error creating addressbook database."
 	return 1 }
     # make sure is private
-    chmod 600 $ADDRESSBOOK
-    chown $_uid:$_gid $ADDRESSBOOK
+    chmod 600 "$1"
+    chown $_uid:$_gid "$1"
 
     return 0
 }
diff --git a/src/zlibs/filters b/src/zlibs/filters
@@ -126,6 +126,8 @@ text/html; lynx -dump -assume_charset=%{charset} %s; nametemplate=%s.html; copio
 EOF
     fi
 
+    { test -r ${MAILDIRS}/Applications.txt } && {
+
     apptypes=`cat ${MAILDIRS}/Applications.txt`
     for t in ${(f)apptypes}; do
 	eval `print $t | awk '
@@ -137,6 +139,8 @@ EOF
     cat <<EOF >> $MUTTDIR/mailcap
 application/*; a="${TMPDIR}" && f=\`basename %s\` && rm -f "\$a"/"\$f" && cp %s "\$a"/"\$f" && jaro preview "\$a"/"\$f"
 EOF
+    } # Applications.txt
+
 
     # this one is empty and sources files in temp when necessary
     # touch $TMPDIR/muttpass
@@ -197,7 +201,7 @@ EOF
 
 # continue later on while we parse filters
 
-
+touch $MAILDIRS/Filters.txt
 
     ##########
     # PROCMAIL
diff --git a/src/zlibs/keyring b/src/zlibs/keyring
@@ -0,0 +1,250 @@
+#!/usr/bin/env zsh
+#
+# Jaro Mail, your humble and faithful electronic postman
+#
+# a tool to easily and privately handle your e-mail communication
+#
+# Copyleft (C) 2014 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.
+
+create_keyring() {
+    # make sure the local keyring exists 
+    touch "$1"
+    chmod 600 "$1"
+    chown $_uid:$_gid "$1"
+    cat <<EOF | ${SQL} -batch "$1"
+CREATE TABLE secrets
+(
+  hash		text unique,
+  password	text 
+);
+EOF
+}
+
+
+# we use pinentry
+# comes from gpg project and is secure
+# it also conveniently uses the right toolkit
+pin_entry() {
+    	cat <<EOF | pinentry 2>/dev/null | awk '/^D / { sub(/^D /, ""); print }'
+OPTION ttyname=$TTY
+OPTION lc-ctype=$LANG
+SETTITLE Type your password
+SETDESC Type the password for $1 @ $2
+SETPROMPT Password:
+GETPIN
+EOF
+}
+
+
+# retrieve a password for user @ domain
+# put it in variable password
+# up to the caller to unset it after use
+ask_password() {
+    case $OS in
+	MAC)
+            func "Looking for password in Mac/OSX keyring for $email on $host over $type"
+	    security find-internet-password \
+		-c JARO -a $email -s $host \
+		-p $transport -P $port > /dev/null
+	    if [ $? != 0 ]; then # its a new password
+		new_password
+		{ test $? != 0 } && {
+		    error "Password input aborted."
+		    return 1 }
+	    else
+		password=`security find-internet-password -c JARO -a $email -s $host -p $transport -P $port -g 2>&1| awk '/^password:/ { print $2 }' | sed -e 's/"//g'`
+	    fi
+	    return 0
+	    ;;
+	#####################################
+	GNU)
+	    ###################
+	    # USE GNOME KEYRING
+	    if [ "$GNOMEKEY" = "1" ]; then
+                func "Looking for password in Gnome keyring for $email on $host over $type"
+		func "path: jaromail/${type}/${email}"
+
+		print "protocol=${type}\npath=jaromail/${type}/${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=`print "protocol=${type}\npath=jaromail/${type}/${email}\nusername=${login}\nhost=${host}\n\n" | $WORKDIR/bin/jaro-gnome-keyring get`
+		fi
+		return 0
+	    elif [ -r $KEYRING ]; then
+                func "Looking for password in local keyring for $type account $account on $host"
+		func "new pass hash for: $type:$login:$host"
+		_hash=`print "$type:$login:$host" | shasum | awk '{print $1}'`
+		lookup="`lookup_secret ${_hash}`"
+		{ test "$lookup" = "" } || {
+		    act "Saved password found for $email ($transport on $host)"
+		    notice "Type the password to unlock this keyring entry:"
+		    password="`print $lookup | base64 -d | gpg -d --cipher-algo AES256 --openpgp --no-options`"
+		    { test "$?" = 0 } || { error "Incorrect password to unlock local keyring entry, operation aborted."; return 1 }
+		    return 0
+		}
+	    fi
+	    ####################
+	    # USE PINENTRY ALONE
+	    new_password
+	    { test $? != 0 } && {
+		error "Password input aborted."
+		return 1 }
+	    return 0
+	    ;;
+	*)
+	    error "Unknown system, can't figure out how to handle passwords"
+	    return 1
+    esac
+}
+
+lookup_secret() {
+    _hash=$1
+    if [ "$2" = "" ]; then key=password
+    else key="$2"; fi
+    cat <<EOF | ${SQL} -column -batch $KEYRING
+SELECT ${key} FROM secrets
+WHERE hash IS "${_hash}";
+EOF
+}
+
+new_password() {
+    notice "Setting a new password for $type account $account on $host"
+    act "please enter password for username '$login'"
+    password=`pin_entry $login $host`
+    res=0
+    case $OS in
+	MAC)
+	    if [ "$password" != "" ]; then
+
+		security delete-internet-password \
+		    -c JARO -a $email -s $host \
+		    -p $transport -P $port > /dev/null
+
+		security add-internet-password \
+		    -c JARO -a $email -s $host \
+		    -p $transport -P $port -w "${password}"
+
+		if [ $? != 0 ]; then
+		    error "Error adding password to keyring."
+		else
+		    act "New password saved in keyring"
+		fi
+		return 0
+
+	    else
+		error "No password given, operation aborted"
+		return 1
+
+		# we are not deleting passwords anymore
+		security delete-internet-password \
+		    -c JARO -a $email -s $host \
+		    -p $transport -P $port > /dev/null
+		res=$?; unset password
+		{ test $res != 0 } && {
+		    echo
+		    error "Error deleting password from keyring."
+		    return 1 }
+		act "No new password given, old password erased."
+		return 0
+		#########
+
+	    fi
+	    ;;
+	GNU)
+	    if [ "$password" != "" ]; then # password was written
+
+		# USE GNOME KEYRING
+		if [ "$GNOMEKEY" = "1" ]; then
+		    act "using gnome-keyring password storage"
+		    func "path: jaromail/${type}/${email}"
+		    cat <<EOF | $WORKDIR/bin/jaro-gnome-keyring store
+protocol=${type}
+path=jaromail/${type}/${email}
+username=${login}
+host=${host}
+password=${password}
+EOF
+		    { test $? != 0 } && { error "Error saving password in Gnome keyring" }
+
+		else # save it into local keyring
+
+		    { test -r "$KEYRING" } || { create_keyring "$KEYRING" }
+
+		    # calculate the hash for this entry
+		    _hash=`print "$type:$login:$host" | shasum | awk '{print $1}'`
+		    # check if the entry is already present
+		    func "new pass hash for: $type:$login:$host"
+		    lookup="`lookup_secret ${_hash} rowid`"
+		    notice "Select the password to lock this keyring entry:"
+		    _password="`print $password | gpg -c --cipher-algo AES256 --openpgp --no-options | base64`"
+		    if [ "$lookup" = "" ]; then # new entry
+			cat <<EOF | ${SQL} -batch $KEYRING
+INSERT INTO secrets (hash, password)
+VALUES ("${_hash}", "${_password}");
+EOF
+			act "saved new password in local keyring"
+		    else # update entry
+			cat <<EOF | ${SQL} -batch $KEYRING
+UPDATE secrets SET password="${_password}" WHERE hash LIKE "${_hash}";
+EOF
+			act "updated local keyring with new password"
+		    fi
+		fi
+
+		return 0
+
+	    else # password is blank or aborted
+
+		# save it into gnome keyring
+		if [ $GNOMEKEY = 1 ]; then
+
+		    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
+		# TODO: delete from local keyring
+
+	    fi
+	    ;;
+	*)
+	    error "Unknown system, can't figure out how to handle passwords"
+	    return 1
+    esac
+}
+
+change_password() {
+
+    read_account ${=PARAM}
+
+    { test $? = 0 } && { test $DRYRUN != 1 } && {
+	new_password }
+
+}