AuthenticationMethods option.
Damien Miller
djm at mindrot.org
Fri Nov 23 15:11:39 EST 2012
On Fri, 23 Nov 2012, Damien Miller wrote:
> On Thu, 22 Nov 2012, Pawel Jakub Dawidek wrote:
>
> > Hi.
> >
> > I can see that SSH partial success functionality was implemented very
> > recently in the OpenSSH server. That's great news.
> >
> > I just tried it and I don't seem to be able to make it work with both
> > public key authentication and password authentication through PAM.
> > I wonder if this is a bug or something that won't be implemented for now
> > or if this is still WIP and I should be more patient?
>
> Yes, there is a bug in there - the monitor is becoming confused by
> returns from monitor_read() that don't reset auth_method to an
> expected method name.
>
> I'll take a look.
I think this fixes it:
Index: auth.c
===================================================================
RCS file: /var/cvs/openssh/auth.c,v
retrieving revision 1.152
diff -u -p -r1.152 auth.c
--- auth.c 30 Oct 2012 21:58:59 -0000 1.152
+++ auth.c 23 Nov 2012 04:09:56 -0000
@@ -251,7 +251,8 @@ allowed_user(struct passwd * pw)
}
void
-auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
+auth_log(Authctxt *authctxt, int authenticated, int partial,
+ const char *method, const char *submethod, const char *info)
{
void (*authlog) (const char *fmt,...) = verbose;
char *authmsg;
@@ -268,12 +269,15 @@ auth_log(Authctxt *authctxt, int authent
if (authctxt->postponed)
authmsg = "Postponed";
+ else if (partial)
+ authmsg = "Partial";
else
authmsg = authenticated ? "Accepted" : "Failed";
- authlog("%s %s for %s%.100s from %.200s port %d%s",
+ authlog("%s %s%s%s for %s%.100s from %.200s port %d%s",
authmsg,
method,
+ submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
authctxt->valid ? "" : "invalid user ",
authctxt->user,
get_remote_ipaddr(),
@@ -303,7 +307,7 @@ auth_log(Authctxt *authctxt, int authent
* Check whether root logins are disallowed.
*/
int
-auth_root_allowed(char *method)
+auth_root_allowed(const char *method)
{
switch (options.permit_root_login) {
case PERMIT_YES:
Index: auth.h
===================================================================
RCS file: /var/cvs/openssh/auth.h,v
retrieving revision 1.89
diff -u -p -r1.89 auth.h
--- auth.h 4 Nov 2012 12:21:41 -0000 1.89
+++ auth.h 23 Nov 2012 04:09:56 -0000
@@ -148,10 +148,12 @@ void disable_forwarding(void);
void do_authentication(Authctxt *);
void do_authentication2(Authctxt *);
-void auth_log(Authctxt *, int, char *, char *);
-void userauth_finish(Authctxt *, int, char *);
+void auth_log(Authctxt *, int, int, const char *, const char *,
+ const char *);
+void userauth_finish(Authctxt *, int, const char *, const char *);
+int auth_root_allowed(const char *);
+
void userauth_send_banner(const char *);
-int auth_root_allowed(char *);
char *auth2_read_banner(void);
int auth2_methods_valid(const char *, int);
Index: auth1.c
===================================================================
RCS file: /var/cvs/openssh/auth1.c,v
retrieving revision 1.128
diff -u -p -r1.128 auth1.c
--- auth1.c 4 Nov 2012 12:21:41 -0000 1.128
+++ auth1.c 23 Nov 2012 04:09:56 -0000
@@ -253,7 +253,8 @@ do_authloop(Authctxt *authctxt)
if (options.use_pam && (PRIVSEP(do_pam_account())))
#endif
{
- auth_log(authctxt, 1, "without authentication", "");
+ auth_log(authctxt, 1, 0, "without authentication",
+ NULL, "");
return;
}
}
@@ -352,7 +353,8 @@ do_authloop(Authctxt *authctxt)
skip:
/* Log before sending the reply */
- auth_log(authctxt, authenticated, get_authname(type), info);
+ auth_log(authctxt, authenticated, 0, get_authname(type),
+ NULL, info);
if (client_user != NULL) {
xfree(client_user);
Index: auth2-chall.c
===================================================================
RCS file: /var/cvs/openssh/auth2-chall.c,v
retrieving revision 1.38
diff -u -p -r1.38 auth2-chall.c
--- auth2-chall.c 28 Jan 2009 05:13:39 -0000 1.38
+++ auth2-chall.c 23 Nov 2012 04:09:56 -0000
@@ -283,7 +283,7 @@ input_userauth_info_response(int type, u
KbdintAuthctxt *kbdintctxt;
int authenticated = 0, res;
u_int i, nresp;
- char **response = NULL, *method;
+ char *devicename = NULL, **response = NULL;
if (authctxt == NULL)
fatal("input_userauth_info_response: no authctxt");
@@ -329,9 +329,7 @@ input_userauth_info_response(int type, u
/* Failure! */
break;
}
-
- xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name);
-
+ devicename = kbdintctxt->device->name;
if (!authctxt->postponed) {
if (authenticated) {
auth2_challenge_stop(authctxt);
@@ -341,8 +339,8 @@ input_userauth_info_response(int type, u
auth2_challenge_start(authctxt);
}
}
- userauth_finish(authctxt, authenticated, method);
- xfree(method);
+ userauth_finish(authctxt, authenticated, "keyboard-interactive",
+ devicename);
}
void
Index: auth2-gss.c
===================================================================
RCS file: /var/cvs/openssh/auth2-gss.c,v
retrieving revision 1.20
diff -u -p -r1.20 auth2-gss.c
--- auth2-gss.c 5 May 2011 04:04:11 -0000 1.20
+++ auth2-gss.c 23 Nov 2012 04:09:56 -0000
@@ -163,7 +163,7 @@ input_gssapi_token(int type, u_int32_t p
}
authctxt->postponed = 0;
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
- userauth_finish(authctxt, 0, "gssapi-with-mic");
+ userauth_finish(authctxt, 0, "gssapi-with-mic", NULL);
} else {
if (send_tok.length != 0) {
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@@ -251,7 +251,7 @@ input_gssapi_exchange_complete(int type,
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
- userauth_finish(authctxt, authenticated, "gssapi-with-mic");
+ userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
}
static void
@@ -291,7 +291,7 @@ input_gssapi_mic(int type, u_int32_t ple
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
- userauth_finish(authctxt, authenticated, "gssapi-with-mic");
+ userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
}
Authmethod method_gssapi = {
Index: auth2-jpake.c
===================================================================
RCS file: /var/cvs/openssh/auth2-jpake.c,v
retrieving revision 1.5
diff -u -p -r1.5 auth2-jpake.c
--- auth2-jpake.c 31 Aug 2010 12:41:14 -0000 1.5
+++ auth2-jpake.c 23 Nov 2012 04:09:56 -0000
@@ -556,7 +556,7 @@ input_userauth_jpake_client_confirm(int
authctxt->postponed = 0;
jpake_free(authctxt->jpake_ctx);
authctxt->jpake_ctx = NULL;
- userauth_finish(authctxt, authenticated, method_jpake.name);
+ userauth_finish(authctxt, authenticated, method_jpake.name, NULL);
}
#endif /* JPAKE */
Index: auth2.c
===================================================================
RCS file: /var/cvs/openssh/auth2.c,v
retrieving revision 1.155
diff -u -p -r1.155 auth2.c
--- auth2.c 4 Nov 2012 12:21:41 -0000 1.155
+++ auth2.c 23 Nov 2012 04:09:56 -0000
@@ -286,7 +286,7 @@ input_userauth_request(int type, u_int32
debug2("input_userauth_request: try method %s", method);
authenticated = m->userauth(authctxt);
}
- userauth_finish(authctxt, authenticated, method);
+ userauth_finish(authctxt, authenticated, method, NULL);
xfree(service);
xfree(user);
@@ -294,7 +294,8 @@ input_userauth_request(int type, u_int32
}
void
-userauth_finish(Authctxt *authctxt, int authenticated, char *method)
+userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
+ const char *submethod)
{
char *methods;
int partial = 0;
@@ -302,6 +303,8 @@ userauth_finish(Authctxt *authctxt, int
if (!authctxt->valid && authenticated)
fatal("INTERNAL ERROR: authenticated invalid user %s",
authctxt->user);
+ if (authenticated && authctxt->postponed)
+ fatal("INTERNAL ERROR: authenticated and postponed");
/* Special handling for root */
if (authenticated && authctxt->pw->pw_uid == 0 &&
@@ -312,6 +315,19 @@ userauth_finish(Authctxt *authctxt, int
#endif
}
+ if (authenticated && options.num_auth_methods != 0) {
+ if (!auth2_update_methods_lists(authctxt, method)) {
+ authenticated = 0;
+ partial = 1;
+ }
+ }
+
+ /* Log before sending the reply */
+ auth_log(authctxt, authenticated, partial, method, submethod, " ssh2");
+
+ if (authctxt->postponed)
+ return;
+
#ifdef USE_PAM
if (options.use_pam && authenticated) {
if (!PRIVSEP(do_pam_account())) {
@@ -330,22 +346,9 @@ userauth_finish(Authctxt *authctxt, int
#ifdef _UNICOS
if (authenticated && cray_access_denied(authctxt->user)) {
authenticated = 0;
- fatal("Access denied for user %s.",authctxt->user);
+ fatal("Access denied for user %s.", authctxt->user);
}
#endif /* _UNICOS */
-
- /* Log before sending the reply */
- auth_log(authctxt, authenticated, method, " ssh2");
-
- if (authctxt->postponed)
- return;
-
- if (authenticated && options.num_auth_methods != 0) {
- if (!auth2_update_methods_lists(authctxt, method)) {
- authenticated = 0;
- partial = 1;
- }
- }
if (authenticated == 1) {
/* turn off userauth */
Index: monitor.c
===================================================================
RCS file: /var/cvs/openssh/monitor.c,v
retrieving revision 1.153
diff -u -p -r1.153 monitor.c
--- monitor.c 4 Nov 2012 12:21:41 -0000 1.153
+++ monitor.c 23 Nov 2012 04:09:56 -0000
@@ -199,6 +199,7 @@ static int key_blobtype = MM_NOKEY;
static char *hostbased_cuser = NULL;
static char *hostbased_chost = NULL;
static char *auth_method = "unknown";
+static char *auth_submethod = NULL;
static u_int session_id2_len = 0;
static u_char *session_id2 = NULL;
static pid_t monitor_child_pid;
@@ -352,7 +353,7 @@ void
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
{
struct mon_table *ent;
- int authenticated = 0;
+ int authenticated = 0, partial = 0;
debug3("preauth child monitor started");
@@ -379,7 +380,9 @@ monitor_child_preauth(Authctxt *_authctx
/* The first few requests do not require asynchronous access */
while (!authenticated) {
+ partial = 0;
auth_method = "unknown";
+ auth_submethod = NULL;
authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
/* Special handling for multiple required authentications */
@@ -393,6 +396,7 @@ monitor_child_preauth(Authctxt *_authctx
debug3("%s: method %s: partial", __func__,
auth_method);
authenticated = 0;
+ partial = 1;
}
}
@@ -417,7 +421,8 @@ monitor_child_preauth(Authctxt *_authctx
#endif
}
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
- auth_log(authctxt, authenticated, auth_method,
+ auth_log(authctxt, authenticated, partial,
+ auth_method, auth_submethod,
compat20 ? " ssh2" : "");
if (!authenticated)
authctxt->failures++;
@@ -943,7 +948,7 @@ mm_answer_bsdauthrespond(int sock, Buffe
mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m);
if (compat20)
- auth_method = "keyboard-interactive";
+ auth_method = "keyboard-interactive"; /* XXX auth_submethod */
else
auth_method = "bsdauth";
@@ -1084,7 +1089,8 @@ mm_answer_pam_query(int sock, Buffer *m)
xfree(prompts);
if (echo_on != NULL)
xfree(echo_on);
- auth_method = "keyboard-interactive/pam";
+ auth_method = "keyboard-interactive";
+ auth_submethod = "pam";
mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m);
return (0);
}
@@ -1113,7 +1119,8 @@ mm_answer_pam_respond(int sock, Buffer *
buffer_clear(m);
buffer_put_int(m, ret);
mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m);
- auth_method = "keyboard-interactive/pam";
+ auth_method = "keyboard-interactive";
+ auth_submethod = "pam";
if (ret == 0)
sshpam_authok = sshpam_ctxt;
return (0);
@@ -1127,7 +1134,8 @@ mm_answer_pam_free_ctx(int sock, Buffer
(sshpam_device.free_ctx)(sshpam_ctxt);
buffer_clear(m);
mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m);
- auth_method = "keyboard-interactive/pam";
+ auth_method = "keyboard-interactive";
+ auth_submethod = "pam";
return (sshpam_authok == sshpam_ctxt);
}
#endif
@@ -1201,7 +1209,8 @@ mm_answer_keyallowed(int sock, Buffer *m
hostbased_chost = chost;
} else {
/* Log failed attempt */
- auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
+ auth_log(authctxt, 0, 0, auth_method, NULL,
+ compat20 ? " ssh2" : "");
xfree(blob);
xfree(cuser);
xfree(chost);
More information about the openssh-unix-dev
mailing list