[PATCH] RFC: hooks for clipboard manager integration

Allan Odgaard lists+pass at simplit.com
Sun Jul 5 05:25:02 CEST 2020


On macOS the way for password managers to temporarily put sensitive data 
on the clipboard is by tagging the data.

Therefore a pre/post hook will not be a good solution for macOS, instead 
it should be a callback that places the content on the clipboard.

A simple interface would be a function that accepts $password and 
$duration, the default implementation on macOS (using `pbcopy` and 
`pbpaste`) would be something like this:

    function user_function {
       password="$1"
       duration="$2"

       old="$(pbpaste)"
       printf "%s" "$password" | pbcopy

       sleep "$duration"

       if [[ "$(pbpaste)" == "$password" ]]; then
          printf "%s" "$old" | pbcopy
       fi
    }

The advantage of using pre/post hooks is that it does not become the job 
of the callback to sleep nor check if content has changed.

However, for the latter, a callback might do better than `pass` itself, 
for example on macOS the clipboard has a change counter, so the callback 
can check that to learn about changes.

Furthermore for the `sleep`: Having the callback perform the sleep, we 
avoid having to introduce state that is shared between the pre and post 
hook, if we also want to improve restoring content (e.g. on macOS `pass` 
will currently not restore non-text content or text with multiple 
representations).

So all in all, I think the interface should be a single function that 
does all the work, instead of introducing hooks, as I don’t think the 
complexity of implementing a callback is higher than writing hooks, and 
a function is much less limited, e.g. on macOS we will be able both to 
tag the content (for clipboard managers) and we will be able to do a 
better job at restoring the old clipboard data, neither of which is 
possible with the hooks.

For the records though, in order to improve things on macOS, we will 
need to write a compiled helper and use that instead of 
`pbcopy`/`pbpaste`.


On 5 Jul 2020, at 8:20, Dov Feldstern wrote:

