1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
From 33feceb1573cbb6ba7fb326bb7872de75bca6b9e Mon Sep 17 00:00:00 2001
From: mancha <mancha1 AT zoho DOT com>
Date: Wed, 18 Feb 2015
Subject: Fix account validation with glibc crypt
Starting with glibc 2.17, crypt() can return NULL which can cause
xrdp-sesman to segfault. This patch backports upstream's fix for
this as well as changes auth_userpass so it can validate SHA-256
and SHA-512 hashed passwords.
---
sesman/verify_user.c | 87 ++++++++++++++++-------------------------
1 file changed, 35 insertions(+), 52 deletions(-)
--- a/sesman/verify_user.c
+++ b/sesman/verify_user.c
@@ -51,64 +51,47 @@ auth_account_disabled(struct spwd* stp);
long DEFAULT_CC
auth_userpass(char* user, char* pass)
{
- char salt[13] = "$1$";
- char hash[35] = "";
- char* encr = 0;
- struct passwd* spw;
- struct spwd* stp;
- int saltcnt = 0;
-
- spw = getpwnam(user);
- if (spw == 0)
- {
- return 0;
- }
- if (g_strncmp(spw->pw_passwd, "x", 3) == 0)
- {
- /* the system is using shadow */
- stp = getspnam(user);
- if (stp == 0)
+ const char *encr;
+ const char *epass;
+ struct passwd *spw;
+ struct spwd *stp;
+
+ spw = getpwnam(user);
+
+ if (spw == 0)
+ {
+ return 0;
+ }
+
+ if (g_strncmp(spw->pw_passwd, "x", 3) == 0)
{
- return 0;
+ /* the system is using shadow */
+ stp = getspnam(user);
+
+ if (stp == 0)
+ {
+ return 0;
+ }
+
+ if (1 == auth_account_disabled(stp))
+ {
+ log_message(&(g_cfg->log), LOG_LEVEL_INFO, "account %s is disabled", user);
+ return 0;
+ }
+
+ encr = stp->sp_pwdp;
}
- if (1==auth_account_disabled(stp))
+ else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "account %s is disabled", user);
- return 0;
+ /* old system with only passwd */
+ encr = spw->pw_passwd;
}
- g_strncpy(hash, stp->sp_pwdp, 34);
- }
- else
- {
- /* old system with only passwd */
- g_strncpy(hash, spw->pw_passwd, 34);
- }
- hash[34] = '\0';
- if (g_strncmp(hash, "$1$", 3) == 0)
- {
- /* gnu style crypt(); */
- saltcnt = 3;
- while ((hash[saltcnt] != '$') && (saltcnt < 11))
+ epass = crypt(pass, encr);
+ if (epass == 0)
{
- salt[saltcnt] = hash[saltcnt];
- saltcnt++;
+ return 0;
}
- salt[saltcnt] = '$';
- salt[saltcnt + 1] = '\0';
- }
- else
- {
- /* classic two char salt */
- salt[0] = hash[0];
- salt[1] = hash[1];
- salt[2] = '\0';
- }
- encr = crypt(pass,salt);
- if (g_strncmp(encr, hash, 34) != 0)
- {
- return 0;
- }
- return 1;
+ return (strcmp(encr, epass) == 0);
}
/******************************************************************************/
|