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