From f861da6d66c559cce7c78d84585c1397c2c42700 Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Mon, 29 May 2017 04:29:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81ssh=E2=80=9C=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E5=BC=8F=E7=99=BB=E5=BD=95=E2=80=9D=EF=BC=8C=E4=BB=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81FreeBSD10=E7=AD=89=E7=B3=BB=E7=BB=9F=EF=BC=88?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=AE=BE=E7=BD=AE=E4=B8=BA=E4=BB=85=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E4=BA=A4=E4=BA=92=E5=BC=8F=E7=99=BB=E5=BD=95=E6=88=96?= =?UTF-8?q?=E7=A7=81=E9=92=A5=E7=99=BB=E5=BD=95=E6=96=B9=E5=BC=8F=EF=BC=89?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/tp_core/protocol/ssh/ssh_session.cpp | 87 +++++++++++++++++---- 1 file changed, 73 insertions(+), 14 deletions(-) diff --git a/server/tp_core/protocol/ssh/ssh_session.cpp b/server/tp_core/protocol/ssh/ssh_session.cpp index 09dbe4a..fd66974 100644 --- a/server/tp_core/protocol/ssh/ssh_session.cpp +++ b/server/tp_core/protocol/ssh/ssh_session.cpp @@ -310,34 +310,93 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user, return SSH_AUTH_DENIED; } + // 检查服务端支持的认证协议 + ssh_userauth_none(_this->m_srv_session, NULL); + int auth_methods = ssh_userauth_list(_this->m_srv_session, NULL); + //(auth_methods & SSH_AUTH_METHOD_INTERACTIVE); + + if (_this->m_auth_mode == TS_AUTH_MODE_PASSWORD) { - rc = ssh_userauth_password(_this->m_srv_session, NULL, _this->m_user_auth.c_str()); - if (rc != SSH_OK) { - EXLOGE("[ssh] can not use user/name login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port); + if (auth_methods & SSH_AUTH_METHOD_PASSWORD) { + rc = ssh_userauth_password(_this->m_srv_session, NULL, _this->m_user_auth.c_str()); + if (rc != SSH_AUTH_SUCCESS) { + 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_retcode = SESS_STAT_ERR_AUTH_DENIED; + return SSH_AUTH_DENIED; + } + } + else if (auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { + bool is_login = false; + for (;;) { + rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL); + if (rc != SSH_AUTH_INFO) + break; + + if(ssh_userauth_kbdint_getnprompts(_this->m_srv_session) != 1) + break; + + rc = ssh_userauth_kbdint_setanswer(_this->m_srv_session, 0, _this->m_user_auth.c_str()); + if (rc < 0) + break; + + // 有时候服务端会再发一个空的提示来完成交互 + rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL); + if (rc == SSH_AUTH_INFO) { + if (ssh_userauth_kbdint_getnprompts(_this->m_srv_session) != 0) + break; + rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL); + if (rc < 0) + break; + } + + if(rc == SSH_AUTH_SUCCESS) + is_login = true; + break; + } + + if (!is_login) { + 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_retcode = SESS_STAT_ERR_AUTH_DENIED; + return SSH_AUTH_DENIED; + } + } + 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) { - ssh_key key = NULL; - 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"); - _this->m_have_error = true; - _this->m_retcode = SESS_STAT_ERR_BAD_SSH_KEY; - return SSH_AUTH_DENIED; - } + if (auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { + ssh_key key = NULL; + 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"); + _this->m_have_error = true; + _this->m_retcode = SESS_STAT_ERR_BAD_SSH_KEY; + return SSH_AUTH_DENIED; + } + + rc = ssh_userauth_publickey(_this->m_srv_session, NULL, key); + if (rc != SSH_OK) { + 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; + } - rc = ssh_userauth_publickey(_this->m_srv_session, NULL, key); - if (rc != SSH_OK) { ssh_key_free(key); - EXLOGE("[ssh] can not use private-key login to real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port); + } + 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); _this->m_have_error = true; _this->m_retcode = SESS_STAT_ERR_AUTH_DENIED; return SSH_AUTH_DENIED; } - ssh_key_free(key); } else if (_this->m_auth_mode == TS_AUTH_MODE_NONE) {