libssh2_userauth_list()函数password认证失败原因

本文解决SSH连接时因服务端禁用密码认证导致无法使用password方式登录的问题。通过修改ssh_config文件,重新启动sshd服务,使能PasswordAuthentication,实现正常SSH密码登录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为libssh2_userauth_list()函数返回值有password、publickey、keyboard-interactive三种方式,具体根据返回值调用对应的认证函数

根据用户名和密码方式验证时,libssh2_userauth_list()返回值中检测不到password/PASSWORD原因服务端密码认证被禁用:
1.cd /etc/ssh
2.vi sshd_config将PasswordAuthentication no中no修改为yes
3.cd /etc/rc.d/
sudo ./sshd restart重启sshd
 

#include "FtSshTool.h" #include <libssh2.h> #include "FtSshChannel.h" #include <libssh2.h> #include <libssh2_sftp.h> #ifdef WIN32 #include <windows.h> #include <winsock2.h> #else #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> #endif #include <sys/stat.h> #include <iostream> #include <string> #include <sys/types.h> #include <fcntl.h> #include <errno.h> #include <stdio.h> #include <ctype.h> #include <filesystem> #include <libssh2.h> #include <libssh2_sftp.h> #define _CRT_SECURE_NO_WARNINGS FtSshTool::FtSshTool(std::string srvIp, int srvPort) :m_srvIp(srvIp), m_srvPort(srvPort) { m_sock = -1; m_session = NULL; SetConsoleOutputCP(65001); //65001 是设置UTF编码 } FtSshTool::~FtSshTool(void) { Disconnect(); libssh2_exit(); } //void FtSshTool::S_KbdCallback(const char* name, int name_len, // const char* instruction, int instruction_len, // int num_prompts, // const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, // LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, // void** abstract) //{ // (void)name; // (void)name_len; // (void)instruction; // (void)instruction_len; // if (num_prompts == 1) // { // // responses[0].text = strdup(s_password.c_str()); // // responses[0].length = (int)s_password.size(); // } // (void)prompts; // (void)abstract; //} bool FtSshTool::Connect(std::string userName, std::string userPwd) { //WSAData wsdData; //int wsaRes = WSAStartup(MAKEWORD(2, 2), &wsdData); //if (wsaRes != 0) //{ // printf("0000"); //} m_sock = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(22); sin.sin_addr.s_addr = inet_addr(m_srvIp.c_str()); if (connect(m_sock, (sockaddr*)(&sin), sizeof(sockaddr_in)) != 0) { Disconnect(); return false; } // 初始化libssh2库 //flag 默认初始化选项 int rc = libssh2_init(0); m_session = libssh2_session_init(); if (libssh2_session_handshake(m_session, m_sock))//会话握手 { Disconnect(); return false; } // libssh2_session_set_blocking(m_session, 0); // 0非阻塞模式 1// 阻塞模式 int auth_pw = 0; std::string fingerprint = libssh2_hostkey_hash(m_session, LIBSSH2_HOSTKEY_HASH_SHA1); /* check what authentication methods are available */ std::string userauthlist = libssh2_userauth_list(m_session, userName.c_str(), (int)userName.size()); if (strstr(userauthlist.c_str(), "password") != NULL) { auth_pw |= 1; } if (strstr(userauthlist.c_str(), "keyboard-interactive") != NULL) { auth_pw |= 2; } if (strstr(userauthlist.c_str(), "publickey") != NULL) { auth_pw |= 4; } if (auth_pw & 1) { /* We could authenticate via password */ // 使用用户名和密码进行身份验证 if (libssh2_userauth_password(m_session, userName.c_str(), userPwd.c_str())) { Disconnect(); return false; } } else if (auth_pw & 2) { /* Or via keyboard-interactive */ // s_password = userPwd; /* if (libssh2_userauth_keyboard_interactive(m_session, userName.c_str(), &S_KbdCallback)) { Disconnect(); return false; }*/ } else { Disconnect(); return false; } return true; } int FtSshTool::Connect(std::string srvIp, std::string userName, std::string userPwd) { //WSAData wsdData; //int wsaRes = WSAStartup(MAKEWORD(2, 2), &wsdData); //if (wsaRes != 0) //{ // printf("0000"); //} m_sock = socket(AF_INET, SOCK_STREAM, 0); if (m_sock < 0) { std::cerr << "Cannot create socket" << std::endl; return -5; } sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(22); sin.sin_addr.s_addr = inet_addr(srvIp.c_str()); if (connect(m_sock, (sockaddr*)(&sin), sizeof(sockaddr_in)) != 0) { std::cout << "connect Failed " << std::endl; Disconnect(); return -3; } // 初始化libssh2库 //flag 默认初始化选项 int rc = libssh2_init(0); if (rc != 0) { Disconnect(); return -1; // 初始化失败 } // 创建SSH会话 m_session = libssh2_session_init(); if (!m_session) { Disconnect(); return -2; // 创建会话失败 } // 设置会话选项 libssh2_session_set_blocking(m_session, 1);// 0非阻塞模式 1// 阻塞模式 libssh2_session_set_timeout(m_session,30*1000); // 连接到远程主机 rc = libssh2_session_startup(m_session, m_sock); if (rc != 0) { // 连接失败 Disconnect(); return -3; } // 使用用户名和密码进行身份验证(用户名和密码) rc = libssh2_userauth_password(m_session, userName.c_str(), userPwd.c_str()); if (rc != 0) { // 身份验证失败 libssh2_session_disconnect(m_session, "Authentication failed"); libssh2_session_free(m_session); Disconnect(); return -4; } return 0; } int FtSshTool::Connect(std::string localIp, std::string srvIp, std::string userName, std::string userPwd) { // 很重要,否则m_sock 创建失败 //WSAData wsdData; //int wsaRes = WSAStartup(MAKEWORD(2, 2), &wsdData); //if (wsaRes != 0) //{ // printf("0000"); //} m_sock = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(22); sin.sin_addr.s_addr = inet_addr(srvIp.c_str()); // 绑定客户端socket到特定的本地IP地址 struct sockaddr_in local_addr; memset(&local_addr, 0, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_port = htons(0); // 随机选择一个可用的本地端口 local_addr.sin_addr.s_addr = inet_addr(localIp.c_str()); // 客户端的本地IP地址 if (bind(m_sock, (struct sockaddr*)&local_addr, sizeof(local_addr)) == SOCKET_ERROR) { // std::cerr << "Bind failed" << std::endl; perror("Bind "); //return 1; } else { std::cout << "Bind Success" << localIp<< std::endl; } if (connect(m_sock, (sockaddr*)(&sin), sizeof(sockaddr_in)) != 0) { perror("connect "); Disconnect(); return -3; } // 初始化libssh2库 //flag 默认初始化选项 int rc = libssh2_init(0); if (rc != 0) { Disconnect(); return -1; // 初始化失败 } // 创建SSH会话 m_session = libssh2_session_init(); if (!m_session) { Disconnect(); return -2; // 创建会话失败 } // 设置会话选项 libssh2_session_set_blocking(m_session, 1);// 0非阻塞模式 1// 阻塞模式 libssh2_session_set_timeout(m_session, 30 * 1000); // 连接到远程主机 rc = libssh2_session_startup(m_session, m_sock); if (rc != 0) { // 连接失败 Disconnect(); return -3; } // 使用用户名和密码进行身份验证(用户名和密码) rc = libssh2_userauth_password(m_session, userName.c_str(), userPwd.c_str()); if (rc != 0) { // 身份验证失败 libssh2_session_disconnect(m_session, "Authentication failed"); //libssh2_session_free(m_session); Disconnect(); return -4; } return 0; } bool FtSshTool::Disconnect(void) { //WSACleanup(); if (m_session) { libssh2_session_disconnect(m_session, "Bye bye, Thank you"); libssh2_session_free(m_session); m_session = NULL; } if (m_sock != -1) { #ifdef WIN32 closesocket(m_sock); #else close(m_sock); #endif m_sock = -1; } return true; } std::shared_ptr<Channel> FtSshTool::CreateChannel(const std::string& ptyType) { if (NULL == m_session) { return NULL; } LIBSSH2_CHANNEL* channel = NULL; /* Request a shell */ if (!(channel = libssh2_channel_open_session(m_session))) { return NULL; } /* Request a terminal with 'vanilla' terminal emulation * See /etc/termcap for more options */ if (libssh2_channel_request_pty(channel, ptyType.c_str())) { libssh2_channel_free(channel); return NULL; } /* Open a SHELL on that pty */ if (libssh2_channel_shell(channel)) { libssh2_channel_free(channel); return NULL; } std::shared_ptr < Channel> pChannel = std::make_shared<Channel>(channel); // Channel* ret = new Channel(channel); std::cout << pChannel->Read() << std::endl; return pChannel; } bool FtSshTool::Scp(std::string localfile, std::string remotefile) { FILE* local = NULL; int size = 0; try { struct stat file_info; size = std::filesystem::file_size(localfile); // Send the file struct stat file_status; // 获取文件状态 if (stat(localfile.c_str(), &file_status) == -1) { std::cerr << "Error: Unable to get file status for " << localfile << std::endl; return 1; } LIBSSH2_CHANNEL* channel = libssh2_scp_send64(m_session, remotefile.c_str(), 0644, size, file_status.st_mtime, file_status.st_atime); if (!channel) { char* errmsg; int errlen; int err = libssh2_session_last_error(m_session, &errmsg, &errlen, 0); fprintf(stderr, "Unable to open a session: (%d) %s\n", err, errmsg); } char mem[1024]; size_t nread; char* ptr; fprintf(stderr, "SCP session waiting to send file\n"); local = fopen(localfile.c_str(), "rb"); if (!local) { fprintf(stderr, "Cannot open local file %s\n", localfile.c_str()); return 1; } do { nread = fread(mem, 1, sizeof(mem), local); if (nread <= 0) { fclose(local); break; } ptr = mem; do { ssize_t nwritten; /* write the same data over and over, until error or completion */ nwritten = libssh2_channel_write(channel, ptr, nread); if (nwritten < 0) { fprintf(stderr, "ERROR %ld\n", (long)nwritten); break; } else { /* nwritten indicates how many bytes were written this time */ ptr += nwritten; nread -= (size_t)nwritten; } } while (nread); } while (1); if (local) fclose(local); libssh2_channel_send_eof(channel); fprintf(stderr, "Waiting for EOF\n"); libssh2_channel_wait_eof(channel); fprintf(stderr, "Waiting for channel to close\n"); libssh2_channel_wait_closed(channel); libssh2_channel_free(channel); channel = NULL; return true; } catch (...) { if (local) fclose(local); return false; } } bool FtSshTool::ScpAll(std::string localpath, std::string remotePath) { // 检查路径是否存在 if (!std::filesystem::exists(localpath)) { std::cerr << "Directory does not exist: " << localpath << std::endl; return false; } // 遍历文件夹中的所有项 for (const auto& entry : std::filesystem::directory_iterator(localpath)) { if (std::filesystem::is_directory(entry)) { } else { Scp(entry.path().string(), remotePath + "/"+ entry.path().filename().string()); } } return false; } bool FtSshTool::ScpDirectory(std::string localdirectory, std::string remotedirectory) { // 检查路径是否存在 if (!std::filesystem::exists(localdirectory)) { std::cerr << "Directory does not exist: " << localdirectory << std::endl; return false; } std::shared_ptr<Channel>pchannel = this->CreateChannel(); std::string cmd_cd = "mkdir -p " + remotedirectory; pchannel->Write(cmd_cd); // 遍历文件夹中的所有项 for (const auto& entry : std::filesystem::directory_iterator(localdirectory)) { if (std::filesystem::is_directory(entry)) { std::string cmd_cd = "mkdir -p " + remotedirectory + "/" + entry.path().filename().string(); pchannel->Write(cmd_cd); Scp(entry.path().string(), remotedirectory + "/" + entry.path().filename().string()); std::cout << cmd_cd << std::endl; } else { Scp(entry.path().string(), remotedirectory + "/" + entry.path().filename().string()); std::string cmd_cd = "cd "+ remotedirectory +"; chmod 777 -R ./*;"; pchannel->Write(cmd_cd); std::cout << cmd_cd << std::endl; } } return true; } bool FtSshTool::KillProcessByName(std::string processName) { // 构建完整的WinSCP命令 //std::string commandLine = mWinscpPath + " /command " // "open ssh://" + mUsername + ":" + mPassword + "@" + mHost + // "call ps -ef|grep " + processName + " |grep -v grep |awk '{print $2}'|xargs kill -2" // " /log=log.txt exit"; // 将执行结果保存到日志文件 //// 执行命令 //system(commandLine.c_str()); return true; } 是用scp方法的时候,libssh2_channel_write返回-39的错误原因
07-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值