修正:某些主机ssh服务不支持查询所支持的认证方式,导致无法进行ssh连接。

pull/32/head
Apex Liu 2017-06-05 17:06:43 +08:00
parent 0aba3ce42d
commit e66e002161
1 changed files with 91 additions and 98 deletions

View File

@ -249,7 +249,8 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
// 因为是从sftp会话得来的登录数据因此限制本会话只能用于sftp不允许再使用shell了。 // 因为是从sftp会话得来的登录数据因此限制本会话只能用于sftp不允许再使用shell了。
_this->_enter_sftp_mode(); _this->_enter_sftp_mode();
} else { }
else {
_this->m_server_ip = sess_info->host_ip; _this->m_server_ip = sess_info->host_ip;
_this->m_server_port = sess_info->host_port; _this->m_server_port = sess_info->host_port;
_this->m_auth_mode = sess_info->auth_mode; _this->m_auth_mode = sess_info->auth_mode;
@ -310,31 +311,41 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
// 检查服务端支持的认证协议 // 检查服务端支持的认证协议
ssh_userauth_none(_this->m_srv_session, NULL); ssh_userauth_none(_this->m_srv_session, NULL);
int auth_methods = ssh_userauth_list(_this->m_srv_session, NULL); // int auth_methods = ssh_userauth_list(_this->m_srv_session, NULL);
if (_this->m_auth_mode == TS_AUTH_MODE_PASSWORD) { if (_this->m_auth_mode == TS_AUTH_MODE_PASSWORD) {
if (auth_methods & SSH_AUTH_METHOD_PASSWORD) {
rc = ssh_userauth_password(_this->m_srv_session, NULL, _this->m_user_auth.c_str()); rc = ssh_userauth_password(_this->m_srv_session, NULL, _this->m_user_auth.c_str());
if (rc != SSH_AUTH_SUCCESS) { if (rc == SSH_AUTH_SUCCESS) {
_this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
}
else if (rc == SSH_AUTH_ERROR) {
EXLOGE("[ssh] invalid password for password mode to login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port); EXLOGE("[ssh] invalid password for password mode to login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port);
_this->m_have_error = true; _this->m_have_error = true;
_this->m_retcode = SESS_STAT_ERR_AUTH_DENIED; _this->m_retcode = SESS_STAT_ERR_AUTH_DENIED;
return SSH_AUTH_DENIED; return SSH_AUTH_ERROR;
} }
}
else if (auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { // 可能远程主机不允许用密码登录,试试交互式登录
bool is_login = false;
for (;;) { for (;;) {
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL); rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
if (rc != SSH_AUTH_INFO) if (rc != SSH_AUTH_INFO) {
EXLOGE("[ssh] try ssh interactive login failed at init, errcode=%d.\n", rc);
break; break;
}
if(ssh_userauth_kbdint_getnprompts(_this->m_srv_session) != 1) if (ssh_userauth_kbdint_getnprompts(_this->m_srv_session) != 1) {
EXLOGE("[ssh] ssh interactive login, prompt count not 1.\n");
break; break;
}
rc = ssh_userauth_kbdint_setanswer(_this->m_srv_session, 0, _this->m_user_auth.c_str()); rc = ssh_userauth_kbdint_setanswer(_this->m_srv_session, 0, _this->m_user_auth.c_str());
if (rc < 0) if (rc != SSH_AUTH_SUCCESS) {
break; EXLOGE("[ssh] invalid password for interactive mode to login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port);
_this->m_have_error = true;
_this->m_retcode = SESS_STAT_ERR_AUTH_DENIED;
return SSH_AUTH_ERROR;
}
// 有时候服务端会再发一个空的提示来完成交互 // 有时候服务端会再发一个空的提示来完成交互
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL); rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
@ -346,68 +357,50 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
break; break;
} }
if(rc == SSH_AUTH_SUCCESS) if (rc == SSH_AUTH_SUCCESS) {
is_login = true; _this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
}
break; break;
} }
if (!is_login) { EXLOGE("[ssh] can not use password mode or interactive mode ot login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port);
EXLOGE("[ssh] invalid password for keyboard-interactive mode to login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port);
_this->m_have_error = true; _this->m_have_error = true;
_this->m_retcode = SESS_STAT_ERR_AUTH_DENIED; _this->m_retcode = SESS_STAT_ERR_AUTH_DENIED;
return SSH_AUTH_DENIED; return SSH_AUTH_ERROR;
}
}
else {
EXLOGE("[ssh] real SSH server [%s:%d] does not support password or keyboard-interactive login.\n", _this->m_server_ip.c_str(), _this->m_server_port);
_this->m_have_error = true;
_this->m_retcode = SESS_STAT_ERR_AUTH_DENIED;
return SSH_AUTH_DENIED;
}
} }
else if (_this->m_auth_mode == TS_AUTH_MODE_PRIVATE_KEY) { else if (_this->m_auth_mode == TS_AUTH_MODE_PRIVATE_KEY) {
if (auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
ssh_key key = NULL; ssh_key key = NULL;
if (SSH_OK != ssh_pki_import_privkey_base64(_this->m_user_auth.c_str(), NULL, NULL, NULL, &key)) { if (SSH_OK != ssh_pki_import_privkey_base64(_this->m_user_auth.c_str(), NULL, NULL, NULL, &key)) {
EXLOGE("[ssh] can not import private-key for auth.\n"); EXLOGE("[ssh] can not import private-key for auth.\n");
_this->m_have_error = true; _this->m_have_error = true;
_this->m_retcode = SESS_STAT_ERR_BAD_SSH_KEY; _this->m_retcode = SESS_STAT_ERR_BAD_SSH_KEY;
return SSH_AUTH_DENIED; return SSH_AUTH_ERROR;
} }
rc = ssh_userauth_publickey(_this->m_srv_session, NULL, key); rc = ssh_userauth_publickey(_this->m_srv_session, NULL, key);
if (rc != SSH_OK) {
ssh_key_free(key); ssh_key_free(key);
EXLOGE("[ssh] invalid private-key for login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port);
_this->m_have_error = true;
_this->m_retcode = SESS_STAT_ERR_AUTH_DENIED;
return SSH_AUTH_DENIED;
}
ssh_key_free(key); if (rc == SSH_AUTH_SUCCESS) {
_this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
} }
else { else {
EXLOGE("[ssh] real SSH server [%s:%d] does not support public key login.\n", _this->m_server_ip.c_str(), _this->m_server_port); EXLOGE("[ssh] failed to use private-key to login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port);
_this->m_have_error = true; _this->m_have_error = true;
_this->m_retcode = SESS_STAT_ERR_AUTH_DENIED; _this->m_retcode = SESS_STAT_ERR_AUTH_DENIED;
return SSH_AUTH_DENIED; return SSH_AUTH_ERROR;
} }
} }
else if (_this->m_auth_mode == TS_AUTH_MODE_NONE) else if (_this->m_auth_mode == TS_AUTH_MODE_NONE) {
{ return SSH_AUTH_ERROR;
// do nothing.
return SSH_AUTH_DENIED;
} }
else { else {
EXLOGE("[ssh] invalid auth mode.\n"); EXLOGE("[ssh] invalid auth mode.\n");
_this->m_have_error = true; _this->m_have_error = true;
_this->m_retcode = SESS_STAT_ERR_AUTH_DENIED; _this->m_retcode = SESS_STAT_ERR_AUTH_DENIED;
return SSH_AUTH_DENIED; return SSH_AUTH_ERROR;
} }
_this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
} }
ssh_channel SshSession::_on_new_channel_request(ssh_session session, void *userdata) { ssh_channel SshSession::_on_new_channel_request(ssh_session session, void *userdata) {