Merge pull request #5290 from edolstra/ssh-nologin

SSHStore / LegacySSHStore: Show better error if the remote's stdout is polluted
This commit is contained in:
Eelco Dolstra 2021-09-23 23:14:30 +02:00 committed by GitHub
commit 87de086e1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 46 additions and 6 deletions

View file

@ -82,9 +82,20 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor
conn->to << SERVE_MAGIC_1 << SERVE_PROTOCOL_VERSION; conn->to << SERVE_MAGIC_1 << SERVE_PROTOCOL_VERSION;
conn->to.flush(); conn->to.flush();
unsigned int magic = readInt(conn->from); StringSink saved;
try {
TeeSource tee(conn->from, saved);
unsigned int magic = readInt(tee);
if (magic != SERVE_MAGIC_2) if (magic != SERVE_MAGIC_2)
throw Error("protocol mismatch with 'nix-store --serve' on '%s'", host); throw Error("'nix-store --serve' protocol mismatch from '%s'", host);
} catch (SerialisationError & e) {
/* In case the other side is waiting for our input,
close it. */
conn->sshConn->in.close();
auto msg = conn->from.drain();
throw Error("'nix-store --serve' protocol mismatch from '%s', got '%s'",
host, chomp(*saved.s + msg));
}
conn->remoteVersion = readInt(conn->from); conn->remoteVersion = readInt(conn->from);
if (GET_PROTOCOL_MAJOR(conn->remoteVersion) != 0x200) if (GET_PROTOCOL_MAJOR(conn->remoteVersion) != 0x200)
throw Error("unsupported 'nix-store --serve' protocol version on '%s'", host); throw Error("unsupported 'nix-store --serve' protocol version on '%s'", host);

View file

@ -162,8 +162,19 @@ void RemoteStore::initConnection(Connection & conn)
try { try {
conn.to << WORKER_MAGIC_1; conn.to << WORKER_MAGIC_1;
conn.to.flush(); conn.to.flush();
unsigned int magic = readInt(conn.from); StringSink saved;
if (magic != WORKER_MAGIC_2) throw Error("protocol mismatch"); try {
TeeSource tee(conn.from, saved);
unsigned int magic = readInt(tee);
if (magic != WORKER_MAGIC_2)
throw Error("protocol mismatch");
} catch (SerialisationError & e) {
/* In case the other side is waiting for our input, close
it. */
conn.closeWrite();
auto msg = conn.from.drain();
throw Error("protocol mismatch, got '%s'", chomp(*saved.s + msg));
}
conn.from >> conn.daemonVersion; conn.from >> conn.daemonVersion;
if (GET_PROTOCOL_MAJOR(conn.daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION)) if (GET_PROTOCOL_MAJOR(conn.daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION))

View file

@ -125,7 +125,6 @@ public:
struct Connection struct Connection
{ {
AutoCloseFD fd;
FdSink to; FdSink to;
FdSource from; FdSource from;
unsigned int daemonVersion; unsigned int daemonVersion;
@ -133,6 +132,8 @@ public:
virtual ~Connection(); virtual ~Connection();
virtual void closeWrite() = 0;
std::exception_ptr processStderr(Sink * sink = 0, Source * source = 0, bool flush = true); std::exception_ptr processStderr(Sink * sink = 0, Source * source = 0, bool flush = true);
}; };

View file

@ -57,6 +57,11 @@ private:
struct Connection : RemoteStore::Connection struct Connection : RemoteStore::Connection
{ {
std::unique_ptr<SSHMaster::Connection> sshConn; std::unique_ptr<SSHMaster::Connection> sshConn;
void closeWrite() override
{
sshConn->in.close();
}
}; };
ref<RemoteStore::Connection> openConnection() override; ref<RemoteStore::Connection> openConnection() override;

View file

@ -45,6 +45,12 @@ std::string UDSRemoteStore::getUri()
} }
void UDSRemoteStore::Connection::closeWrite()
{
shutdown(fd.get(), SHUT_WR);
}
ref<RemoteStore::Connection> UDSRemoteStore::openConnection() ref<RemoteStore::Connection> UDSRemoteStore::openConnection()
{ {
auto conn = make_ref<Connection>(); auto conn = make_ref<Connection>();

View file

@ -40,6 +40,12 @@ public:
private: private:
struct Connection : RemoteStore::Connection
{
AutoCloseFD fd;
void closeWrite() override;
};
ref<RemoteStore::Connection> openConnection() override; ref<RemoteStore::Connection> openConnection() override;
std::optional<std::string> path; std::optional<std::string> path;
}; };