summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <vinschen@redhat.com>2019-02-20 13:41:24 +0100
committerDarren Tucker <dtucker@dtucker.net>2019-02-22 15:04:16 +1100
commitf02afa350afac1b2f2d1413259a27a4ba1e2ca24 (patch)
treec568d26fa3747cfe35d86b46df84d5bcc0417245
parent4c55b674835478eb80a1a7aeae588aa654e2a433 (diff)
Revert "[auth.c] On Cygwin, refuse usernames that have differences in case"
This reverts commit acc9b29486dfd649dfda474e5c1a03b317449f1c. Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-rw-r--r--auth.c13
-rw-r--r--groupaccess.c4
-rw-r--r--match.c4
-rw-r--r--openbsd-compat/bsd-cygwin_util.c146
-rw-r--r--servconf.c4
5 files changed, 158 insertions, 13 deletions
diff --git a/auth.c b/auth.c
index 62c58e72f..332b6220c 100644
--- a/auth.c
+++ b/auth.c
@@ -584,19 +584,6 @@ getpwnamallow(struct ssh *ssh, const char *user)
584#if defined(_AIX) && defined(HAVE_SETAUTHDB) 584#if defined(_AIX) && defined(HAVE_SETAUTHDB)
585 aix_restoreauthdb(); 585 aix_restoreauthdb();
586#endif 586#endif
587#ifdef HAVE_CYGWIN
588 /*
589 * Windows usernames are case-insensitive. To avoid later problems
590 * when trying to match the username, the user is only allowed to
591 * login if the username is given in the same case as stored in the
592 * user database.
593 */
594 if (pw != NULL && strcmp(user, pw->pw_name) != 0) {
595 logit("Login name %.100s does not match stored username %.100s",
596 user, pw->pw_name);
597 pw = NULL;
598 }
599#endif
600 if (pw == NULL) { 587 if (pw == NULL) {
601 logit("Invalid user %.100s from %.100s port %d", 588 logit("Invalid user %.100s from %.100s port %d",
602 user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 589 user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
diff --git a/groupaccess.c b/groupaccess.c
index 9e4d25521..43367990d 100644
--- a/groupaccess.c
+++ b/groupaccess.c
@@ -103,7 +103,11 @@ ga_match_pattern_list(const char *group_pattern)
103 int i, found = 0; 103 int i, found = 0;
104 104
105 for (i = 0; i < ngroups; i++) { 105 for (i = 0; i < ngroups; i++) {
106#ifndef HAVE_CYGWIN
106 switch (match_pattern_list(groups_byname[i], group_pattern, 0)) { 107 switch (match_pattern_list(groups_byname[i], group_pattern, 0)) {
108#else
109 switch (match_pattern_list(groups_byname[i], group_pattern, 1)) {
110#endif
107 case -1: 111 case -1:
108 return 0; /* Negated match wins */ 112 return 0; /* Negated match wins */
109 case 0: 113 case 0:
diff --git a/match.c b/match.c
index bb3e95f67..b50ae4057 100644
--- a/match.c
+++ b/match.c
@@ -111,6 +111,8 @@ match_pattern(const char *s, const char *pattern)
111 /* NOTREACHED */ 111 /* NOTREACHED */
112} 112}
113 113
114#ifndef HAVE_CYGWIN /* Cygwin version in openbsd-compat/bsd-cygwin_util.c */
115
114/* 116/*
115 * Tries to match the string against the 117 * Tries to match the string against the
116 * comma-separated sequence of subpatterns (each possibly preceded by ! to 118 * comma-separated sequence of subpatterns (each possibly preceded by ! to
@@ -170,6 +172,8 @@ match_pattern_list(const char *string, const char *pattern, int dolower)
170 return got_positive; 172 return got_positive;
171} 173}
172 174
175#endif
176
173/* 177/*
174 * Tries to match the host name (which must be in all lowercase) against the 178 * Tries to match the host name (which must be in all lowercase) against the
175 * comma-separated sequence of subpatterns (each possibly preceded by ! to 179 * comma-separated sequence of subpatterns (each possibly preceded by ! to
diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c
index fb49e30f5..f721fca9d 100644
--- a/openbsd-compat/bsd-cygwin_util.c
+++ b/openbsd-compat/bsd-cygwin_util.c
@@ -37,6 +37,8 @@
37#include <string.h> 37#include <string.h>
38#include <unistd.h> 38#include <unistd.h>
39#include <stdarg.h> 39#include <stdarg.h>
40#include <wchar.h>
41#include <wctype.h>
40 42
41#include "xmalloc.h" 43#include "xmalloc.h"
42 44
@@ -117,4 +119,148 @@ free_windows_environment(char **p)
117 free(p); 119 free(p);
118} 120}
119 121
122/*
123 * Returns true if the given string matches the pattern (which may contain ?
124 * and * as wildcards), and zero if it does not match.
125 *
126 * The Cygwin version of this function must be case-insensitive and take
127 * Unicode characters into account.
128 */
129
130static int
131__match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive)
132{
133 for (;;) {
134 /* If at end of pattern, accept if also at end of string. */
135 if (!*pattern)
136 return !*s;
137
138 if (*pattern == '*') {
139 /* Skip the asterisk. */
140 pattern++;
141
142 /* If at end of pattern, accept immediately. */
143 if (!*pattern)
144 return 1;
145
146 /* If next character in pattern is known, optimize. */
147 if (*pattern != '?' && *pattern != '*') {
148 /*
149 * Look instances of the next character in
150 * pattern, and try to match starting from
151 * those.
152 */
153 for (; *s; s++)
154 if (*s == *pattern &&
155 __match_pattern(s + 1, pattern + 1,
156 caseinsensitive))
157 return 1;
158 /* Failed. */
159 return 0;
160 }
161 /*
162 * Move ahead one character at a time and try to
163 * match at each position.
164 */
165 for (; *s; s++)
166 if (__match_pattern(s, pattern, caseinsensitive))
167 return 1;
168 /* Failed. */
169 return 0;
170 }
171 /*
172 * There must be at least one more character in the string.
173 * If we are at the end, fail.
174 */
175 if (!*s)
176 return 0;
177
178 /* Check if the next character of the string is acceptable. */
179 if (*pattern != '?' && (*pattern != *s &&
180 (!caseinsensitive || towlower(*pattern) != towlower(*s))))
181 return 0;
182
183 /* Move to the next character, both in string and in pattern. */
184 s++;
185 pattern++;
186 }
187 /* NOTREACHED */
188}
189
190static int
191_match_pattern(const char *s, const char *pattern, int caseinsensitive)
192{
193 wchar_t *ws;
194 wchar_t *wpattern;
195 size_t len;
196
197 if ((len = mbstowcs(NULL, s, 0)) < 0)
198 return 0;
199 ws = (wchar_t *) alloca((len + 1) * sizeof (wchar_t));
200 mbstowcs(ws, s, len + 1);
201 if ((len = mbstowcs(NULL, pattern, 0)) < 0)
202 return 0;
203 wpattern = (wchar_t *) alloca((len + 1) * sizeof (wchar_t));
204 mbstowcs(wpattern, pattern, len + 1);
205 return __match_pattern (ws, wpattern, caseinsensitive);
206}
207
208/*
209 * Tries to match the string against the
210 * comma-separated sequence of subpatterns (each possibly preceded by ! to
211 * indicate negation). Returns -1 if negation matches, 1 if there is
212 * a positive match, 0 if there is no match at all.
213 */
214int
215match_pattern_list(const char *string, const char *pattern, int caseinsensitive)
216{
217 char sub[1024];
218 int negated;
219 int got_positive;
220 u_int i, subi, len = strlen(pattern);
221
222 got_positive = 0;
223 for (i = 0; i < len;) {
224 /* Check if the subpattern is negated. */
225 if (pattern[i] == '!') {
226 negated = 1;
227 i++;
228 } else
229 negated = 0;
230
231 /*
232 * Extract the subpattern up to a comma or end. Convert the
233 * subpattern to lowercase.
234 */
235 for (subi = 0;
236 i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
237 subi++, i++)
238 sub[subi] = pattern[i];
239 /* If subpattern too long, return failure (no match). */
240 if (subi >= sizeof(sub) - 1)
241 return 0;
242
243 /* If the subpattern was terminated by a comma, then skip it. */
244 if (i < len && pattern[i] == ',')
245 i++;
246
247 /* Null-terminate the subpattern. */
248 sub[subi] = '\0';
249
250 /* Try to match the subpattern against the string. */
251 if (_match_pattern(string, sub, caseinsensitive)) {
252 if (negated)
253 return -1; /* Negative */
254 else
255 got_positive = 1; /* Positive */
256 }
257 }
258
259 /*
260 * Return success if got a positive match. If there was a negative
261 * match, we have already returned -1 and never get here.
262 */
263 return got_positive;
264}
265
120#endif /* HAVE_CYGWIN */ 266#endif /* HAVE_CYGWIN */
diff --git a/servconf.c b/servconf.c
index d9680aba1..4fa896fd4 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1049,7 +1049,11 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
1049 } 1049 }
1050 if (ci->user == NULL) 1050 if (ci->user == NULL)
1051 match_test_missing_fatal("User", "user"); 1051 match_test_missing_fatal("User", "user");
1052#ifndef HAVE_CYGWIN
1052 if (match_pattern_list(ci->user, arg, 0) != 1) 1053 if (match_pattern_list(ci->user, arg, 0) != 1)
1054#else
1055 if (match_pattern_list(ci->user, arg, 1) != 1)
1056#endif
1053 result = 0; 1057 result = 0;
1054 else 1058 else
1055 debug("user %.100s matched 'User %.100s' at " 1059 debug("user %.100s matched 'User %.100s' at "