mirror of git://anongit.mindrot.org/openssh.git
- markus@cvs.openbsd.org 2013/03/07 19:27:25
[auth.h auth2-chall.c auth2.c monitor.c sshd_config.5] add submethod support to AuthenticationMethods; ok and freedback djm@
This commit is contained in:
parent
4ce189d910
commit
91a55f28f3
|
@ -19,6 +19,9 @@
|
|||
have included a style (e.g. "root:skey") when checking public key
|
||||
signatures. Fixes public key and hostbased auth when the client specified
|
||||
a style; ok markus@
|
||||
- markus@cvs.openbsd.org 2013/03/07 19:27:25
|
||||
[auth.h auth2-chall.c auth2.c monitor.c sshd_config.5]
|
||||
add submethod support to AuthenticationMethods; ok and freedback djm@
|
||||
|
||||
20130418
|
||||
- (djm) [config.guess config.sub] Update to last versions before they switch
|
||||
|
|
5
auth.h
5
auth.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth.h,v 1.72 2012/12/02 20:34:09 djm Exp $ */
|
||||
/* $OpenBSD: auth.h,v 1.73 2013/03/07 19:27:25 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
|
@ -157,8 +157,9 @@ void userauth_send_banner(const char *);
|
|||
|
||||
char *auth2_read_banner(void);
|
||||
int auth2_methods_valid(const char *, int);
|
||||
int auth2_update_methods_lists(Authctxt *, const char *);
|
||||
int auth2_update_methods_lists(Authctxt *, const char *, const char *);
|
||||
int auth2_setup_methods_lists(Authctxt *);
|
||||
int auth2_method_allowed(Authctxt *, const char *, const char *);
|
||||
|
||||
void privsep_challenge_enable(void);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2-chall.c,v 1.36 2012/12/03 00:14:06 djm Exp $ */
|
||||
/* $OpenBSD: auth2-chall.c,v 1.37 2013/03/07 19:27:25 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2001 Per Allansson. All rights reserved.
|
||||
|
@ -155,7 +155,7 @@ kbdint_free(KbdintAuthctxt *kbdintctxt)
|
|||
}
|
||||
/* get next device */
|
||||
static int
|
||||
kbdint_next_device(KbdintAuthctxt *kbdintctxt)
|
||||
kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
|
||||
{
|
||||
size_t len;
|
||||
char *t;
|
||||
|
@ -169,9 +169,13 @@ kbdint_next_device(KbdintAuthctxt *kbdintctxt)
|
|||
|
||||
if (len == 0)
|
||||
break;
|
||||
for (i = 0; devices[i]; i++)
|
||||
for (i = 0; devices[i]; i++) {
|
||||
if (!auth2_method_allowed(authctxt,
|
||||
"keyboard-interactive", devices[i]->name))
|
||||
continue;
|
||||
if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0)
|
||||
kbdintctxt->device = devices[i];
|
||||
}
|
||||
t = kbdintctxt->devices;
|
||||
kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
|
||||
xfree(t);
|
||||
|
@ -221,7 +225,7 @@ auth2_challenge_start(Authctxt *authctxt)
|
|||
debug2("auth2_challenge_start: devices %s",
|
||||
kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
|
||||
|
||||
if (kbdint_next_device(kbdintctxt) == 0) {
|
||||
if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
|
||||
auth2_challenge_stop(authctxt);
|
||||
return 0;
|
||||
}
|
||||
|
|
76
auth2.c
76
auth2.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2.c,v 1.126 2012/12/02 20:34:09 djm Exp $ */
|
||||
/* $OpenBSD: auth2.c,v 1.127 2013/03/07 19:27:25 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -98,8 +98,12 @@ static void input_userauth_request(int, u_int32_t, void *);
|
|||
/* helper */
|
||||
static Authmethod *authmethod_lookup(Authctxt *, const char *);
|
||||
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 *
|
||||
auth2_read_banner(void)
|
||||
|
@ -316,7 +320,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
|
|||
}
|
||||
|
||||
if (authenticated && options.num_auth_methods != 0) {
|
||||
if (!auth2_update_methods_lists(authctxt, method)) {
|
||||
if (!auth2_update_methods_lists(authctxt, method, submethod)) {
|
||||
authenticated = 0;
|
||||
partial = 1;
|
||||
}
|
||||
|
@ -387,8 +391,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
|
|||
* methods list. Returns 1 if allowed, or no methods lists configured.
|
||||
* 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
method_allowed(Authctxt *authctxt, const char *method)
|
||||
int
|
||||
auth2_method_allowed(Authctxt *authctxt, const char *method,
|
||||
const char *submethod)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
|
@ -399,7 +404,8 @@ method_allowed(Authctxt *authctxt, const char *method)
|
|||
if (options.num_auth_methods == 0)
|
||||
return 1;
|
||||
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 0;
|
||||
|
@ -419,7 +425,8 @@ authmethods_get(Authctxt *authctxt)
|
|||
if (authmethods[i]->enabled == NULL ||
|
||||
*(authmethods[i]->enabled) == 0)
|
||||
continue;
|
||||
if (!method_allowed(authctxt, authmethods[i]->name))
|
||||
if (!auth2_method_allowed(authctxt, authmethods[i]->name,
|
||||
NULL))
|
||||
continue;
|
||||
if (buffer_len(&b) > 0)
|
||||
buffer_append(&b, ",", 1);
|
||||
|
@ -442,7 +449,8 @@ authmethod_lookup(Authctxt *authctxt, const char *name)
|
|||
if (authmethods[i]->enabled != NULL &&
|
||||
*(authmethods[i]->enabled) != 0 &&
|
||||
strcmp(name, authmethods[i]->name) == 0 &&
|
||||
method_allowed(authctxt, authmethods[i]->name))
|
||||
auth2_method_allowed(authctxt,
|
||||
authmethods[i]->name, NULL))
|
||||
return authmethods[i];
|
||||
debug2("Unrecognized authentication method name: %s",
|
||||
name ? name : "NULL");
|
||||
|
@ -457,7 +465,7 @@ authmethod_lookup(Authctxt *authctxt, const char *name)
|
|||
int
|
||||
auth2_methods_valid(const char *_methods, int need_enable)
|
||||
{
|
||||
char *methods, *omethods, *method;
|
||||
char *methods, *omethods, *method, *p;
|
||||
u_int i, found;
|
||||
int ret = -1;
|
||||
|
||||
|
@ -468,6 +476,8 @@ auth2_methods_valid(const char *_methods, int need_enable)
|
|||
omethods = methods = xstrdup(_methods);
|
||||
while ((method = strsep(&methods, ",")) != NULL) {
|
||||
for (found = i = 0; !found && authmethods[i] != NULL; i++) {
|
||||
if ((p = strchr(method, ':')) != NULL)
|
||||
*p = '\0';
|
||||
if (strcmp(method, authmethods[i]->name) != 0)
|
||||
continue;
|
||||
if (need_enable) {
|
||||
|
@ -533,15 +543,30 @@ auth2_setup_methods_lists(Authctxt *authctxt)
|
|||
}
|
||||
|
||||
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);
|
||||
int match;
|
||||
const char *p;
|
||||
|
||||
if (strncmp(methods, method, l) != 0)
|
||||
return 0;
|
||||
if (methods[l] != ',' && methods[l] != '\0')
|
||||
return 0;
|
||||
return 1;
|
||||
return MATCH_NONE;
|
||||
p = methods + l;
|
||||
match = MATCH_METHOD;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -550,14 +575,21 @@ list_starts_with(const char *methods, const char *method)
|
|||
* if it did.
|
||||
*/
|
||||
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);
|
||||
int match;
|
||||
|
||||
if (!list_starts_with(omethods, method))
|
||||
match = list_starts_with(omethods, method, submethod);
|
||||
if (match != MATCH_METHOD && match != MATCH_BOTH)
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
@ -569,13 +601,15 @@ remove_method(char **methods, const char *method)
|
|||
* Returns 1 if the method completed any authentication list or 0 otherwise.
|
||||
*/
|
||||
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;
|
||||
|
||||
debug3("%s: updating methods list after \"%s\"", __func__, method);
|
||||
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;
|
||||
found = 1;
|
||||
if (*authctxt->auth_methods[i] == '\0') {
|
||||
|
|
11
monitor.c
11
monitor.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor.c,v 1.121 2013/03/07 00:19:59 djm Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.122 2013/03/07 19:27:25 markus Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
|
@ -392,7 +392,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
|
|||
"with SSH protocol 1");
|
||||
if (authenticated &&
|
||||
!auth2_update_methods_lists(authctxt,
|
||||
auth_method)) {
|
||||
auth_method, auth_submethod)) {
|
||||
debug3("%s: method %s: partial", __func__,
|
||||
auth_method);
|
||||
authenticated = 0;
|
||||
|
@ -949,9 +949,10 @@ mm_answer_bsdauthrespond(int sock, Buffer *m)
|
|||
debug3("%s: sending authenticated: %d", __func__, authok);
|
||||
mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m);
|
||||
|
||||
if (compat20)
|
||||
auth_method = "keyboard-interactive"; /* XXX auth_submethod */
|
||||
else
|
||||
if (compat20) {
|
||||
auth_method = "keyboard-interactive";
|
||||
auth_submethod = "bsdauth";
|
||||
} else
|
||||
auth_method = "bsdauth";
|
||||
|
||||
return (authok != 0);
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.156 2013/02/06 00:20:42 dtucker Exp $
|
||||
.Dd $Mdocdate: February 6 2013 $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.157 2013/03/07 19:27:25 markus Exp $
|
||||
.Dd $Mdocdate: March 7 2013 $
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -180,6 +180,20 @@ Only methods that are next in one or more lists are offered at each stage,
|
|||
so for this example, it would not be possible to attempt password or
|
||||
keyboard-interactive authentication before public key.
|
||||
.Pp
|
||||
For keyboard interactive authentication it is also possible to
|
||||
restrict authentication to a specific device by appending a
|
||||
colon followed by the device identifier
|
||||
.Dq bsdauth ,
|
||||
.Dq pam ,
|
||||
or
|
||||
.Dq skey ,
|
||||
depending on the server configuration.
|
||||
For example,
|
||||
.Dq keyboard-interactive:bsdauth
|
||||
would restrict keyboard interactive authentication to the
|
||||
.Dq bsdauth
|
||||
device.
|
||||
.Pp
|
||||
This option is only available for SSH protocol 2 and will yield a fatal
|
||||
error if enabled if protocol 1 is also enabled.
|
||||
Note that each authentication method listed should also be explicitly enabled
|
||||
|
|
Loading…
Reference in New Issue