|
Lines 134-140
input_userauth_request(int type, u_int32
Link Here
|
| 134 |
{ |
134 |
{ |
| 135 |
Authctxt *authctxt = ctxt; |
135 |
Authctxt *authctxt = ctxt; |
| 136 |
Authmethod *m = NULL; |
136 |
Authmethod *m = NULL; |
| 137 |
char *user, *service, *method, *style = NULL; |
137 |
char *user, *service, *method, *active_methods, *style = NULL; |
| 138 |
int authenticated = 0; |
138 |
int authenticated = 0; |
| 139 |
|
139 |
|
| 140 |
if (authctxt == NULL) |
140 |
if (authctxt == NULL) |
|
Lines 183-194
input_userauth_request(int type, u_int32
Link Here
|
| 183 |
authctxt->postponed = 0; |
183 |
authctxt->postponed = 0; |
| 184 |
|
184 |
|
| 185 |
/* try to authenticate user */ |
185 |
/* try to authenticate user */ |
| 186 |
m = authmethod_lookup(method); |
186 |
active_methods = authmethods_get(); |
| 187 |
if (m != NULL) { |
187 |
if (strcmp(method, "none") == 0 || |
| 188 |
debug2("input_userauth_request: try method %s", method); |
188 |
auth_method_in_list(active_methods, method)) { |
| 189 |
authenticated = m->userauth(authctxt); |
189 |
m = authmethod_lookup(method); |
|
|
190 |
if (m != NULL) { |
| 191 |
debug2("input_userauth_request: try method %s", method); |
| 192 |
authenticated = m->userauth(authctxt); |
| 193 |
} |
| 190 |
} |
194 |
} |
| 191 |
userauth_finish(authctxt, authenticated, method); |
195 |
xfree(active_methods); |
|
|
196 |
userauth_finish(authctxt, authenticated, method, NULL); |
| 192 |
|
197 |
|
| 193 |
xfree(service); |
198 |
xfree(service); |
| 194 |
xfree(user); |
199 |
xfree(user); |
|
Lines 196-204
input_userauth_request(int type, u_int32
Link Here
|
| 196 |
} |
201 |
} |
| 197 |
|
202 |
|
| 198 |
void |
203 |
void |
| 199 |
userauth_finish(Authctxt *authctxt, int authenticated, char *method) |
204 |
userauth_finish(Authctxt *authctxt, int authenticated, const char *method, |
|
|
205 |
const char *submethod) |
| 200 |
{ |
206 |
{ |
| 201 |
char *methods; |
207 |
char *methods; |
|
|
208 |
Authmethod *m = NULL; |
| 209 |
u_int partial = 0; |
| 202 |
|
210 |
|
| 203 |
if (!authctxt->valid && authenticated) |
211 |
if (!authctxt->valid && authenticated) |
| 204 |
fatal("INTERNAL ERROR: authenticated invalid user %s", |
212 |
fatal("INTERNAL ERROR: authenticated invalid user %s", |
|
Lines 210-221
userauth_finish(Authctxt *authctxt, int
Link Here
|
| 210 |
authenticated = 0; |
218 |
authenticated = 0; |
| 211 |
|
219 |
|
| 212 |
/* Log before sending the reply */ |
220 |
/* Log before sending the reply */ |
| 213 |
auth_log(authctxt, authenticated, method, " ssh2"); |
221 |
auth_log(authctxt, authenticated, method, submethod, " ssh2"); |
| 214 |
|
222 |
|
| 215 |
if (authctxt->postponed) |
223 |
if (authctxt->postponed) |
| 216 |
return; |
224 |
return; |
|
|
225 |
|
| 226 |
/* Handle RequiredAuthentications2: loop until required methods done */ |
| 227 |
if (authenticated && options.required_auth2 != NULL) { |
| 228 |
if ((m = authmethod_lookup(method)) == NULL) |
| 229 |
fatal("INTERNAL ERROR: authenticated method " |
| 230 |
"\"%s\" unknown", method); |
| 231 |
if (auth_remove_from_list(&options.required_auth2, method) != 1) |
| 232 |
fatal("INTERNAL ERROR: authenticated method " |
| 233 |
"\"%s\" not in required list \"%s\"", |
| 234 |
method, options.required_auth2); |
| 235 |
debug2("userauth_finish: required list now: %s", |
| 236 |
options.required_auth2 == NULL ? |
| 237 |
"DONE" : options.required_auth2); |
| 238 |
/* |
| 239 |
* Disable method so client can't authenticate with it after |
| 240 |
* the required authentications are complete. |
| 241 |
*/ |
| 242 |
if (m->enabled != NULL) |
| 243 |
*(m->enabled) = 0; |
| 244 |
authenticated = 0; |
| 245 |
partial = 1; |
| 246 |
goto send_fail; |
| 247 |
} |
| 217 |
|
248 |
|
| 218 |
/* XXX todo: check if multiple auth methods are needed */ |
|
|
| 219 |
if (authenticated == 1) { |
249 |
if (authenticated == 1) { |
| 220 |
/* turn off userauth */ |
250 |
/* turn off userauth */ |
| 221 |
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); |
251 |
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); |
|
Lines 227-236
userauth_finish(Authctxt *authctxt, int
Link Here
|
| 227 |
} else { |
257 |
} else { |
| 228 |
if (authctxt->failures++ > options.max_authtries) |
258 |
if (authctxt->failures++ > options.max_authtries) |
| 229 |
packet_disconnect(AUTH_FAIL_MSG, authctxt->user); |
259 |
packet_disconnect(AUTH_FAIL_MSG, authctxt->user); |
|
|
260 |
send_fail: |
| 230 |
methods = authmethods_get(); |
261 |
methods = authmethods_get(); |
| 231 |
packet_start(SSH2_MSG_USERAUTH_FAILURE); |
262 |
packet_start(SSH2_MSG_USERAUTH_FAILURE); |
| 232 |
packet_put_cstring(methods); |
263 |
packet_put_cstring(methods); |
| 233 |
packet_put_char(0); /* XXX partial success, unused */ |
264 |
packet_put_char(partial); |
| 234 |
packet_send(); |
265 |
packet_send(); |
| 235 |
packet_write_wait(); |
266 |
packet_write_wait(); |
| 236 |
xfree(methods); |
267 |
xfree(methods); |
|
Lines 246-251
authmethods_get(void)
Link Here
|
| 246 |
char *list; |
277 |
char *list; |
| 247 |
int i; |
278 |
int i; |
| 248 |
|
279 |
|
|
|
280 |
if (options.required_auth2 != NULL) |
| 281 |
return xstrdup(options.required_auth2); |
| 282 |
|
| 249 |
buffer_init(&b); |
283 |
buffer_init(&b); |
| 250 |
for (i = 0; authmethods[i] != NULL; i++) { |
284 |
for (i = 0; authmethods[i] != NULL; i++) { |
| 251 |
if (strcmp(authmethods[i]->name, "none") == 0) |
285 |
if (strcmp(authmethods[i]->name, "none") == 0) |
|
Lines 278-281
authmethod_lookup(const char *name)
Link Here
|
| 278 |
debug2("Unrecognized authentication method name: %s", |
312 |
debug2("Unrecognized authentication method name: %s", |
| 279 |
name ? name : "NULL"); |
313 |
name ? name : "NULL"); |
| 280 |
return NULL; |
314 |
return NULL; |
|
|
315 |
} |
| 316 |
|
| 317 |
int |
| 318 |
auth2_check_required(const char *list) |
| 319 |
{ |
| 320 |
char *orig_methods, *methods, *cp; |
| 321 |
struct Authmethod *m; |
| 322 |
int i, ret = 0; |
| 323 |
|
| 324 |
orig_methods = methods = xstrdup(list); |
| 325 |
for(;;) { |
| 326 |
if ((cp = strsep(&methods, DELIM)) == NULL) |
| 327 |
break; |
| 328 |
debug2("auth2_check_required: method \"%s\"", cp); |
| 329 |
if (*cp == '\0') { |
| 330 |
debug("auth2_check_required: empty method"); |
| 331 |
ret = -1; |
| 332 |
} |
| 333 |
for (i = 0; authmethods[i] != NULL; i++) |
| 334 |
if (strcmp(cp, authmethods[i]->name) == 0) |
| 335 |
break; |
| 336 |
if ((m = authmethods[i]) == NULL) { |
| 337 |
debug("auth2_check_required: unknown method " |
| 338 |
"\"%s\"", cp); |
| 339 |
ret = -1; |
| 340 |
} |
| 341 |
if (m->enabled == NULL || *(m->enabled) == 0) { |
| 342 |
debug("auth2_check_required: method %s explicitly " |
| 343 |
"disabled", cp); |
| 344 |
ret = -1; |
| 345 |
} |
| 346 |
/* Activate method if it isn't already */ |
| 347 |
if (*(m->enabled) == -1) |
| 348 |
*(m->enabled) = 1; |
| 349 |
} |
| 350 |
xfree(orig_methods); |
| 351 |
return (ret); |
| 281 |
} |
352 |
} |