Webinterface for password safe "pass" (http://www.passwordstore.org/)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
andrwe ae21eda224 minor 7 years ago
apigen added documenation; implemented user/isAdmin 7 years ago
backend implemented & documented user/modify->name 7 years ago
doc not needed anymore 7 years ago
frontend fixed bug in changeCategory function 7 years ago
.gitignore added PSX framework; updated UML; added all functions 7 years ago
README.md minor 7 years ago
apigen.backend.config added documenation; implemented user/isAdmin 7 years ago
apigen.webapi.config added documenation; implemented user/isAdmin 7 years ago
gendocu.sh minor fixes in gendocu.sh and backend documentation 7 years ago
webpass-uml.dia implemented addUser 7 years ago
webpass-uml.jpeg added PSX framework; updated UML; added all functions 7 years ago

README.md

webpass

webpass is a web based frontend for the shell password safe program "pass". It contains a backend implementing an web API and a frontend for browsers.

installation

  1. checkout code from https://www.seiichiro0185.org/gitlab/andrwe/webpass.git
  2. configure webserver
  • for nginx configuration example using default php-fpm settings see below
  1. change permissions of data path that webserver-user may write into it
sudo chown http:http data && sudo chmod 770 data
user http;
worker_processes  1;
error_log  /tmp/nginx-error.log;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    access_log  /tmp/nginx-access.log;
    sendfile        on;
    keepalive_timeout  65;
    gzip  on;
    root   /data/git/webpass/backend;
    server {
        listen       80;
        server_name  localhost;
        location /webpass {
            index  index.php;
            rewrite ^(.*)$ /webpass/index.php last;
        }
        location ~ \.php$ {
            fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

    }
}

API

All API calls have to POST the variable "json" containing the JSON encoded parameters. Every JSON has to contain the login data in format:

{ "login": {"username": "<username>", "password": "<password>"} }
category method description call params added to URL POST-params in JSON Return
user add add a user to password storage /user/add/ username "newlogin": { "password": "password", "admin": false-OR-true} { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
user exists check if users exist /user/exists/ { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
user ready check if addition of given user has finished /user/ready/ username { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
user remove remove given user /user/remove/ username { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
user credCheck check user credentials /user/credCheck { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
user isAdmin check whether user is admin or not /user/isAdmin { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
user list list existing users /user/list { "success": true-OR-false, "error": error-code, "error_msg": "error message", "data": { 2: "user1", 3: "user2", ... } }
store add add identifier to password store /store/add "store": { "category": "category", "identifier": "identifier", "password": "password", [ "force": true-OR-false (default = false) ] } { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
store add add category to password store /store/add "store": { "category": "category" } { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
store show show password of identifier /store/show "store": { "category": "category", "identifier": "identifier" } { "success": true-OR-false, "error": error-code, "error_msg": "error message", "data": {"password"} }
store list list identifiers in store (category may be omitted to list first level) /store/list "store": { "category": "category" } { "success": true-OR-false, "error": error-code, "error_msg": "error message", "data": [ { "name": "name1", "type": "category", { "name": "name3", "type": "identifier" } ] }
store list list all identifiers in store (category may be omitted to list first level) /store/list "store": { "category": "category", "listall": true } { "success": true-OR-false, "error": error-code, "error_msg": "error message", "data": [ { "name": "name1", "type": "category", "data": [ { "name": "name2", "type": "identifier" } ] }, { "name": "name3", "type": "identifier" } ] }
store remove remove category/identifier from password store (either category or identifier have to be given) /store/remove "store": { "category": "category", "identifier": "identifier", [ "force": true-OR-false (default = false) ] } { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
store copy copy category/identifier within password store /store/copy "store": { "category": "category", "identifier": "identifier", "newcategory": "newcategory", "newidentifier": "newidentifier", "force": true-OR-false (default = false) } { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
store move move category/identifier within password store /store/copy "store": { "category": "category", "identifier": "identifier", "newcategory": "newcategory", "newidentifier": "newidentifier", "force": true-OR-false (default = false) } { "success": true-OR-false, "error": error-code, "error_msg": "error message"}
store find find categories/identifiers matching a search string /store/find "store": { "search": "searchstring" } { "success": true-OR-false, "error": error-code, "error_msg": "error message", "data": {"array same as list method"} }

Error codes

code message call
0 (used if "data" is set) all
1 (internal use only if no error occured) API::processApi(), user/add
2 method not found API::processApi(), WebpassBackend::user(), WebpassBackend::store()
3 only admins may do WebpassBackend::user()
4 method not yet implemented all
5 not enough paramters for given method WebpassBackend::user()
6 username or password missing all
10 user does not exist user/ready, user/credCheck, user/modify, user/remove
11 user is ready user/ready
12 initializing user user/ready
13 users found user/exists
14 no users found user/exists
15 user removed user/remove
16 user could not be removed user/remove
17 user initialization started user/add
18 credentials valid user/credCheck
19 credentials invalid user/credCheck
20 user renamed successfully user/modify->name
21 user could not be renamed user/modify->name
30 login data stored successfully store/add
31 login data could not be stored store/add
32 given identifier already exists, "force" needed store/add
33 could not load stored password store/show
34 given category/identifier does not exist store/list, store/remove, store/copy
35 given category is emtpy store/list
36 category is not empty and "force" is not given, skipped store/remove
37 category removed successfully store/remove
38 category could not be removed store/remove
39 identifier removed successfully store/remove
40 identifier could not be removed store/remove
41 either category or identifier has to be given store/remove, store/copy
42 either new category or new identifier has to be given store/copy
43 one or more categories/identifiers already exists in target, "force" needed store/copy
44 login data could not be stored, password missing store/add
45 category/identifier copied successfully store/copy
46 category/identifier could not be copied store/copy
47 category/identifier moved successfully store/move
48 category/identifier could not be moved store/move
49 search string missing store/find
50 path removed successfully WebpassBackend::_removePath()
51 path could not be removed WebpassBackend::_removePath()
52 path moved successfully WebpassBackend::_movePath()
53 (unused) path could not be moved WebpassBackend::_movePath()
54 (unused) path copied successfully WebpassBackend::_copyPath()
55 path could not be copied WebpassBackend::_copyPath()
56 (unused) destination path alredy exists WebpassBackend::_copyPath(), WebpassBackend::_movePath()
57 (unused) source path does not exist WebpassBackend::_copyPath(), WebpassBackend::_movePath()
58 Path does exist WebpassBackend::_existsPath()
59 Path does not exist WebpassBackend::_existsPath()

Decisions

  1. frontend does session handling
  • in backend the session data (GPG password) would be cached on the system storing the GPG keys => all persons and systems with access to server may use keys by just reading the cache
  1. don't implement Git support of "pass"
  • if Git is enabled "pass" creates a new commit for every change
  • if GPG key is compromised changing the key would not be sufficient as the attacker just has to revert some commits => all passwords have to be changed too
  • without Git support the probability of comprised passwords is lower and GPG key change might be enough
  1. category and identifier are give via POST
  • it kind of breaks RESTful but there are to much restrictions if given via URL (e.g. character-set)

TODO

  • validation of username based on allowed characters
  • validation of store path given by store/*
  • general error handling checks
  • validation of category and identifier names

Credits