Skip to content
This repository was archived by the owner on May 9, 2018. It is now read-only.

Commit 6e5ff18

Browse files
committed
Merge remote-tracking branch 'upstream/master'
Conflicts: README.md authy-ssh authy-ssh.sha1sum tests/test_protect.rb
2 parents 28ecd12 + 2d0897a commit 6e5ff18

7 files changed

Lines changed: 135 additions & 48 deletions

File tree

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Copyright (c) 2014 Authy, Inc.
2+
3+
Permission is hereby granted, free of charge, to any person
4+
obtaining a copy of this software and associated documentation
5+
files (the "Software"), to deal in the Software without
6+
restriction, including without limitation the rights to use,
7+
copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the
9+
Software is furnished to do so, subject to the following
10+
conditions:
11+
12+
The above copyright notice and this permission notice shall be
13+
included in all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Type the following command in the terminal:
1010

11-
$ curl -O 'https://raw.githubusercontent.com/authy/authy-ssh/master/authy-ssh'
11+
$ curl -O 'https://raw.githubusercontent.com/DigitalDJ/authy-ssh/master/authy-ssh'
1212
$ sudo bash authy-ssh install /usr/local/bin
1313

1414
Then enable two-factor for your user:
@@ -31,7 +31,7 @@ Restart your SSH server (look below if you are not on Ubuntu).
3131

3232
**Debian**
3333

34-
sudo /etc/init.d/sshd restart
34+
sudo service sshd restart
3535

3636
**RedHat and Fedora Core Linux**
3737

@@ -45,7 +45,7 @@ Restart your SSH server (look below if you are not on Ubuntu).
4545

4646
Type the following command in the terminal:
4747

48-
$ curl 'https://raw.github.com/authy/authy-ssh/master/authy-ssh' -o authy-ssh
48+
$ curl 'https://raw.githubusercontent.com/DigitalDJ/authy-ssh/master/authy-ssh' -o authy-ssh
4949
$ bash authy-ssh install ~/.authy-ssh/
5050

5151

@@ -54,6 +54,19 @@ Now protect your user:
5454
$ bash ~/.authy-ssh/authy-ssh protect
5555

5656

57+
## Enable two-factor auth on a user.
58+
59+
After the installation is finished, you have to proactively enable the two-factor for the users you want to protect.
60+
61+
To enable users type the following command and fill the form:
62+
63+
$ sudo authy-ssh enable
64+
65+
If you want to do it in one line just type:
66+
67+
$ sudo authy-ssh enable <local-username> <user-email> <user-cellphone-country-code> <user-cellphone> [grace-period]
68+
69+
5770
## How it works
5871

5972
Authy-ssh uses the `sshd_config` directive `ForceCommand` to run itself before every login. Here's how your sshd_config will look after installing:
@@ -71,11 +84,10 @@ Here's an example:
7184
user=root:1:-1
7285
user=daniel:1:300
7386

74-
In this case it means user root and daniel have two-factor enabled and that 1 is their `authy_id`. If a user is not in this list, `authy-ssh` will automatically let him in.
87+
In this case it means user root and daniel have two-factor enabled and that 1 is their `authy_id`. If a user is not in this list, `authy-ssh` will automatically let him in.
7588
The user daniel has an optional `grace-period` of 300 seconds, allowing them to open a new session within 5 minutes of the last successful login without requiring two-factor authentication.
7689
On the other hand, the root user uses the default `grace-period` of -1, requiring all sessions to use two-factor authentication, regardless of recent successful logins.
7790

78-
7991
The `load_default_banner` option will show the operating system's default SSH banner when a successful login occurs. This checks to see if a MOTD is set in /etc/pam.d/sshd or /etc/motd.
8092
Setting this to disable will suppress the default sshd MOTD.
8193

@@ -103,20 +115,9 @@ Now that my root user is in the two-factor group, I edit my /etc/ssh/sshd_config
103115
Now force command will only operate on users that belong to the two-factor group.
104116

105117

