【发布时间】:2017-04-21 00:55:44
【问题描述】:
免责声明:我正在谷歌上搜索
- 使用 C++
- 两端都是Linux
- 我可以通过 TCPDUMP 看到远端的 SSH 连接
- 除 0 外没有构建错误或返回代码(调试表明一切正常)
- TCPPDUMP 似乎无法传输足够的数据(它是一个 2MB 的文件*)
- 据我所知,连接/身份验证/授权正在正常进行
当我去远端寻找应该被复制的文件时,它不存在。我试过更新b并找到“文件”,但找不到。
提前感谢您提供任何可能的见解!
SSH 功能(身份验证和连接)因“最小、完整和可验证示例”而被清除,因为它们似乎工作正常*
#include <cstdio>
#include <string>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <curl/curl.h>
#include <boost/regex.hpp>
#include <boost/system/error_code.hpp>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <x86_64-linux-gnu/sys/stat.h>
#define LIBSSH_STATIC 1
#include <libssh/libssh.h>
using namespace std;
int sourcePull(void)
{
CURL *curl;
FILE *fp;
CURLcode res;
char *url = "https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset";
char outfilename[FILENAME_MAX] = "fireHOL";
curl = curl_easy_init();
if (curl)
{
fp = fopen(outfilename, "wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
return 0;
}
int sourceParse()
{
//Regex for IP's in sourcePull result
ifstream infile("fireHOL");
string ipAddress;
boost::regex expr1("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
boost::regex expr2("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$");
boost::smatch matches;
while (infile >> ipAddress)
{
if (boost::regex_match(ipAddress, matches, expr1))
{
ofstream checkpoint;
checkpoint.open("samp_batch.txt", ios::out | ios::app);
checkpoint << "add -t 86400 -a d -l r -o icewall ip -s " << ipAddress << endl;
checkpoint << "add -t 86400 -a r -l r -o icewall ip -d " << ipAddress << endl;
}
if (boost::regex_match(ipAddress, matches, expr2))
{
ofstream checkpoint;
checkpoint.open("samp_batch.txt", ios::out | ios::app);
checkpoint << "add -t 86400 -a d -l r -o icewall ip -s " << ipAddress << endl;
checkpoint << "add -t 86400 -a r -l r -o icewall ip -d " << ipAddress << endl;
}
}
ofstream terminate;
terminate.open("samp_batch.txt", ios::out | ios::app);
terminate << "EOF";
return 0;
}
int fileSize()
{
int size;
streampos begin, end;
ifstream inputFile("samp_batch", ios::binary);
begin = inputFile.tellg();
inputFile.seekg(0, ios::end);
end = inputFile.tellg();
inputFile.close();
return size;
}
int ssh()
{
ssh_session my_ssh_session;
ssh_scp scp;
int port = 22;
int rc;
int method;
char password[128] = { 0 };
char *banner;
//open session & set options
my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
exit(-1);
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "XXX.XXX.XXX.XXX");
ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, "security");
//connect to server
rc = ssh_connect(my_ssh_session);
if (rc != SSH_OK)
{
fprintf(stderr, "Error connecting to host: %s\n", ssh_get_error(my_ssh_session));
ssh_free(my_ssh_session);
exit(-1);
}
//verify the servers identity
if (verify_knownHost(my_ssh_session) < 0)
{
fprintf(stdout, "unkown host\n");
ssh_disconnect(my_ssh_session);
ssh_free(my_ssh_session);
exit(-1);
}
// Try to authenticate
rc = ssh_userauth_none(my_ssh_session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(my_ssh_session);
return rc;
}
method = ssh_auth_list(my_ssh_session);
while (rc != SSH_AUTH_SUCCESS) {
// Try to authenticate with public key first
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
rc = ssh_userauth_autopubkey(my_ssh_session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(my_ssh_session);
return rc;
}
else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
return rc;
//SCP samp_batch file here
const int length = fileSize();
const char *fileName = "samp_batch";
ifstream inputFile(fileName);
constexpr size_t bufferSize = 1024 * 1024 * 1024;
unique_ptr<char[]> buffer(new char[bufferSize]);
const void* cvp = &buffer;
rc = ssh_scp_push_file(scp, "samp_batch", length, 0777);
if (rc != SSH_OK)
{
fprintf(stderr, "Can't open remote file: %s\n", ssh_get_error(my_ssh_session));
ssh_free(my_ssh_session);
exit(-1);
}
while (inputFile)
{
inputFile.read(buffer.get(), 1024 * 1024 * 1024);
rc = ssh_scp_write(scp, cvp, bufferSize);
if (rc != SSH_OK)
{
fprintf(stderr, "Cant write to remote file: %s\n", ssh_get_error(my_ssh_session));
ssh_free(my_ssh_session);
exit(-1);
}
}
return SSH_OK;
////execute remote command here
//ssh_free(my_ssh_session);
}
int main()
{
sourcePull();
sourceParse();
ssh();
return 0;
}
【问题讨论】:
-
为什么
fileSize()不把文件名作为参数?就像现在一样,您正在查看两个不同的文件。一个用于获取大小,一个用于读取。 -
我已经将它“编码”了,因为它将被设置在一个计时工作上并且不理会,但这是一个错误,谢谢。编辑帖子以反映它仍然无法正常工作:(。它也是一个不会改变的常量文件名*
-
rc = ssh_scp_write(scp, cvp, bufferSize);你在这里写出了整个缓冲区。您应该只写从输入文件中读取的字节数。还考虑到您的缓冲区大小为 1GB,如果您没有通过 tcpdump 看到那么多流量,则表明您的程序甚至没有达到这一点。你需要这么大的缓冲区吗?超过 32k-64k 的任何东西都可能是浪费。 -
编辑了更多细节@Jonas