mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-11-29 22:08:10 +02:00
75 lines
3.6 KiB
Markdown
75 lines
3.6 KiB
Markdown
|
|
# Keyboard Interactive Authentication
|
||
|
|
|
||
|
|
Keyboard interactive authentication is, in general, a series of questions asked by the server with responses provided by the client.
|
||
|
|
This authentication method is typically used for multi-factor authentication.
|
||
|
|
There are no restrictions on the number of questions asked on a particular authentication stage; there are also no restrictions on the number of stages involving different sets of questions.
|
||
|
|
|
||
|
|
To enable keyboard interactive authentication, you must set the absolute path of your authentication program using the `keyboard_interactive_auth_program` key in your configuration file.
|
||
|
|
|
||
|
|
The external program can read the following environment variables to get info about the user trying to authenticate:
|
||
|
|
|
||
|
|
- `SFTPGO_AUTHD_USERNAME`
|
||
|
|
- `SFTPGO_AUTHD_PASSWORD`, this is the hashed password as stored inside the data provider
|
||
|
|
|
||
|
|
Previous global environment variables aren't cleared when the script is called. The content of these variables is _not_ quoted. They may contain special characters.
|
||
|
|
|
||
|
|
The program must write the questions on its standard output, in a single line, using the following struct JSON serialized:
|
||
|
|
|
||
|
|
- `instruction`, string. A short description to show to the user that is trying to authenticate. Can be empty or omitted
|
||
|
|
- `questions`, list of questions to be asked to the user
|
||
|
|
- `echos` list of boolean flags corresponding to the questions (so the lengths of both lists must be the same) and indicating whether user's reply for a particular question should be echoed on the screen while they are typing: true if it should be echoed, or false if it should be hidden.
|
||
|
|
- `check_password` optional integer. Ask exactly one question and set this field to 1 if the expected answer is the user password and you want SFTPGo to check it for you. If the password is correct, the returned response to the program is `OK`. If the password is wrong, the program will be terminated and an authentication error will be returned to the user that is trying to authenticate.
|
||
|
|
- `auth_result`, integer. Set this field to 1 to indicate successful authentication. 0 is ignored. Any other value means authentication error. If this field is found and it is different from 0 then SFTPGo will not read any other questions from the external program, and it will finalize the authentication.
|
||
|
|
|
||
|
|
SFTPGo writes the user answers to the program standard input, one per line, in the same order as the questions.
|
||
|
|
Please be sure that your program receives the answers for all the issued questions before asking for the next ones.
|
||
|
|
|
||
|
|
Keyboard interactive authentication can be chained to the external authentication.
|
||
|
|
The authentication must finish within 60 seconds.
|
||
|
|
|
||
|
|
Let's see a very basic example. Our sample keyboard interactive authentication program will ask for 2 sets of questions and accept the user if the answer to the last question is `answer3`.
|
||
|
|
|
||
|
|
```
|
||
|
|
#!/bin/sh
|
||
|
|
|
||
|
|
echo '{"questions":["Question1: ","Question2: "],"instruction":"This is a sample for keyboard interactive authentication","echos":[true,false]}'
|
||
|
|
|
||
|
|
read ANSWER1
|
||
|
|
read ANSWER2
|
||
|
|
|
||
|
|
echo '{"questions":["Question3: "],"instruction":"","echos":[true]}'
|
||
|
|
|
||
|
|
read ANSWER3
|
||
|
|
|
||
|
|
if test "$ANSWER3" = "answer3"; then
|
||
|
|
echo '{"auth_result":1}'
|
||
|
|
else
|
||
|
|
echo '{"auth_result":-1}'
|
||
|
|
fi
|
||
|
|
```
|
||
|
|
|
||
|
|
and here is an example where SFTPGo checks the user password for you:
|
||
|
|
|
||
|
|
```
|
||
|
|
#!/bin/sh
|
||
|
|
|
||
|
|
echo '{"questions":["Password: "],"instruction":"This is a sample for keyboard interactive authentication","echos":[false],"check_password":1}'
|
||
|
|
|
||
|
|
read ANSWER1
|
||
|
|
|
||
|
|
if test "$ANSWER1" != "OK"; then
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo '{"questions":["One time token: "],"instruction":"","echos":[false]}'
|
||
|
|
|
||
|
|
read ANSWER2
|
||
|
|
|
||
|
|
if test "$ANSWER2" = "token"; then
|
||
|
|
echo '{"auth_result":1}'
|
||
|
|
else
|
||
|
|
echo '{"auth_result":-1}'
|
||
|
|
fi
|
||
|
|
```
|
||
|
|
|