106-
## Enable two-factor auth on a user.
107-
108-
To enable users type the following command and fill the form:
109-
110-
$ sudo authy-ssh enable
111-
112-
If you want to do it in one line just type:
113-
114-
$ sudo authy-ssh enable <local-username> <user-email> <user-cellphone-country-code> <user-cellphone> [grace-period]
118+
## `scp`, `sftp`, `mosh` and `git push` with two-factor authentication.
115119

116-
117-
## `scp`, `mosh` and `git push` with two-factor authentication.
118-
119-
To enable non-interactive commands like `scp`, `mosh` and `git clone|fetch|push` you have to allow to pass the environment variable `AUTHY_TOKEN` from the client. To do so edit your `sshd_config` (normally located at `/etc` or `/etc/ssh/`) and add `AUTHY_TOKEN` to the AcceptEnv directive:
120+
To enable non-interactive commands like `scp`, `sftp`, `mosh` and `git clone|fetch|push` you have to allow to pass the environment variable `AUTHY_TOKEN` from the client. To do so edit your `sshd_config` (normally located at `/etc` or `/etc/ssh/`) and add `AUTHY_TOKEN` to the AcceptEnv directive:
120121

121122
AcceptEnv AUTHY_TOKEN
122123

@@ -131,6 +132,9 @@ And finally pass the token before the command:
131132
AUTHY_TOKEN="valid-token" scp server:path/to/file local-file
132133
AUTHY_TOKEN="valid-token" mosh server
133134

135+
### Note
136+
137+
For cases like `sftp` if you enter an invalid token, you may receive a response like *"Received message too long 458961713"*. This is because the interactive command is not able to render the proper output text message returned by the program.
134138

135139
## Multiple users sharing the same unix account.
136140

@@ -158,4 +162,10 @@ To uninstall type:
158162
$ sudo authy-ssh uninstall
159163
$ restart your SSH server
160164

161-
165+
166+
## Running Unit Tests
167+
168+
Fork and clone the git repository https://github.com/DigitalDJ/authy-ssh.git
169+
170+
$ cd tests
171+
$ rake test

authy-ssh

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
#!/usr/bin/env bash
22

3-
VERSION="1.6.1"
3+
VERSION="1.7.1"
44
AUTHY_URL="https://api.authy.com"
55
APP_ROOT=`dirname $0`
66
CONFIG_FILE="$APP_ROOT/authy-ssh.conf"
77
LAST_LOGIN_FOLDER="$HOME/.authy-ssh/"
88
LAST_LOGIN_FILE="$LAST_LOGIN_FOLDER/last-login"
9-
UPSTREAM_URL="https://raw.github.com/authy/authy-ssh/master/authy-ssh"
9+
UPSTREAM_URL="https://raw.githubusercontent.com/DigitalDJ/authy-ssh/master/authy-ssh"
1010
READ_TIMEOUT=60
11+
MIN_API_KEY_SIZE=12
1112

1213
OK=0
1314
FAIL=1
15+
SEQ="seq"
1416

1517
export TERM="xterm-256color"
1618
NORMAL=$(tput sgr0)
1719
GREEN=$(tput setaf 2; tput bold)
1820
YELLOW=$(tput setaf 3)
1921
RED=$(tput setaf 1)
2022

23+
2124
function red() {
2225
echo -e "$RED$*$NORMAL"
2326
}
@@ -37,6 +40,19 @@ function debug() {
3740
fi
3841
}
3942

43+
function check_dependencies() {
44+
if ! type "seq" > /dev/null 2>&1;
45+
then
46+
if ! type "jot" > /dev/null 2>&1;
47+
then
48+
red "You need installed on your system either 'seq' or 'jot' command"
49+
exit $FAIL
50+
else
51+
SEQ="jot"
52+
fi
53+
fi
54+
}
55+
4056
function escape_input() {
4157
sed "s/[;\`\"\$\' ]//g" <<<$*
4258
}
@@ -45,6 +61,10 @@ function escape_number() {
4561
sed 's/^-?[0-9]*//g' <<< $*
4662
}
4763

