summaryrefslogtreecommitdiff
path: root/pt
blob: 91aa0cc1df39455dcad5b793f3734c9ca31488f1 (plain)
    1 #!/usr/bin/env bash
    2 #
    3 # Automatically types the username and password from the pass entry specified
    4 # as argument one. The required password-store backend is pass, the standard
    5 # unix password manager.
    6 #
    7 # A simple workflow for this may be to go to a website requiring a username and
    8 # password. Select the username field, open a program launcher such as rofi or
    9 # dmenu, then execute 'quicktype password-name'.
   10 #
   11 # Note that for this to work, each pass entry must match the following criteria
   12 # * The password is on the first line (this is the pass standard)
   13 # * The username can be anywhere in the file, but the line must look like
   14 #   'username: <password>'
   15 # 
   16 # Depends on: pass xdotool
   17 #
   18 
   19 
   20 export PASSWORD_STORE_DIR=~/.password-store
   21 
   22 
   23 #
   24 # Writes log output to terminal and notification daemon, if one is present.
   25 #
   26 function log {
   27   local msg="${@}"
   28 
   29   if [[ $(type -p notify-send) != '' ]]; then
   30     notify-send "$(basename ${0}):" "${msg}"
   31   fi
   32   echo ${msg}
   33 }
   34 
   35 
   36 #
   37 # Ensures required tools are available, returning code 1 and log if any of them
   38 # are not.
   39 #
   40 function check_env {
   41   # Verify pass is installed and in the PATH.
   42   if [[ $(type -p pass) == '' ]]; then
   43     log "Error: Could not find pass." && return 1
   44   fi
   45 
   46   # Verify xdotool is installed and in the path
   47   if [[ $(type -p xdotool) ==  '' ]]; then
   48     log "Error: Could not find xdotool." && return 1
   49   fi
   50 
   51   # Verify /dev/null is a character device, on the off chance someone with root
   52   # access is trying to capture output redirected there.
   53   local devstat=$(ls -l /dev/null)
   54   if [[ ${devstat:0:1} != 'c' ]]; then
   55     log "Error: /dev/null is not a character device."
   56     return 1
   57   fi
   58 
   59   return 0
   60 }
   61 
   62 
   63 #
   64 # Gets a field's value from the specified [multiline] string, using the
   65 # specified delimiter.
   66 #
   67 # @param content Content to extract field value from
   68 # @param delim   Delimiter seperating fields and values
   69 # @param field   Field name to get value for
   70 #
   71 getfield() {
   72   local _content="${1:-}"
   73   local _delim="${2:-}"
   74   local _field="${3:-}"
   75 
   76   printf "${_content}" \
   77     | sed -n "s/${_field}${_delim} *\(.*\)/\1/p" \
   78     | head -n 1
   79 }
   80 
   81 
   82 function main {
   83   local _passentry    # Contents of the requested pass entry
   84   local _passpassword # Password from the pass entry
   85   local _passusername # Username field from the pass entry
   86   local _passdelim    # UI Field delimiter (Tab, Return), from the pass entry
   87   local _passsubmit   # Boolean submit (1,y,yes...), from the pass entry
   88 
   89   local _delim=Tab    # Default delimiter if not specified in pass entry
   90   local _submit=0     # Default submit value if not specified in pass entry
   91 
   92   # Exit failure if no password was specified
   93   [[ -z ${1} ]] && log "Please specify a password to be typed" && exit 1
   94 
   95   check_env || exit 0
   96   
   97   # Check if the password exists in the store
   98   # Also, copy the contents into a variable if it exists
   99   _passentry=$(pass ${@} 2>/dev/null)
  100   [[ $? -gt 0 ]] && log "Error: '${@}' is not in the password store" && exit 1
  101   
  102   # Parse pass output into appropriate variables 
  103   _passpassword=$(printf "${_passentry}" | head -n1)
  104   _passusername=$(getfield "${_passentry}" ':' username)
  105   _passdelim=$(getfield    "${_passentry}" ':' delim)
  106   _passsubmit=$(getfield   "${_passentry}" ':' submit)
  107 
  108   # If any of the known 'submit' values are specified, set submit to 1
  109   if [ "${_passsubmit}" = '1' ] \
  110     || [ "${_passsubmit}" = 'y' ] \
  111     || [ "${_passsubmit}" = 'yes' ]; then
  112     _submit=1
  113   fi
  114   
  115   # Type the password
  116   xdotool type --delay 15 "${_passusername}"
  117   xdotool key "${_delim}"
  118   xdotool type --delay 15 "${_passpassword}"
  119 
  120   [ "${_submit}" = 1 ] && xdotool key Return
  121 }
  122 
  123 main ${@}

Generated by cgit