ref: 9c50712d64a5b58cd67970a58702138ddcd31e8d
parent: 2e714ffe7c3dd2d0a449622189df4efc69a9adba
author: cinap_lenrek <[email protected]>
date: Thu Apr 20 19:45:56 EDT 2017
ssh: do not try authentication methods that we know are not possible
--- a/sys/src/cmd/ssh.c
+++ b/sys/src/cmd/ssh.c
@@ -617,7 +617,32 @@
setupChachastate(&recv.cs2, k12+0*ChachaKeylen, ChachaKeylen, nil, 64/8, 20);
}
+static char *authnext;
+
int
+authok(char *meth)
+{
+ if(authnext == nil || strstr(authnext, meth) != nil)
+ return 1;
+ return 0;
+}
+
+int
+authfailure(char *meth)
+{
+ char *s;
+ int n, partial;
+
+ if(unpack(recv.r, recv.w-recv.r, "_sb", &s, &n, &partial) < 0)
+ sysfatal("bad auth failure response");
+ free(authnext);
+ authnext = smprint("%.*s", n, s);
+if(debug)
+ fprint(2, "userauth %s failed: partial=%d, next=%s\n", meth, partial, authnext);
+ return partial != 0 || !authok(meth);
+}
+
+int
pubkeyauth(void)
{
static char authmeth[] = "publickey";
@@ -631,6 +656,9 @@
AuthRpc *rpc;
RSApub *pub;
+ if(!authok(authmeth))
+ return -1;
+
if(debug)
fprint(2, "%s...\n", authmeth);
@@ -674,6 +702,8 @@
dispatch();
goto Next1;
case MSG_USERAUTH_FAILURE:
+ if(authfailure(authmeth))
+ goto Failed;
continue;
case MSG_USERAUTH_SUCCESS:
case MSG_USERAUTH_PK_OK:
@@ -717,6 +747,8 @@
dispatch();
goto Next2;
case MSG_USERAUTH_FAILURE:
+ if(authfailure(authmeth))
+ goto Failed;
continue;
case MSG_USERAUTH_SUCCESS:
break;
@@ -726,6 +758,7 @@
close(afd);
return 0;
}
+Failed:
rsapubfree(pub);
auth_freerpc(rpc);
close(afd);
@@ -738,6 +771,9 @@
static char authmeth[] = "password";
UserPasswd *up;
+ if(!authok(authmeth))
+ return -1;
+
if(debug)
fprint(2, "%s...\n", authmeth);
@@ -761,7 +797,8 @@
dispatch();
goto Next0;
case MSG_USERAUTH_FAILURE:
- werrstr("%s authentication failed", authmeth);
+ werrstr("wrong password");
+ authfailure(authmeth);
return -1;
case MSG_USERAUTH_SUCCESS:
return 0;
@@ -778,6 +815,9 @@
int nquest, echo;
uchar *ans, *answ;
+ if(!authok(authmeth))
+ return -1;
+
if(debug)
fprint(2, "%s...\n", authmeth);
@@ -793,7 +833,7 @@
dispatch();
goto Next0;
case MSG_USERAUTH_FAILURE:
- werrstr("%s authentication failed", authmeth);
+ authfailure(authmeth);
return -1;
case MSG_USERAUTH_SUCCESS:
return 0;
@@ -800,7 +840,7 @@
case MSG_USERAUTH_INFO_REQUEST:
break;
}
-
+Retry:
if((fd = open("/dev/cons", OWRITE)) < 0)
return -1;
@@ -850,8 +890,10 @@
default:
dispatch();
goto Next1;
+ case MSG_USERAUTH_INFO_REQUEST:
+ goto Retry;
case MSG_USERAUTH_FAILURE:
- werrstr("%s authentication failed", authmeth);
+ authfailure(authmeth);
return -1;
case MSG_USERAUTH_SUCCESS:
return 0;