64+
function os_version() {
65+
echo `uname -srm`
66+
}
67+
4868
function read_input() {
4969
read -t "$READ_TIMEOUT" input
5070
echo "$(escape_input $input)"
@@ -93,14 +113,19 @@ function require_curl() {
93113
return $FAIL
94114
}
95115

116+
function user_agent() {
117+
os="$(os_version)"
118+
echo "User-Agent: AuthySSH/${VERSION} (${os})"
119+
}
120+
96121
function find_sshd_config() {
97122
debug "Trying to find sshd_config file"
98123
if [[ -f /etc/sshd_config ]]
99124
then
100125
SSHD_CONFIG="/etc/sshd_config"
101126
elif [[ -f /etc/ssh/sshd_config ]]
102127
then
103-
SSHD_CONFIG="/etc/ssh/sshd_config"
128+
SSHD_CONFIG="/etc/ssh/sshd_config"
104129
fi
105130
}
106131

@@ -167,7 +192,7 @@ function install_authy() {
167192
echo -n "Enter the Authy API key: "
168193
read authy_api_key
169194

170-
if [ ${#authy_api_key} != 32 ]
195+
if [ ${#authy_api_key} -lt ${MIN_API_KEY_SIZE} ]
171196
then
172197
red "you have entered a wrong API key"
173198
return $FAIL
@@ -306,7 +331,7 @@ function check_config_file() {
306331
# - anything else: exits the command
307332
function check_api_key() {
308333
debug "Checking api key"
309-
if [[ "${#AUTHY_API_KEY}" != 32 ]]
334+
if [ ${#AUTHY_API_KEY} -lt ${MIN_API_KEY_SIZE} ]
310335
then
311336
red "Cannot find a valid api key"
312337
run_shell
@@ -513,7 +538,8 @@ function register_user_on_authy() {
513538
return $FAIL
514539
fi
515540

516-
response=`curl --connect-timeout 10 "${url}" -d user[email]="${email}" -d user[country_code]="${country_code}" -d user[cellphone]="${cellphone}" -s 2>/dev/null`
541+
useragent="$(user_agent)"
542+
response=`curl --connect-timeout 10 "${url}" -A "${useragent}" -d user[email]="${email}" -d user[country_code]="${country_code}" -d user[cellphone]="${cellphone}" -s 2>/dev/null`
517543
ok=true
518544

519545
debug "[register-user] url: $url | response: $response | curl exit stats: $?"
@@ -621,8 +647,17 @@ function login() {
621647
return $FAIL
622648
fi
623649

650+
size=${#authy_token}
651+
if [[ $size -lt 6 || $size -gt 10 ]]
652+
then
653+
red "You have to enter a valid token."
654+
return $FAIL
655+
fi
656+
657+
useragent="$(user_agent)"
624658
url="$AUTHY_URL/protected/json/verify/${authy_token}/${authy_id}?api_key=${AUTHY_API_KEY}&force=true"
625-
response=`curl --connect-timeout 30 -sL -w "|%{http_code}" "${url}"`
659+
660+
response=`curl --connect-timeout 30 -sL -w "|%{http_code}" -A "${useragent}" "${url}"`
626661
curl_exit_code=$?
627662
IFS='|' response_body=($response) # convert to array
628663

@@ -637,7 +672,7 @@ function login() {
637672
if [[ $default_verify_action == "disable" ]]
638673
then
639674
debug "Checking if authy service is up."
640-
check_response=`curl --connect-timeout 10 -s "${AUTHY_URL}" -o /dev/null`
675+
check_response=`curl --connect-timeout 10 -s "${AUTHY_URL}" -A "${useragent}" -o /dev/null`
641676
check_exit_code=$?
642677

643678
if [[ $check_exit_code == 7 || $check_exit_code == 28 ]]
@@ -647,10 +682,10 @@ function login() {
647682
fi
648683
fi
649684

650-
if [[ "${response_body[1]}" == "200" ]] && [[ "${response_body[0]}" == *\"success\":\"true\"* ]]
685+
if [[ "${response_body[1]}" == "200" ]] && [[ "${response_body[0]}" == *\"token\":\"is*valid\"* ]]
651686
then
652687
debug "Two-factor token was accepted."
653-
if [[ "$AUTHY_TOKEN" == "" ]]
688+
if [[ ! $AUTHY_TOKEN ]]
654689
then
655690
banner_text=$(read_config banner)
656691
if [[ $? == $OK ]];
@@ -679,7 +714,8 @@ function request_sms() {
679714
authy_id="$(escape_number $1)"
680715
url="$AUTHY_URL/protected/json/sms/${authy_id}?api_key=${AUTHY_API_KEY}&force=true"
681716

682-
response=`curl --connect-timeout 10 "${url}" 2>/dev/null`
717+
useragent="$(user_agent)"
718+
response=`curl --connect-timeout 10 -A "${useragent}" "${url}" 2>/dev/null`
683719
debug "[request sms] url: $url | response: $response | curl exit stats: $?"
684720

685721
if [[ $response == *success*"was sent"* ]]
@@ -724,15 +760,15 @@ function ask_token_and_log_user_in() {
724760
update_last_login
725761
run_shell
726762
fi
727-
763+
728764
times=3
729765
if [[ $AUTHY_TOKEN ]] # env var
730766
then
731767
times=1
732768
fi
733-
769+
734770
unset IFS
735-
for i in `seq 1 $times`
771+
for i in `$SEQ 1 $times`
736772
do
737773
authy_token="$(escape_number $AUTHY_TOKEN)"
738774
if [[ ! $AUTHY_TOKEN ]]
@@ -760,7 +796,7 @@ function ask_token_and_log_user_in() {
760796
}
761797

762798
function update_authy() {
763-
temp_file="$(mktemp)"
799+
temp_file="$(mktemp -t tmpXXXXXXXXX)"
764800
curl "${UPSTREAM_URL}" -o "$temp_file"
765801
chmod 755 "$temp_file"
766802

@@ -785,9 +821,11 @@ cd - >/dev/null
785821

786822
case $1 in
787823
install)
824+
check_dependencies
788825
install_authy "$0" "$2"
789826
;;
790827
update)
828+
check_dependencies
791829
require_root
792830
update_authy
793831
;;
@@ -797,11 +835,13 @@ case $1 in
797835
;;
798836
test|check)
799837
check_config_file
838+
check_dependencies
800839
AUTHY_API_KEY="$(read_config api_key)"
801840
check_api_key || exit
802841
ask_token_and_log_user_in "test"
803842
;;
804843
enable|register)
844+
check_dependencies
805845
require_root
806846
check_config_file "writable"
807847
AUTHY_API_KEY="$(read_config api_key)"
@@ -810,12 +850,14 @@ case $1 in
810850
;;
811851
login)
812852
check_config_file
853+
check_dependencies
813854
AUTHY_API_KEY="$(read_config api_key)"
814855
check_api_key
815856
ask_token_and_log_user_in "login" "$2" "$3"
816857
;;
817858
protect)
818859
check_config_file
860+
check_dependencies
819861
AUTHY_API_KEY="$(read_config api_key)"
820862
protect_user "$2"
821863
;;

authy-ssh.sha1sum

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9aac50642fe69aeb65a5c03b5088d1a82edc3885 authy-ssh
1+
2323b34ac668deadb3aaf86ab14542303d351580 authy-ssh

tests/test_enable.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@
4545
stdin.puts "y"
4646
end
4747

48-
if read_until(stdout, /0 is not a valid country code/i)
49-
print "Sending an invalid country code: 0"
48+
if read_until(stdout, /country_code":"is invalid/i)
5049
green " [OK]"
5150
else
51+
5252
red " [FAILED]"
5353
end
5454
end

0 commit comments

Comments
 (0)