forked from gopasspw/gopass
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve clipboard safety (gopasspw#2065)
This commit finally incorporates the changes suggested by rianadon in Additionally it switches the unclip checksum from SHA256 to Argon2id. Although the risk is close to zero (i.e. if someone can access our process env we're doomed anyway) but there is just no reason to not do it properly. RELEASE_NOTES=[ENHANCEMENT] Hide password on MacOS clipboards Fixes gopasspw#1816 Signed-off-by: Dominik Schulz <[email protected]>
- Loading branch information
1 parent
28479c0
commit 39e39be
Showing
6 changed files
with
118 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
//go:build darwin | ||
// +build darwin | ||
|
||
package clipboard | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"io" | ||
"os" | ||
"os/exec" | ||
|
||
"github.com/atotto/clipboard" | ||
"github.com/gopasspw/gopass/pkg/debug" | ||
) | ||
|
||
func copyToClipboard(ctx context.Context, content []byte) error { | ||
password := string(content) | ||
|
||
// first try to copy via osascript, if that fails fallback to pbcopy | ||
if err := copyViaOsascript(ctx, password); err != nil { | ||
debug.Log("failed to copy via osascript: %s", err) | ||
return clipboard.WriteAll(password) | ||
} | ||
return nil | ||
} | ||
|
||
func copyViaOsascript(ctx context.Context, password string) error { | ||
args := []string{ | ||
// The Foundation library has the Objective C symbols for pasteboard | ||
"-e", `use framework "Foundation"`, | ||
// Need to use scripting additions for access to "do shell script" | ||
"-e", "use scripting additions", | ||
// type = a reference to the ObjC constant NSPasteboardTypeString | ||
// which is needed to indentify clioboard contents as text | ||
"-e", "set type to current application's NSPasteboardTypeString", | ||
// pb = a reference to the system's pasteboard | ||
"-e", "set pb to current application's NSPasteboard's generalPasteboard()", | ||
// Must clear contents before adding a new item to pasteboard | ||
"-e", "pb's clearContents()", | ||
// Set the flag ConcealedType so clipboard history managers don't record the password. | ||
// The first argument can by anything, but an empty string will do fine. | ||
"-e", `pb's setString:"" forType:"org.nspasteboard.ConcealedType"`, | ||
// AppleScript cannot read from stdin, so pipe fd#3 to stdin of cat and read the output. | ||
// This output is put in the clipboard, setting type = string type | ||
"-e", `pb's setString:(do shell script "cat 0<&3") forType:type`, | ||
} | ||
cmd := exec.CommandContext(ctx, "osascript", args...) | ||
r, w, err := os.Pipe() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// This connects the pipe to stdin of the osascript command, see the "do shell script" | ||
// part around line 46. The pipe is created and written to before the osascript command | ||
// is run so we shouldn't need to worry about partial writes (I hope!). | ||
// | ||
// TODO: We might be able to use `cmd.Stdin = strings.NewReader(password)` instead | ||
cmd.ExtraFiles = []*os.File{r} // Receiving end of pipes is connected to fd#3 | ||
go func() { | ||
defer w.Close() | ||
io.WriteString(w, password) // Write the password to fd#3 | ||
}() | ||
|
||
out, err := cmd.Output() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// osascript should print true (return value of the last setString call) on success | ||
if string(out) != "true\n" { | ||
// Fallback to using attoto's pbcopy | ||
return fmt.Errorf("osascript failed to set password: %s", string(out)) | ||
} | ||
debug.Log("copied via osascript") | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
//go:build !darwin | ||
// +build !darwin | ||
|
||
package clipboard | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/atotto/clipboard" | ||
) | ||
|
||
func copyToClipboard(ctx context.Context, content []byte) error { | ||
return clipboard.WriteAll(string(content)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters