... | ... | @@ -727,7 +727,84 @@ of the email into `/srv/db.torproject.org/mail-logs/`, for example: |
|
|
"| /usr/bin/ud-mailgate change"
|
|
|
/srv/db.torproject.org/mail-logs/received.changes
|
|
|
|
|
|
TODO: walk through `ud-mailgate`.
|
|
|
This is how `ud-mailgate` processes incoming messages:
|
|
|
|
|
|
1. it parses the email from stdin using Python's `email.parser`
|
|
|
library
|
|
|
|
|
|
2. it tries to find an OpenPGP-signed message and passes it to the
|
|
|
`GPGCheckSig` function to verify the signature against the trusted
|
|
|
keyring
|
|
|
|
|
|
3. it does a check against replay attacks by checking:
|
|
|
|
|
|
* if the OpenPGP signature timestamp is reasonable (less than 3
|
|
|
days in the future, or 4 days in the past)
|
|
|
|
|
|
* if the signature has already been received in the last 7 days
|
|
|
|
|
|
The `ReplayCache` is a [dbm](https://docs.python.org/3/library/dbm.html) database stored in
|
|
|
`/var/cache/userdir-ldap/mail/replay`.
|
|
|
|
|
|
4. it then behaves differently whether it was called with `ping`,
|
|
|
`chpass` or `change` as its argument
|
|
|
|
|
|
5. in any case it tries to send a reply to the user by email,
|
|
|
encrypted in the case of `chpass`
|
|
|
|
|
|
The `ping` routine just responds to the user with their LDAP entry,
|
|
|
rendered according to the `ping-reply` template (in
|
|
|
`/etc/userdir-ldap/templates`).
|
|
|
|
|
|
The `chpass` routine behaves differently depending on a magic string
|
|
|
in the signed message, which can either be:
|
|
|
|
|
|
1. "Please change my Debian password"
|
|
|
2. "Please change my Tor password"
|
|
|
3. "Please change my Kerberos password"
|
|
|
4. "Please change my TOTP seed"
|
|
|
|
|
|
The first two do the same thing. The latter two are not in use at
|
|
|
TPO. The main `chpass` routine basically does this:
|
|
|
|
|
|
1. generate a 15-character random string
|
|
|
2. "hash" it with Python's [crypt](https://docs.python.org/3/library/crypt.html) with a MD5 (!) salt
|
|
|
4. set the hashed password in the user's LDAP object, `userPassword`
|
|
|
field
|
|
|
5. bump the `shadowLastChange` field in the user's LDAP object
|
|
|
6. render the `passwd-changed` email template which will include an
|
|
|
OpenPGP encrypted copy of the cleartext email
|
|
|
|
|
|
The `change` routine does one or many of the following, depending on
|
|
|
the lines in the signed message:
|
|
|
|
|
|
* on `show`: send a `key: value` list of parameters of the user's
|
|
|
LDAP object, OpenPGP-encrypted
|
|
|
* change the user's "position marker" (latitude/longitude) with a
|
|
|
format like `Lat: -10.0 Long: +10.0`
|
|
|
* add or replace a `dnsZoneEntry` if the line looks like `host IN
|
|
|
{A,AAAA,CNAME,MX,TXT}`
|
|
|
* replace LDAP user object fields if the line looks like `field:
|
|
|
value`. only some fields are supported
|
|
|
* add or replace `sshRSAAuthKey` lines when the line looks like an
|
|
|
SSH key (note that this routine sends its error email
|
|
|
separately). this gets massaged so that it matches the format
|
|
|
expected by `ud-generate` in LDAP and is validated by piping in
|
|
|
`ssh-keygen -l -f`. the `allowed_hosts` block is checked against
|
|
|
the existing list of servers and it enforces a minimum RSA key size
|
|
|
(2048 bits)
|
|
|
* delete an LDAP user field, when provided with a line that looks
|
|
|
like `del FIELD`
|
|
|
* add or replace `mailrbl`, `mailrhsbl` and `mailwhiltelist` fields,
|
|
|
except allow a space separator instead of the normal colon
|
|
|
separator for arbitrary fields (??)
|
|
|
* if the sudo password is changed, it checks if the HMAC provided
|
|
|
matches the expected one from the database and switched from
|
|
|
`unconfirmed` to `confirmed`
|
|
|
|
|
|
Note that the `change` routine only operates if the account is not
|
|
|
locked (if the `userPassword` does not contain the string `*LK*` or
|
|
|
starts with the `!` string).
|
|
|
|
|
|
### Interactions with Puppet
|
|
|
|
... | ... | |