Skip to content

Commit eaf9d89

Browse files
author
Serghey Rodin
committed
Auth fix 0.9.8-20
1 parent 1034d1b commit eaf9d89

File tree

6 files changed

+382
-63
lines changed

6 files changed

+382
-63
lines changed

bin/v-check-api-key

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
# info: check api key
3+
# options: KEY
4+
#
5+
# The function checks a key file in /usr/local/vesta/data/keys/
6+
7+
8+
#----------------------------------------------------------#
9+
# Variable&Function #
10+
#----------------------------------------------------------#
11+
12+
if [ -z "$1" ]; then
13+
echo "Error: key missmatch"
14+
exit 9
15+
fi
16+
key=$(basename $1)
17+
ip=${2-127.0.0.1}
18+
time_n_date=$(date +'%T %F')
19+
time=$(echo "$time_n_date" |cut -f 1 -d \ )
20+
date=$(echo "$time_n_date" |cut -f 2 -d \ )
21+
22+
23+
#----------------------------------------------------------#
24+
# Action #
25+
#----------------------------------------------------------#
26+
27+
if [ ! -e $VESTA/data/keys/$key ]; then
28+
echo "Error: key missmatch"
29+
echo "$date $time api $ip failed to login" >> $VESTA/log/auth.log
30+
exit 9
31+
fi
32+
33+
34+
#----------------------------------------------------------#
35+
# Vesta #
36+
#----------------------------------------------------------#
37+
38+
echo "$date $time api $ip successfully launched" >> $VESTA/log/auth.log
39+
40+
exit

bin/v-check-user-hash

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/bin/bash
2+
# info: check user hash
3+
# options: USER HASH [IP]
4+
#
5+
# The function verifies user hash
6+
7+
8+
#----------------------------------------------------------#
9+
# Variable&Function #
10+
#----------------------------------------------------------#
11+
12+
# Argument definition
13+
user=$1
14+
hash=$2; HIDE=2
15+
ip=${3-127.0.0.1}
16+
17+
# Includes
18+
source $VESTA/func/main.sh
19+
source $VESTA/conf/vesta.conf
20+
21+
time_n_date=$(date +'%T %F')
22+
time=$(echo "$time_n_date" |cut -f 1 -d \ )
23+
date=$(echo "$time_n_date" |cut -f 2 -d \ )
24+
25+
26+
#----------------------------------------------------------#
27+
# Verifications #
28+
#----------------------------------------------------------#
29+
30+
31+
check_args '2' "$#" 'USER HASH'
32+
is_format_valid 'user'
33+
34+
# Checking user
35+
if [ ! -d "$VESTA/data/users/$user" ] && [ "$user" != 'root' ]; then
36+
echo "Error: password missmatch"
37+
echo "$date $time $user $ip failed to login" >> $VESTA/log/auth.log
38+
exit 9
39+
fi
40+
41+
# Checking user hash
42+
is_hash_valid
43+
44+
# Checking empty hash
45+
if [[ -z "$hash" ]]; then
46+
echo "Error: password missmatch"
47+
echo "$date $time $user $ip failed to login" >> $VESTA/log/auth.log
48+
exit 9
49+
fi
50+
51+
52+
#----------------------------------------------------------#
53+
# Action #
54+
#----------------------------------------------------------#
55+
56+
57+
# Parsing user's salt
58+
shadow=$(grep "^$user:" /etc/shadow | cut -f 2 -d :)
59+
60+
if echo "$shadow" | grep -qE '^\$[0-9a-z]+\$[^\$]+\$'
61+
then
62+
salt=$(echo "$shadow" |cut -f 3 -d \$)
63+
method=$(echo "$shadow" |cut -f 2 -d \$)
64+
if [ "$method" -eq '1' ]; then
65+
method='md5'
66+
elif [ "$method" -eq '6' ]; then
67+
method='sha-512'
68+
else
69+
echo "Error: password missmatch"
70+
echo "$date $time $user $ip failed to login" >> $VESTA/log/auth.log
71+
exit 9
72+
fi
73+
else
74+
salt=${shadow:0:2}
75+
method='des'
76+
fi
77+
78+
if [ -z "$salt" ]; then
79+
echo "Error: password missmatch"
80+
echo "$date $time $user $ip failed to login" >> $VESTA/log/auth.log
81+
exit 9
82+
fi
83+
84+
# Checking hash
85+
result=$(grep "^$user:$hash:" /etc/shadow 2>/dev/null)
86+
if [[ -z "$result" ]]; then
87+
echo "Error: password missmatch"
88+
echo "$date $time $user $ip failed to login" >> $VESTA/log/auth.log
89+
exit 9
90+
fi
91+
92+
93+
#----------------------------------------------------------#
94+
# Vesta #
95+
#----------------------------------------------------------#
96+
97+
# Logging
98+
echo "$date $time $user $ip successfully logged in" >> $VESTA/log/auth.log
99+
100+
exit