> # HG changeset patch
> # User Dov Feldstern <dovdevel at gmail.com>
> # Date 1593908715 -10800
> #      Sun Jul 05 03:25:15 2020 +0300
> # Node ID d4af3f470f3f04fb81bbcb079556ea56e8e43898
> # Parent  dcfa9a1c9c827206f899e7ba604f42366fbd60f3
> RFC: hooks for clipboard manager integration
>
> I've been using password-store for a few months now, and am very happy 
> with it
> -- thanks to all involved!
>
> One thing that I'm still grappling with is how to avoid having the 
> passwords
> get stored by my clipboard manager (currently copyq). I see that 
> discussions of
> this come up in the mailing list every once in a while, for various 
> clipboard
> managers; and also from the clipboard manager side, I see that many 
> clipboard
> managers discuss how to deal with the issue of passwords. But there 
> doesn't
> seem to be any standard way, which obviously makes dealing with this 
> in a
> generic way a bit difficult...
>
> In this patch, I propose to add hooks, which can then be implemented 
> as
> appropriate for the various clipboard managers. I moved the handling 
> for
> klipper into the "default" hook, and in contrib/ I added a reference
> implementation for how I'd like passwords to be handled for copyq -- 
> so this
> demonstrates that the method works for at least two password managers 
> ;) .
>
> I am offering this here as an RFC: is this kind of approach acceptable 
> to the
> project? If so, probably the hooking mechanism should be designed a 
> bit more
> throughly than what I've done here (I am also not very proficient in 
> bash
> programming, so there's probably a nicer way to add hooks than what 
> I've
> done...). But once such a hooking mechanism is in place, I think it 
> offers a
> more scalable solution for dealing with the variety of clipboard 
> managers, and
> will probably also find a bunch of other use cases, as well...
>
> I'd be glad to hear any thoughts on this...
>
> Thanks!
> Dov
>
> diff -r dcfa9a1c9c82 -r d4af3f470f3f contrib/hooks/copyq.sh
> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/contrib/hooks/copyq.sh	Sun Jul 05 03:25:15 2020 +0300
> @@ -0,0 +1,11 @@
> +hook_clip_pre_copy_pw() {
> +	copyq disable
> +}
> +
> +hook_clip_post_copy_pw() {
> +	copyq enable
> +}
> +
> +hook_clip_pre_restore() {
> +	return
> +}
> diff -r dcfa9a1c9c82 -r d4af3f470f3f src/password-store.sh
> --- a/src/password-store.sh	Thu Jun 25 23:41:11 2020 +0200
> +++ b/src/password-store.sh	Sun Jul 05 03:25:15 2020 +0300
> @@ -14,6 +14,7 @@
>
>  PREFIX="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
>  EXTENSIONS="${PASSWORD_STORE_EXTENSIONS_DIR:-$PREFIX/.extensions}"
> +HOOKS="${PASSWORD_STORE_HOOKS_DIR:-$PREFIX/.hooks}"
>  X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}"
>  CLIP_TIME="${PASSWORD_STORE_CLIP_TIME:-45}"
>  GENERATED_LENGTH="${PASSWORD_STORE_GENERATED_LENGTH:-25}"
> @@ -152,6 +153,25 @@
>  # BEGIN platform definable
>  #
>
> +hook_clip_pre_copy_pw() {
> +	return
> +}
> +
> +hook_clip_post_copy_pw() {
> +	return
> +}
> +
> +hook_clip_pre_restore() {
> +		# It might be nice to programatically check to see if klipper 
> exists,
> +		# as well as checking for other common clipboard managers. But for 
> now,
> +		# this works fine -- if qdbus isn't there or if klipper isn't 
> running,
> +		# this essentially becomes a no-op.
> +		#
> +		# Clipboard managers frequently write their history out in 
> plaintext,
> +		# so we axe it here:
> +		qdbus org.kde.klipper /klipper 
> org.kde.klipper.klipper.clearClipboardHistory &>/dev/null
> +}
> +
>  clip() {
>  	if [[ -n $WAYLAND_DISPLAY ]]; then
>  		local copy_cmd=( wl-copy )
> @@ -175,21 +195,15 @@
>  	# trailing new lines.
>  	pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.5
>  	local before="$("${paste_cmd[@]}" 2>/dev/null | $BASE64)"
> +	hook_clip_pre_copy_pw
>  	echo -n "$1" | "${copy_cmd[@]}" || die "Error: Could not copy data 
> to the clipboard"
> +	hook_clip_post_copy_pw
>  	(
>  		( exec -a "$sleep_argv0" bash <<<"trap 'kill %1' TERM; sleep 
> '$CLIP_TIME' & wait" )
>  		local now="$("${paste_cmd[@]}" | $BASE64)"
>  		[[ $now != $(echo -n "$1" | $BASE64) ]] && before="$now"
>
> -		# It might be nice to programatically check to see if klipper 
> exists,
> -		# as well as checking for other common clipboard managers. But for 
> now,
> -		# this works fine -- if qdbus isn't there or if klipper isn't 
> running,
> -		# this essentially becomes a no-op.
> -		#
> -		# Clipboard managers frequently write their history out in 
> plaintext,
> -		# so we axe it here:
> -		qdbus org.kde.klipper /klipper 
> org.kde.klipper.klipper.clearClipboardHistory &>/dev/null
> -
> +		hook_clip_pre_restore
>  		echo "$before" | $BASE64 -d | "${copy_cmd[@]}"
>  	) >/dev/null 2>&1 & disown
>  	echo "Copied $2 to clipboard. Will clear in $CLIP_TIME seconds."
> @@ -246,6 +260,10 @@
>
>  source "$(dirname "$0")/platform/$(uname | cut -d _ -f 1 | tr 
> '[:upper:]' '[:lower:]').sh" 2>/dev/null # PLATFORM_FUNCTION_FILE
>
> +for hook in $HOOKS/*.sh; do
> +	source $hook
> +done
> +
>  #
>  # END platform definable
>  #


More information about the Password-Store mailing list