File kdump-sftp-init-session.patch of Package kdump
From: Petr Tesarik <ptesarik@suse.cz>
Date: Tue, 14 Apr 2015 11:40:43 +0200
Subject: Initialize an SFTP session
References: FATE#318874, bsc#917747
Patch-mainline: v0.8.16
Git-commit: b3e46fd6db3e681915a1a686805bbdf24563a938
Implement the initial SFTP request-response handling.
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
---
kdumptool/sshtransfer.cc | 67 +++++++++++++++++++++++++++++++++++++++++++++++
kdumptool/sshtransfer.h | 16 +++++++++++
2 files changed, 83 insertions(+)
--- a/kdumptool/sshtransfer.cc
+++ b/kdumptool/sshtransfer.cc
@@ -368,6 +368,18 @@ SFTPTransfer::SFTPTransfer(const RootDir
m_fdreq = m_process.getPipeFD(STDIN_FILENO);
m_fdresp = m_process.getPipeFD(STDOUT_FILENO);
+
+ SFTPPacket initpkt;
+ initpkt.addByte(SSH_FXP_INIT);
+ initpkt.addInt32(MY_PROTO_VER);
+ sendPacket(initpkt);
+ recvPacket(initpkt);
+ unsigned char type = initpkt.getByte();
+ if (type != SSH_FXP_VERSION)
+ throw KError(KString("Invalid response to SSH_FXP_INIT: type ") +
+ Stringutil::number2string(unsigned(type)));
+ m_proto_ver = initpkt.getInt32();
+ Debug::debug()->dbg("Remote SFTP version %lu", m_proto_ver);
}
/* -------------------------------------------------------------------------- */
@@ -424,4 +436,59 @@ StringVector SFTPTransfer::makeArgs(void
return ret;
}
+/* -------------------------------------------------------------------------- */
+void SFTPTransfer::sendPacket(SFTPPacket &pkt)
+{
+ const ByteVector bv = pkt.update();
+ const unsigned char *bufp = bv.data();
+ size_t buflen = bv.size();
+
+ while (buflen) {
+ ssize_t len = write(m_fdreq, bufp, buflen);
+ if (len < 0)
+ throw KSystemError("SFTPTransfer::sendPacket: write failed",
+ errno);
+ bufp += len;
+ buflen -= len;
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void SFTPTransfer::recvBuffer(unsigned char *bufp, size_t buflen)
+{
+ while (buflen) {
+ ssize_t len = read(m_fdresp, bufp, buflen);
+ if (len < 0)
+ throw KSystemError("SFTPTransfer::recvPacket: read failed",
+ errno);
+ else if (!len)
+ throw KError("SFTPTransfer::recvPacket: unexpected EOF");
+
+ bufp += len;
+ buflen -= len;
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void SFTPTransfer::recvPacket(SFTPPacket &pkt)
+{
+ ByteVector buffer;
+
+ buffer.resize(sizeof(uint32_t));
+ recvBuffer(buffer.data(), sizeof(uint32_t));
+ pkt.setData(buffer);
+ size_t length = pkt.getInt32();
+
+ buffer.resize(BUFSIZ);
+ while (length > 0) {
+ if (buffer.size() > length)
+ buffer.resize(length);
+
+ recvBuffer(buffer.data(), buffer.size());
+ pkt.addByteVector(buffer);
+
+ length -= buffer.size();
+ }
+}
+
//}}}
--- a/kdumptool/sshtransfer.h
+++ b/kdumptool/sshtransfer.h
@@ -117,6 +117,14 @@ typedef KCodeError<KSFTPErrorCode> KSFTP
//{{{ SFTPPacket ---------------------------------------------------------------
/**
+ * Packet types defined by protocol (incomplete list)
+ */
+enum {
+ SSH_FXP_INIT = 1,
+ SSH_FXP_VERSION = 2,
+};
+
+/**
* Encode/decode an SFTP packet.
*/
class SFTPPacket {
@@ -196,11 +204,19 @@ class SFTPTransfer : public URLTransfer
bool *directSave)
throw (KError);
+ protected:
+ static const int MY_PROTO_VER = 3; // our advertised version
+
private:
SubProcess m_process;
int m_fdreq, m_fdresp;
+ unsigned long m_proto_ver; // remote SFTP protocol version
StringVector makeArgs(void);
+
+ void sendPacket(SFTPPacket &pkt);
+ void recvPacket(SFTPPacket &pkt);
+ void recvBuffer(unsigned char *bufp, size_t buflen);
};
//}}}