diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 31 |
1 files changed, 18 insertions, 13 deletions
| @@ -10,7 +10,7 @@ It requires no additional libraries. | |||
| 10 | The main reason for writing this library was the need to login into my | 10 | The main reason for writing this library was the need to login into my |
| 11 | FreeBSD servers using [opiepasswd](https://en.wikipedia.org/wiki/OPIE_Authentication_System). | 11 | FreeBSD servers using [opiepasswd](https://en.wikipedia.org/wiki/OPIE_Authentication_System). |
| 12 | 12 | ||
| 13 | *opiepasswd* has since been removed from FreeBSD since version 14. | 13 | *opiepasswd* has meanwhile been removed from FreeBSD ( >=14). |
| 14 | 14 | ||
| 15 | I decided to license the library under the | 15 | I decided to license the library under the |
| 16 | [Simplified BSD License / 2-clause BSD license](https://codeberg.org/sgs/pyotp2289/src/branch/master/LICENSE) and not under the | 16 | [Simplified BSD License / 2-clause BSD license](https://codeberg.org/sgs/pyotp2289/src/branch/master/LICENSE) and not under the |
| @@ -120,17 +120,16 @@ RFC-2289 consists of interactions between them. | |||
| 120 | # initialization digest (hash). The password 'This is a test.' will give you | 120 | # initialization digest (hash). The password 'This is a test.' will give you |
| 121 | # the same results as in the following example. | 121 | # the same results as in the following example. |
| 122 | passwd_bytes = getpass.getpass().encode() # Fetch the password as bytes | 122 | passwd_bytes = getpass.getpass().encode() # Fetch the password as bytes |
| 123 | generator = otp2289.generator.OTPGenerator(passwd_bytes, | 123 | generator = otp2289.OTPGenerator(passwd_bytes, 'TesT', otp2289.OTP_ALGO_MD5) |
| 124 | 'TesT', | 124 | response = generator.generate_otp_response(500) # otp2289.OTPResponse |
| 125 | otp2289.OTP_ALGO_MD5) | 125 | digest = response.hexdigest |
| 126 | digest = generator.generate_otp_hexdigest(500) | ||
| 127 | # digest is now: 0x2b8d82b6ac14346c | 126 | # digest is now: 0x2b8d82b6ac14346c |
| 128 | # the client sends it to the server | 127 | # the client sends it to the server |
| 129 | 128 | ||
| 130 | # the server creates the first state. Note that step is decremented by 1: | 129 | # the server creates the first state. Note that step is decremented by 1: |
| 131 | state = otp2289.server.OTPState(digest, 499, 'TesT', otp2289.OTP_ALGO_MD5) | 130 | state = otp2289.OTPState(digest, 499, 'TesT', otp2289.OTP_ALGO_MD5) |
| 132 | # the state can be stored in a OTPStore container: | 131 | # the state can be stored in a OTPStore container: |
| 133 | store = otp2289.server.OTPStore() | 132 | store = otp2289.OTPStore() |
| 134 | # key can be any str that can be used to reference the state (f.i username) | 133 | # key can be any str that can be used to reference the state (f.i username) |
| 135 | store.add_state('myusername', state) # where key can be any str that can be | 134 | store.add_state('myusername', state) # where key can be any str that can be |
| 136 | # OTPStore is provided only for convenience as it is not part of RFC-2289. | 135 | # OTPStore is provided only for convenience as it is not part of RFC-2289. |
| @@ -145,12 +144,16 @@ RFC-2289 consists of interactions between them. | |||
| 145 | # created earlier. RFC-2289 defines two types of responses: | 144 | # created earlier. RFC-2289 defines two types of responses: |
| 146 | # - hex (like '0x2b8d82b6ac14346c') - more suited for automation | 145 | # - hex (like '0x2b8d82b6ac14346c') - more suited for automation |
| 147 | # - tokens consisting of 6 short words - better when responding manually | 146 | # - tokens consisting of 6 short words - better when responding manually |
| 148 | hex_response = generator.generate_otp_hexdigest(499) # '0x6323f96296a2526b' | 147 | # |
| 149 | token_response = generator.generate_otp_words(499) | 148 | # OTPResponse object can represent a response in both formats: |
| 149 | response = generator.generate_otp_response(499) | ||
| 150 | hex_response = response.hexdigest # '0x6323f96296a2526b' | ||
| 151 | token_response = response.words | ||
| 150 | # token_response is now: 'CANT JAW BITS NU LO PUP' | 152 | # token_response is now: 'CANT JAW BITS NU LO PUP' |
| 151 | # a possible shortcut may be to use the challenge-string directly: | 153 | # a possible shortcut may be to use the challenge-string directly: |
| 152 | hex_response = generator.generate_otp_hexdigest_from_challenge(challenge) | 154 | response = generator.generate_otp_response_from_challenge(challenge) |
| 153 | token_response = generator.generate_otp_words_from_challenge(challenge) | 155 | hex_response = response.hexdigest |
| 156 | token_response = response.words | ||
| 154 | # ... giving the same results. | 157 | # ... giving the same results. |
| 155 | 158 | ||
| 156 | # once the response is received, the server validates it by yet again using | 159 | # once the response is received, the server validates it by yet again using |
| @@ -158,9 +161,11 @@ RFC-2289 consists of interactions between them. | |||
| 158 | result = state.response_validates(hex_response) | 161 | result = state.response_validates(hex_response) |
| 159 | # or | 162 | # or |
| 160 | result = state.response_validates(token_response) | 163 | result = state.response_validates(token_response) |
| 164 | # or using the OTPResponse object directly | ||
| 165 | result = state.response_validates(response) | ||
| 161 | # result should be True if the response matches the state, False if not | 166 | # result should be True if the response matches the state, False if not |
| 162 | # in case of invalid response or response checksum doesn't match, a | 167 | # in case of invalid response or response checksum doesn't match, a |
| 163 | # otp2289.server.OTPInvalidResponse exception is raised. | 168 | # otp2289.OTPInvalidResponse exception is raised. |
| 164 | 169 | ||
| 165 | # once the state has successfully validated the corresponding response, | 170 | # once the state has successfully validated the corresponding response, |
| 166 | # the state **must never be used again** and a state corresponding to the | 171 | # the state **must never be used again** and a state corresponding to the |
| @@ -170,7 +175,7 @@ RFC-2289 consists of interactions between them. | |||
| 170 | # the next authentication attempt... | 175 | # the next authentication attempt... |
| 171 | challenge = state.challenge_string # challenge is now 'otp-md5 498 TesT ' | 176 | challenge = state.challenge_string # challenge is now 'otp-md5 498 TesT ' |
| 172 | # ... and on the client side... | 177 | # ... and on the client side... |
| 173 | hex_response = generator.generate_otp_hexdigest_from_challenge(challenge) | 178 | response = generator.generate_otp_response_from_challenge(challenge) |
| 174 | # etc. etc... | 179 | # etc. etc... |
| 175 | ``` | 180 | ``` |
| 176 | 181 | ||