bin/v-get-user-salt

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/bin/bash
2+
# info: get user salt
3+
# options: USER [IP] [FORMAT]
4+
#
5+
# The function provides users salt
6+
7+
8+
#----------------------------------------------------------#
9+
# Variable&Function #
10+
#----------------------------------------------------------#
11+
12+
# Argument definition
13+
user=$1
14+
ip=${2-127.0.0.1}
15+
format=${3-shell}
16+
17+
# Includes
18+
source $VESTA/func/main.sh
19+
source $VESTA/conf/vesta.conf
20+
21+
time_n_date=$(date +'%T %F')
22+
time=$(echo "$time_n_date" |cut -f 1 -d \ )
23+
date=$(echo "$time_n_date" |cut -f 2 -d \ )
24+
25+
# JSON list function
26+
json_list() {
27+
echo '{'
28+
echo ' "'$user'": {
29+
"METHOD": "'$method'",
30+
"SALT": "'$salt'",
31+
"TIME": "'$time'",
32+
"DATE": "'$date'"
33+
}'
34+
echo '}'
35+
}
36+
37+
# SHELL list function
38+
shell_list() {
39+
echo "METHOD: $method"
40+
echo "SALT: $salt"
41+
}
42+
43+
# PLAIN list function
44+
plain_list() {
45+
echo -e "$method\t$salt"
46+
}
47+
48+
# CSV list function
49+
csv_list() {
50+
echo "METHOD,SALT"
51+
echo "$method, $salt"
52+
}
53+
54+
55+
#----------------------------------------------------------#
56+
# Verifications #
57+
#----------------------------------------------------------#
58+
59+
60+
check_args '1' "$#" 'USER [IP] [SALT]'
61+
is_format_valid 'user'
62+
63+
# Checking user
64+
if [ ! -d "$VESTA/data/users/$user" ] && [ "$user" != 'root' ]; then
65+
echo "Error: password missmatch"
66+
echo "$date $time $user $ip failed to login" >> $VESTA/log/auth.log
67+
exit 9
68+
fi
69+
70+
71+
#----------------------------------------------------------#
72+
# Action #
73+
#----------------------------------------------------------#
74+
75+
# Parsing user's salt
76+
shadow=$(grep "^$user:" /etc/shadow | cut -f 2 -d :)
77+
78+
if echo "$shadow" | grep -qE '^\$[0-9a-z]+\$[^\$]+\$'
79+
then
80+
salt=$(echo "$shadow" |cut -f 3 -d \$)
81+
method=$(echo "$shadow" |cut -f 2 -d \$)
82+
if [ "$method" -eq '1' ]; then
83+
method='md5'
84+
elif [ "$method" -eq '6' ]; then
85+
method='sha-512'
86+
else
87+
echo "Error: password missmatch"
88+
echo "$date $time $user $ip failed to login" >> $VESTA/log/auth.log
89+
exit 9
90+
fi
91+
else
92+
salt=${shadow:0:2}
93+
method='des'
94+
fi
95+
96+
if [ -z "$salt" ]; then
97+
echo "Error: password missmatch"
98+
echo "$date $time $user $ip failed to login" >> $VESTA/log/auth.log
99+
exit 9
100+
fi
101+
102+
103+
# Listing data
104+
case $format in
105+
json) json_list ;;
106+
plain) plain_list ;;
107+
csv) csv_list ;;
108+
shell) shell_list ;;
109+
esac
110+
111+
112+
#----------------------------------------------------------#
113+
# Vesta #
114+
#----------------------------------------------------------#
115+
116+
# Logging
117+
118+
exit

