Differences From
Artifact [d4a5d691bd]:
1 1 # parsav
2 2
3 3 **parsav** is a lightweight fediverse server
4 4
5 +## backends
6 +parsav is designed to be storage-agnostic, and can draw data from multiple backends at a time. backends can be enabled or disabled at compile time to avoid unnecessary dependencies.
7 +
8 +* postgresql
9 +
5 10 ## dependencies
6 11
7 -* libhttp
12 +* mongoose
8 13 * json-c
9 14 * mbedtls
10 -* postgresql-libs
15 +* **postgresql backend:**
16 + * postgresql-libs
11 17
12 18 ## building
13 19
14 -first, either install any missing dependencies as shared libraries, or build them as static libraries as described below:
20 +first, either install any missing dependencies as shared libraries, or build them as static libraries with the command `make dep.$LIBRARY`. as a shortcut, `make dep` will build all dependencies as static libraries. note that if the build system finds a static version of a librari in the `lib/` folder, it will use that instead of any system library.
21 +
22 +postgresql-libs must be installed systemwide, as `parsav` does not currently provide for statically compiling and linking it
23 +
24 +## configuring
25 +
26 +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.
27 +
28 +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.
29 +
30 +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
31 +
32 + master pgsql host=localhost dbname=parsav
33 + tweets pgsql host=420.69.dread.cloud dbname=content
34 +
35 +the form the configuration string takes depends on the specific backend.
36 +
37 +### postgresql backend
38 +
39 +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).
40 +
41 +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.
42 +
43 +`parsav_auth` has the following schema:
44 +
45 + create table parsav_auth (
46 + aid bigint primary key,
47 + uid bigint,
48 + newname text,
49 + kind text not null,
50 + cred bytea not null,
51 + restrict text[],
52 + netmask cidr,
53 + blacklist bool
54 + )
55 +
56 +`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.
57 +
58 +## authentication
59 +in the most basic case, an authentication record would be something like `{uid = 123, kind = "pw-sha512", cred = "12bf90…a10e"}`. 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.
60 +
61 +`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`.
62 +
63 +below is a full list of authentication types we intend to support. a checked box indicates the scheme has been implemented.
64 +
65 +* ☑ pw-sha{512,384,256,224}: an ordinary password, hashed with the appropriate algorithm
66 +* ☐ 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"`)
67 +* ☐ pw-pbkdf2-hmac-sha{…}: a password hashed with the Password-Based Key Derivation Function 2 instead of plain SHA2
68 +* ☐ 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`.
69 +* ☐ 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
70 +* ☐ tls-cert-fp: a fingerprint of a client certificate
71 +* ☐ 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
72 +* ☐ 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.
73 +* ☐ 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.
74 +* ☐ 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.
75 +* ☑ trust: authentication always succeeds. only use in combination with netmask!!!
76 +
77 +## license
78 +
79 +parsav is released under the terms of the EUPL v1.2. copies of this license are included in the repository. dependencies are produced
80 +
81 +## future direction
15 82
16 -* libhttp: run `$ make lib/libhttp/lib/libhttp.a`
17 -* json-c (deps: `cmake`): run `$ make lib/json-c/libjson-c.a`
18 -* mbedtls: run `$ make lib/mbedtls/lib/mbed{crypto,tls,x509}.a`
83 +parsav needs more storage backends, as it currently supports only postgres. some possibilities, in order of priority, are:
19 84
20 -you can install static libraries for all dependencies with `$ make dep`, but this is recommended only if you have none of the above
85 +* plain text/filesystem storage
86 +* lmdb
87 +* sqlite3
88 +* generic odbc
89 +* lua
90 +* ldap?? possibly just for users
91 +* cdb (for static content, maybe?)
92 +* mariadb/mysql
93 +* the various nosql horrors, e.g. redis, mongo, and so on