version 1.126, 2012/12/02 20:34:09 |
version 1.127, 2013/03/07 19:27:25 |
|
|
/* helper */ |
/* helper */ |
static Authmethod *authmethod_lookup(Authctxt *, const char *); |
static Authmethod *authmethod_lookup(Authctxt *, const char *); |
static char *authmethods_get(Authctxt *authctxt); |
static char *authmethods_get(Authctxt *authctxt); |
static int method_allowed(Authctxt *, const char *); |
|
static int list_starts_with(const char *, const char *); |
|
|
|
|
#define MATCH_NONE 0 /* method or submethod mismatch */ |
|
#define MATCH_METHOD 1 /* method matches (no submethod specified) */ |
|
#define MATCH_BOTH 2 /* method and submethod match */ |
|
#define MATCH_PARTIAL 3 /* method matches, submethod can't be checked */ |
|
static int list_starts_with(const char *, const char *, const char *); |
|
|
char * |
char * |
auth2_read_banner(void) |
auth2_read_banner(void) |
{ |
{ |
|
|
authenticated = 0; |
authenticated = 0; |
|
|
if (authenticated && options.num_auth_methods != 0) { |
if (authenticated && options.num_auth_methods != 0) { |
if (!auth2_update_methods_lists(authctxt, method)) { |
if (!auth2_update_methods_lists(authctxt, method, submethod)) { |
authenticated = 0; |
authenticated = 0; |
partial = 1; |
partial = 1; |
} |
} |
|
|
* methods list. Returns 1 if allowed, or no methods lists configured. |
* methods list. Returns 1 if allowed, or no methods lists configured. |
* 0 otherwise. |
* 0 otherwise. |
*/ |
*/ |
static int |
int |
method_allowed(Authctxt *authctxt, const char *method) |
auth2_method_allowed(Authctxt *authctxt, const char *method, |
|
const char *submethod) |
{ |
{ |
u_int i; |
u_int i; |
|
|
|
|
if (options.num_auth_methods == 0) |
if (options.num_auth_methods == 0) |
return 1; |
return 1; |
for (i = 0; i < authctxt->num_auth_methods; i++) { |
for (i = 0; i < authctxt->num_auth_methods; i++) { |
if (list_starts_with(authctxt->auth_methods[i], method)) |
if (list_starts_with(authctxt->auth_methods[i], method, |
|
submethod) != MATCH_NONE) |
return 1; |
return 1; |
} |
} |
return 0; |
return 0; |
|
|
if (authmethods[i]->enabled == NULL || |
if (authmethods[i]->enabled == NULL || |
*(authmethods[i]->enabled) == 0) |
*(authmethods[i]->enabled) == 0) |
continue; |
continue; |
if (!method_allowed(authctxt, authmethods[i]->name)) |
if (!auth2_method_allowed(authctxt, authmethods[i]->name, |
|
NULL)) |
continue; |
continue; |
if (buffer_len(&b) > 0) |
if (buffer_len(&b) > 0) |
buffer_append(&b, ",", 1); |
buffer_append(&b, ",", 1); |
|
|
if (authmethods[i]->enabled != NULL && |
if (authmethods[i]->enabled != NULL && |
*(authmethods[i]->enabled) != 0 && |
*(authmethods[i]->enabled) != 0 && |
strcmp(name, authmethods[i]->name) == 0 && |
strcmp(name, authmethods[i]->name) == 0 && |
method_allowed(authctxt, authmethods[i]->name)) |
auth2_method_allowed(authctxt, |
|
authmethods[i]->name, NULL)) |
return authmethods[i]; |
return authmethods[i]; |
debug2("Unrecognized authentication method name: %s", |
debug2("Unrecognized authentication method name: %s", |
name ? name : "NULL"); |
name ? name : "NULL"); |
|
|
int |
int |
auth2_methods_valid(const char *_methods, int need_enable) |
auth2_methods_valid(const char *_methods, int need_enable) |
{ |
{ |
char *methods, *omethods, *method; |
char *methods, *omethods, *method, *p; |
u_int i, found; |
u_int i, found; |
int ret = -1; |
int ret = -1; |
|
|
|
|
omethods = methods = xstrdup(_methods); |
omethods = methods = xstrdup(_methods); |
while ((method = strsep(&methods, ",")) != NULL) { |
while ((method = strsep(&methods, ",")) != NULL) { |
for (found = i = 0; !found && authmethods[i] != NULL; i++) { |
for (found = i = 0; !found && authmethods[i] != NULL; i++) { |
|
if ((p = strchr(method, ':')) != NULL) |
|
*p = '\0'; |
if (strcmp(method, authmethods[i]->name) != 0) |
if (strcmp(method, authmethods[i]->name) != 0) |
continue; |
continue; |
if (need_enable) { |
if (need_enable) { |
|
|
} |
} |
|
|
static int |
static int |
list_starts_with(const char *methods, const char *method) |
list_starts_with(const char *methods, const char *method, |
|
const char *submethod) |
{ |
{ |
size_t l = strlen(method); |
size_t l = strlen(method); |
|
int match; |
|
const char *p; |
|
|
if (strncmp(methods, method, l) != 0) |
if (strncmp(methods, method, l) != 0) |
return 0; |
return MATCH_NONE; |
if (methods[l] != ',' && methods[l] != '\0') |
p = methods + l; |
return 0; |
match = MATCH_METHOD; |
return 1; |
if (*p == ':') { |
|
if (!submethod) |
|
return MATCH_PARTIAL; |
|
l = strlen(submethod); |
|
p += 1; |
|
if (strncmp(submethod, p, l)) |
|
return MATCH_NONE; |
|
p += l; |
|
match = MATCH_BOTH; |
|
} |
|
if (*p != ',' && *p != '\0') |
|
return MATCH_NONE; |
|
return match; |
} |
} |
|
|
/* |
/* |
|
|
* if it did. |
* if it did. |
*/ |
*/ |
static int |
static int |
remove_method(char **methods, const char *method) |
remove_method(char **methods, const char *method, const char *submethod) |
{ |
{ |
char *omethods = *methods; |
char *omethods = *methods, *p; |
size_t l = strlen(method); |
size_t l = strlen(method); |
|
int match; |
|
|
if (!list_starts_with(omethods, method)) |
match = list_starts_with(omethods, method, submethod); |
|
if (match != MATCH_METHOD && match != MATCH_BOTH) |
return 0; |
return 0; |
*methods = xstrdup(omethods + l + (omethods[l] == ',' ? 1 : 0)); |
p = omethods + l; |
|
if (submethod && match == MATCH_BOTH) |
|
p += 1 + strlen(submethod); /* include colon */ |
|
if (*p == ',') |
|
p++; |
|
*methods = xstrdup(p); |
free(omethods); |
free(omethods); |
return 1; |
return 1; |
} |
} |
|
|
* Returns 1 if the method completed any authentication list or 0 otherwise. |
* Returns 1 if the method completed any authentication list or 0 otherwise. |
*/ |
*/ |
int |
int |
auth2_update_methods_lists(Authctxt *authctxt, const char *method) |
auth2_update_methods_lists(Authctxt *authctxt, const char *method, |
|
const char *submethod) |
{ |
{ |
u_int i, found = 0; |
u_int i, found = 0; |
|
|
debug3("%s: updating methods list after \"%s\"", __func__, method); |
debug3("%s: updating methods list after \"%s\"", __func__, method); |
for (i = 0; i < authctxt->num_auth_methods; i++) { |
for (i = 0; i < authctxt->num_auth_methods; i++) { |
if (!remove_method(&(authctxt->auth_methods[i]), method)) |
if (!remove_method(&(authctxt->auth_methods[i]), method, |
|
submethod)) |
continue; |
continue; |
found = 1; |
found = 1; |
if (*authctxt->auth_methods[i] == '\0') { |
if (*authctxt->auth_methods[i] == '\0') { |