func/main.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,15 @@ is_password_valid() {
278278
fi
279279
}
280280

281+
# Check if hash is transmitted via file
282+
is_hash_valid() {
283+
if [[ "$hash" =~ ^/tmp/ ]]; then
284+
if [ -f "$hash" ]; then
285+
hash="$(head -n1 $hash)"
286+
fi
287+
fi
288+
}
289+
281290
# Get object value
282291
get_object_value() {
283292
object=$(grep "$2='$3'" $USER_DATA/$1.conf)

web/api/index.php

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,64 @@
44
if (isset($_POST['user']) || isset($_POST['hash'])) {
55

66
// Authentication
7-
$auth_code = 1;
87
if (empty($_POST['hash'])) {
9-
// Check user permission to use API
108
if ($_POST['user'] != 'admin') {
11-
echo 'Error: only admin is allowed to use API';
9+
echo 'Error: authentication failed';
1210
exit;
1311
}
1412

15-
$v_user = escapeshellarg($_POST['user']);
16-
$v_password = tempnam("/tmp","vst");
17-
$fp = fopen($v_password, "w");
18-
fwrite($fp, $_POST['password']."\n");
13+
$password = $_POST['password'];
14+
$v_ip = escapeshellarg($_SERVER['REMOTE_ADDR']);
15+
$output = '';
16+
exec (VESTA_CMD."v-get-user-salt admin ".$v_ip." json" , $output, $return_var);
17+
$pam = json_decode(implode('', $output), true);
18+
$salt = $pam['admin']['SALT'];
19+
$method = $pam['admin']['METHOD'];
20+
21+
if ($method == 'md5' ) {
22+
$hash = crypt($password, '$1$'.$salt.'$');
23+
}
24+
if ($method == 'sha-512' ) {
25+
$hash = crypt($password, '$6$rounds=5000$'.$salt.'$');
26+
$hash = str_replace('$rounds=5000','',$hash);
27+
}
28+
if ($method == 'des' ) {
29+
$hash = crypt($password, $salt);
30+
}
31+
32+
// Send hash via tmp file
33+
$v_hash = exec('mktemp -p /tmp');
34+
$fp = fopen($v_hash, "w");
35+
fwrite($fp, $hash."\n");
1936
fclose($fp);
20-
$v_ip_addr = escapeshellarg($_SERVER["REMOTE_ADDR"]);
21-
exec(VESTA_CMD ."v-check-user-password ".$v_user." ".escapeshellarg($v_password)." '".$v_ip_addr."'", $output, $auth_code);
22-
unlink($v_password);
23-
/* No hash auth for security reason
37+
38+
// Check user hash
39+
exec(VESTA_CMD ."v-check-user-hash admin ".$v_hash." ".$v_ip, $output, $return_var);
40+
unset($output);
41+
42+
// Remove tmp file
43+
unlink($v_hash);
44+
45+
// Check API answer
46+
if ( $return_var > 0 ) {
47+
echo 'Error: authentication failed';
48+
exit;
49+
}
2450
} else {
2551
$key = '/usr/local/vesta/data/keys/' . basename($_POST['hash']);
2652
if (file_exists($key) && is_file($key)) {
27-
$auth_code = '0';
53+
exec(VESTA_CMD ."v-check-api-key ".escapeshellarg($key)." ".$v_ip, $output, $return_var);
54+
unset($output);
55+
56+
// Check API answer
57+
if ( $return_var > 0 ) {
58+
echo 'Error: authentication failed';
59+
exit;
60+
}
2861
}
29-
*/
3062
}
3163

32-
if ($auth_code != 0 ) {
64+
if ( $return_var > 0 ) {
3365
echo 'Error: authentication failed';
3466
exit;
3567
}

0 commit comments

Comments
 (0)