Skip to content

njkli/stumpwm-pass-otp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

stumpwm pass-otp

pass-otp helper for StumpWM

DO NOT USE - this code is intended to be submitted to stumpwm-contrib repo at some point in time. Feel free to PR or educate me on lisp in the issues. Currently it works for me(tm).

Compatible with rofi-pass and stolen most of the readme from, thanks!

Why?

For some strange reason, rofi-pass didn’t work for my setup, the :otp was never autotyped, instead of debugging, it was decided to have a StumpWM ‘native’ version built.

Why xdotool and not cl-xlib?

The xdotool type command sends key-[Press|Release] events to the X server, it sends individual events, as can be seen here: https://github.com/jordansissel/xdotool/blob/08c8e2d6cad60a69ce415499e34865157a1b66fd/xdo.c#L958

Recreating it with cl-xlib is pointless, at least for such a meager purpose of typing something into a window. A LISP implementation of xdotool is a whole other different project, which might someday be written by someone, maybe.

Features

  • keymaps

    pass-otp-menu-map

    keyaction
    RETinline view
    C-RETopen url
    M-RETautotype
    M-ncreate new
    M-odisplay
    M-eedit
    M-qqr-code show/generate

    pass-otp-entry-menu-map

    keyaction
    RETset-x-selection
    M-RETautotype
  • pinentry handler

    stolen from stumpwm-contrib/util/pinentry (needed configurable port/host setts)

  • open URL

    if url: (.*) field is found, then it is used, otherwise the entry path is converted to url. Given an entry in hosting.com/someuser like:

    somepassword
    ---
    url: https://panel.hosting.com/login
        

    command xdg-open https://panel.hosting.com/login will run, if url: wasn’t found then https://hosting.com will be used instead.

adding new entries

Edit existing Entries M-e runs pass edit

Inline view RET

copy RET / type M-RET individual entries Regex is ": (.*)" Type any field from entry

Auto-typing

of user and/or password fields.

The format for password files should look like:

foobarmysecurepassword
user: MyUser
url: http://my.url.foo
  • Auto-typing of more than one field, using the autotype entry:
    foobarmysecurepassword
    ---
    user: MyUser
    SomeField: foobar
    AnotherField: barfoo
    url: http://my.url.foo
    autotype: SomeField :tab user any-string-at-all :tab AnotherField :tab pass
        

    Use :tab, :enter, :space, :delay, :otp here to type Tab, Enter, Space, Delay or OTP (useful for toggling checkboxes) respectively. :delay will trigger a delay (5 seconds by default).

    Anything else will be typed verbatim as-is, like the any-string-at-all string in the example above.

  • The field names for user, url and autotype are configurable

Generating OTPs.

The format for OTPs should be pass-otp(1)-compatible otpauth://[...]

Window recognition

Dependencies

Usage

cat /.gnupg/gpg-agent.conf

pinentry-program /full/path/to/pinentry-stumpwm

cat /full/path/to/pinentry-stumpwm

#!/path/to/your/bash
. $XDG_RUNTIME_DIR/pinentry-stumpwm.env

echo OK Your orders please

while IFS="\n" read -r command; do
    if [ "$command" == "GETINFO flavor" ]; then
        echo D stumpwm
    elif [[ "$command" == SETDESC* ]]; then
        description=${command:8}
    elif [[ "$command" == SETPROMPT* ]]; then
        prompt=${command:10}
    elif [ "$command" == GETPIN ]; then
        password=$(printf "%s\n%s\n" "$description" "$prompt" | nc $PINENTRY_HOST $PINENTRY_PORT)
        echo D "$password"
    elif [ "$command" == BYE ]; then
        exit 0
    fi

    echo OK
done < /dev/stdin

Most of the settings have sane defaults, sufficient:

;; I find this useful in general
(setf *menu-maximum-height* 16)

(push "/some/path/stumpwm-pass-otp/" asdf:*central-registry*)
(ql:quickload :pass-otp)

(define-key *root-map* (kbd "s-p") "pass-otp")
(define-key *root-map* (kbd "C-s-p") "pass-otp-show-all")

Or tweak:

(setf pass-otp:*password-store-dir* (merge-pathnames #p".password-store/" (user-homedir-pathname))
      pass-otp:*known-window-class-regex* "Firefox|Chromium"
      pass-otp:*uri-regex* "(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$])"
      pass-otp:*xdotool-delay* 3
      pass-otp:*autotype-delay* 5
      pass-otp:*autotype-default* "user :tab pass :enter"
      pass-otp:*autotype-regex-username* "user"
      pass-otp:*autotype-regex-password* "pass"
      pass-otp:*field-regex-username* "username: (.*)"
      pass-otp:*field-regex-autotype* "autotype: (.*)"
      pass-otp:*pinentry-listen-address* "127.0.0.1"
      pass-otp:*pinentry-listen-port* 65530
      pass-otp:*field-regex-url* "url: (.*)"
      pass-otp:*pass-otp-menu-map* (let ((m (make-sparse-keymap)))
                                     (define-key m (kbd "M-RET") (pass-otp:entry-menu-action :entry-autotype))
                                     (define-key m (kbd "M-o") (pass-otp:entry-menu-action :entry-display))
                                     (define-key m (kbd "M-e") (pass-otp:entry-menu-action :entry-edit))
                                     (define-key m (kbd "M-n") (pass-otp:entry-menu-action :entry-create))
                                     (define-key m (kbd "C-RET") (pass-otp:entry-menu-action :entry-open-url))
                                     (define-key m (kbd "M-q") (pass-otp:entry-menu-action :entry-qr-code))
                                     (define-key m (kbd "RET") (pass-otp:entry-menu-action :entry-menu))
                                     m))

TODO:

  • FIXME: gpg piv (ie. yubikey) will timeout on pin-entry
  • Switch pinentry to use unix domain sockets instead of IP?
  • Support for different password stores (roots), e.g. to separate passwords for work from private passwords

About

pass-otp helper for stumpwm

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published