Differences From
Artifact [ae23203c4b]:
39 39
40 40 if you use nixos and wish to build the pdf documentation, you're going to have to do a bit of extra work (but you're used to that, aren't you). for some incomprehensible reason, the groff package on nix is split up, seemingly randomly, with many crucial output devices relegated to the "perl" output of the package, which is not installed by default (and `nix-env -iA nixos.groff.perl` doesn't work either; i don't know why either). you'll have to instantiate and install the outputs directly by path, e.g. `nix-env -i /nix/store/*groff*/` to get everything you need into your profile. alas, the battle is not over: you also need to change the environment variables `GROFF_FONT_PATH` and `GROFF_TMAC_PATH` to point at the `font` and `tmac` subdirs of `~/.nix-profile/share/groff/$groff_version/`. once this is done, invoking `groff -Tpdf` will work as expected.
41 41
42 42 ## configuring
43 43
44 44 the `parsav` configuration is comprised of two components: the backends list and the config store. the backends list is a simple text file that tells `parsav` which data sources to draw from. the config store is a key-value store which contains the rest of the server's configuration, and is loaded from the backends. the configuration store can be spread across the backends; backends will be checked for configuration keys according to the order in which they are listed. changes to the configuration store affect parsav in real time; you only need to restart the server if you make a change to the backend list.
45 45
46 -eventually, we'll add a command-line tool `parsav-cfg` to enable easy modification of the configuration store from the command line; for now, you'll need to modify the database by hand or use the online administration menu. the schema.sql file contains commands to prompt for various important values like the name of your administrative user.
46 +you can directly modify the store from the command line with the `parsav conf` command; see `parsav conf -h` for more information.
47 47
48 48 by default, parsav looks for a file called `backend.conf` in the current directory when it is launched. you can override this default with the `parsav_backend_file` environment or with the `-b`/`--backend-file` flag. `backend.conf` lists one backend per line, in the form `id type confstring`. for instance, if you had two postgresql databases, you might write a backend file like
49 49
50 50 master pgsql host=localhost dbname=parsav
51 51 tweets pgsql host=420.69.dread.cloud dbname=content
52 52
53 53 the form the configuration string takes depends on the specific backend.
54 54
55 +once you've set up a backend and confirmed parsav can connect succesfully to it, you can initialize the database with the command `parsav db init <domain>`, where `<domain>` is the name of the domain name you will be hosting `parsav` from. this will install all necessary structures and functions in the target and create all necessary files. it will not, however, create any users. you can create an initial administrative user with the `parsav mkroot <handle>` command, where `<handle>` is the handle you want to use on the server. this will also assign a temporary password for the user if possible. you should now be able to log in and administer the server.
56 +
57 +by default, parsav binds to [::1]:10917. if you want to change this (to run it on a different port, or make it directly accessible to other servers on the network), you can use the command `parsav conf set bind <address>`, where `address` is a binding specification like `0.0.0.0:80`. it is recommended, however, that `parsavd` be kept accessible only from localhost, and that connections be forwarded to it from nginx, haproxy, or a similar reverse proxy. (this can also be changed with the online configuration UI)
58 +
55 59 ### postgresql backend
56 60
57 -currently, postgres needs to be configured manually before parsav can make use of it to store data. the first step is to create a database for parsav's use. once you've done that, you need to create the database schema with the command `$ psql (-h $host) -d $database -f schema.sql`. you'll be prompted for some crucial settings to install in the configuration store, such as the name of the relation you want to use for authentication (we'll call it `parsav_auth` from here on out).
61 +a database will need to be created for `parsav`'s use before `parsav db init` will work. this can be accomplished with a command like `$ createdb parsav`. you'll also of course need to set up some way for `parsavd` to authenticate itself to `postgres`. peer auth is the most secure option, and this is what you should use if postgres and `parsavd` are running on the same box. specify the database name to the backend the usual way, with a clause like `dbname=parsav` in your connection string.
58 62
59 -parsav separates the storage of user credentials from the storage of other user data, in order to facilitate centralized user accounting. you don't need to take advantage of this feature, and if you don't want to, you can just create a `parsav_auth` table and have done. however, `parsav_auth` can also be a view, collecting a list of authorized users and their various credentials from whatever source you please.
63 +the postgresql backend has some extra features that enable it to be integrated with existing authentication databases you may have. when you initialize the database, a table `parsav_auth` will be created to hold the credentials of the instance users and the authentication mode will be set to "managed", which will enable parsav's built-in credential administration tools. if you would prefer to use your own source of credentials, you'll need to set parsav to "unmanaged" mode with the command `parsav be pgsql setup-auth unmanaged`.
64 +
65 +this command will reconfigure `parsav` and remove the `parsav_auth` table, making room for you to create a view with the same name. if you want to go back to managed mode at any time, just run `parsav be psql setup-auth managed`; just be aware that this will delete your auth view!
60 66
61 67 `parsav_auth` has the following schema:
62 68
63 69 create table parsav_auth (
64 70 aid bigint primary key,
65 71 uid bigint,
66 72 newname text,
................................................................................
69 75 restrict text[],
70 76 netmask cidr,
71 77 blacklist bool
72 78 )
73 79
74 80 `aid` is a unique value identifying the authentication method. it must be deterministic -- values based on time of creation or a hash of `uid`+`kind`+`cred` are ideal. `uid` is the identifier of the user the row specifies credentials for. `kind` is a string indicating the credential type, and `cred` is the content of that credential.for the meaning of these fields and use of this structure, see **authentication** below.
75 81
76 -## authentication
77 82 in the most basic case, an authentication record would be something like `{uid = 123, kind = "pw-sha512", cred = "\x12bf90…a10e"::bytea}`. but `parsav` is not restricted to username-password authentication, and in addition to various hashing styles, it also will support more esoteric forms of authentcation. any individual user can have as many auth rows as she likes. there is also a `restrict` field, which is normally null, but can be specified in order to restrict a particular credential to certain operations, such as posting tweets or updating a bio. `blacklist` indicates that any attempt to authenticate that matches this row will be denied, regardless of whether it matches other rows. if `netmask` is present, this authentication will only succeed if it comes from the specified IP mask.
78 83
79 -`uid` can also be `0` (not null, which matches any user!), indicating that there is not yet a record in `parsav_actors` for this account. if this is the case, `name` must contain the handle of the account to be created when someone attempts to log in with this credential. whether `name` is used in the authentication process depends on whether the authentication method accepts a username. all rows with the same `uid` *must* have the same `name`.
84 +`uid` can also be `0` (emphatically *not* null, which causes the rule to match any user!), indicating that there is not yet a record in `parsav_actors` for this account. if this is the case, `name` must contain the handle of the account to be created when someone attempts to log in with this credential. whether `name` is used in the authentication process depends on whether the authentication method accepts a username. all rows with the same `uid` *must* have the same `name`.
85 +
86 +## invoking
87 +the build process generates two binaries, `parsav` and `parsavd`. `parsav` is a driver tool that can be used to set up and start a `parsav` instance, as well as administer it from the command line. it accesses databases directly and uses the same backend configuration file as parsav, but can also send IPC messages directly to running `parsavd` instances.
88 +
89 +as a convenience, the `parsav start` command can be used to start and daemonize a `parsav` instance. additionally, the `-l` option to `parsav start` can be used to redirect `parsavd`'s logging output to a file; without `-l`, logging output will be discarded and can be viewed only by connecting to the running instance with `parsav attach`. `parsav start` passes its arguments on to `parsavd`; you can use this to pass options by separating `parsav`'s arguments from `parsavd`'s with `--`. if you launch an instance with `parsav start -- -i chungus`, you can then stop that instance with `parsav -i chungus stop`. `parsav stop` can be used on its own if only one `parsavd` instance is running; otherwise, `parsav -a stop` will cleanly terminate all running instances.
90 +
91 +you generally should not invoke `parsavd` directly except for debugging purposes, or in the context of an init daemon (particularly systemd). if you launch `parsavd` directly it will not fork to the background.
80 92
93 +## authentication
81 94 below is a full list of authentication types we intend/hope to one day support. contributors should consider this a to-do list. a checked box indicates the scheme has been implemented.
82 95
83 96 * ☑ pw-sha{512,384,256,224}: an ordinary password, hashed with the appropriate algorithm
84 97 * ☐ pw-{sha1,md5,clear} (insecure, must be manually enabled at compile time with the config variable `parsav_let_me_be_a_dumbass="i know what i'm doing"`)
85 98 * ☐ pw-pbkdf2-hmac-sha{…}: a password hashed with the Password-Based Key Derivation Function 2 instead of plain SHA2
86 99 * ☐ pw-extern-ldap: try to authenticate by binding against an LDAP server
87 100 * ☐ pw-extern-cyrus: try to authenticate against saslauthd
................................................................................
92 105 * ☐ api-digest-sha{…}: a value that can be hashed with the current epoch to derive a temporary access key without logging in. these are used for API calls, sent in the header `X-API-Key`.
93 106 * ☐ otp-time-sha1: a TOTP PSK: the first two bytes represent the step, the third byte the OTP length, and the remaining ten bytes the secret key
94 107 * ☐ tls-cert-fp: a fingerprint of a client certificate
95 108 * ☐ tls-cert-ca: a value of the form `fp/key=value` where a client certificate with the property `key=value` (e.g. `uid=cyberlord19`) signed by a certificate authority matching the given fingerprint `fp` can authenticate the user
96 109 * ☐ challenge-rsa-sha256: an RSA public key. the user is presented with a challenge and must sign it with the corresponding private key using SHA256.
97 110 * ☐ challenge-ecc-sha256: a Curve25519 public key. the user is presented with a challenge and must sign it with the corresponding private key using SHA256.
98 111 * ☐ challenge-ecc448-sha256: a Curve448 public key. the user is presented with a challenge and must sign it with the corresponding private key using SHA256.
99 -* ☑ trust: authentication always succeeds. only use in combination with netmask!!!
112 +* ☑ trust: authentication always succeeds (or fails, if blacklisted). only use in combination with netmask!!!
113 +
114 +## legal
115 +
116 +parsav is released under the terms of the EUPL v1.2. copies of this license are included in the repository. by contributing any intellectual property to this project, you reassign ownership and all attendant rights over that intellectual property to the current maintainer. this is to ensure that the project can be relicensed without difficulty in the unlikely event that it is necessary.
100 117
101 -## license
118 +## code of conduct
102 119
103 -parsav is released under the terms of the EUPL v1.2. copies of this license are included in the repository. dependencies are produced
120 +when hacking on `parsav`, it is absolutely mandatory to wear a wizard hat and burgundy silk summoning cloak. this code of conduct is enforced capriciously by the Fair Folk, and violations are punishable by dancing hex.
104 121
105 122 ## future direction
106 123
107 124 parsav needs more storage backends, as it currently supports only postgres. some possibilities, in order of priority, are:
108 125
109 126 * plain text/filesystem storage
110 127 * lmdb