Mercurial > prosody-modules
annotate mod_auth_token/README.markdown @ 4651:8231774f5bfd
mod_cloud_notify_encrypted: Ensure body substring remains valid UTF-8
The `body:sub()` call risks splitting the string in the middle of a
multi-byte UTF-8 sequence. This should have been caught by util.stanza
validation, but that would have caused some havoc, at the very least causing
the notification to not be sent.
There have been no reports of this happening. Likely because this module
isn't widely deployed among users with languages that use many longer UTF-8
sequences.
The util.encodings.utf8.valid() function is O(n) where only the last
sequence really needs to be checked, but it's in C and expected to be fast.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 22 Aug 2021 13:22:59 +0200 |
parents | b4bcb84997e7 |
children |
rev | line source |
---|---|
2956
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
1 # mod_auth_token |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
2 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
3 This module enables Prosody to authenticate time-based one-time-pin (TOTP) HMAC tokens. |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
4 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
5 This is an alternative to "external authentication" which avoids the need to |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
6 make a blocking HTTP call to the external authentication service (usually a web application backend). |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
7 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
8 Instead, the application generates the HMAC token, which is then sent to |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
9 Prosody via the XMPP client and Prosody verifies the authenticity of this |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
10 token. |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
11 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
12 If the token is verified, then the user is authenticated. |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
13 |
3471 | 14 ## Luarocks dependencies |
15 | |
16 You'll need to install the following luarocks | |
17 | |
18 otp 0.1-5 | |
19 luatz 0.3-1 | |
20 | |
21 ## How to generate the TOTP seed and shared signing secret | |
2956
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
22 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
23 You'll need a shared OTP_SEED value for generating time-based one-time-pin |
3471 | 24 (TOTP) values and a shared private key for signing the HMAC token. |
2956
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
25 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
26 You can generate the OTP_SEED value with Python, like so: |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
27 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
28 >>> import pyotp |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
29 >>> pyotp.random_base32() |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
30 u'XVGR73KMZH2M4XMY' |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
31 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
32 and the shared secret key as follows: |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
33 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
34 >>> import pyotp |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
35 >>> pyotp.random_base32(length=32) |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
36 u'JYXEX4IQOEYFYQ2S3MC5P4ZT4SDHYEA7' |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
37 |
3471 | 38 ## Configuration |
39 | |
40 Firest you need to enable the relevant modules to your Prosody.cfg file. | |
41 | |
42 Look for the line `modules_enabled` (either globally or for your | |
43 particular `VirtualHost`), and then add the following to tokens: | |
2956
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
44 |
3471 | 45 modules_enabled = { |
46 -- Token authentication | |
47 "auth_token"; | |
48 "sasl_token"; | |
49 } | |
50 | |
51 The previously generated token values also need to go into your Prosody.cfg file: | |
52 | |
53 authentication = "token"; | |
54 token_secret = "JYXEX4IQOEYFYQ2S3MC5P4ZT4SDHYEA7"; | |
55 otp_seed = "XVGR73KMZH2M4XMY"; | |
2956
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
56 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
57 The application that generates the tokens also needs access to these values. |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
58 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
59 For an example on how to generate a token, take a look at the `generate_token` |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
60 function in the `test_token_auth.lua` file inside this directory. |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
61 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
62 ## Custom SASL auth |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
63 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
64 This module depends on a custom SASL auth mechanism called X-TOKEN and which |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
65 is provided by the file `mod_sasl_token.lua`. |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
66 |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
67 Prosody doesn't automatically pick up this file, so you'll need to update your |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
68 configuration file's `plugin_paths` to link to this subdirectory (for example |
d0ca211e1b0e
New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff
changeset
|
69 to `/usr/lib/prosody-modules/mod_auth_token/`). |
3471 | 70 |
71 ## Generating the token | |
72 | |
73 Here's a Python snippet showing how you can generate the token that Prosody | |
74 will then verify: | |
75 | |
76 import base64 | |
77 import pyotp | |
78 import random | |
79 | |
80 # Constants | |
81 OTP_INTERVAL = 30 | |
82 OTP_DIGITS = 8 | |
83 | |
84 jid = '{}@{}'.format(username, domain) | |
85 | |
86 otp_service = pyotp.TOTP( | |
87 OTP_SEED, # OTP_SEED must be set to the value generated previously (see above) | |
88 digits=OTP_DIGITS, | |
89 interval=OTP_INTERVAL | |
90 ) | |
91 otp = otp_service.generate_otp(otp_service.timecode(datetime.utcnow())) | |
92 | |
93 nonce = ''.join([str(random.randint(0, 9)) for i in range(32)]) | |
94 string_to_sign = otp + nonce + jid | |
95 signature = hmac.new(token_secret, string_to_sign, hashlib.sha256).digest() | |
96 token = u"{} {}".format(otp+nonce, base64.b64encode(signature)) | |
97 |