aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Weingärtner <timo@tiwe.de>2021-04-18 00:02:42 +0200
committerTimo Weingärtner <timo@tiwe.de>2026-03-07 18:51:05 +0100
commitd17162f5c6f7d002bf68fac48bcadd2db0c033e7 (patch)
tree811c77fcc9068179420395c00dec1d0dcecf6340
parent013ca71f8e07f462266f5c795930739b37c6d5fb (diff)
downloadssh-agent-filter-d17162f5c6f7d002bf68fac48bcadd2db0c033e7.tar.gz
use C++17 std::optional for dissectors, refactor
-rw-r--r--ssh-agent-filter.C63
1 files changed, 35 insertions, 28 deletions
diff --git a/ssh-agent-filter.C b/ssh-agent-filter.C
index e98123c..c513804 100644
--- a/ssh-agent-filter.C
+++ b/ssh-agent-filter.C
@@ -64,6 +64,8 @@ using std::pair;
using std::mutex;
using std::lock_guard;
+#include <optional>
+
#include <chrono>
#include <cerrno>
@@ -326,9 +328,10 @@ bool confirm (string const & question) {
}
}
-bool dissect_auth_data_ssh_cert (rfc4251::string const & data, string & request_description) try {
+std::optional<string> dissect_auth_data_ssh_cert (rfc4251::string const & data) try {
io::stream<io::array_source> datastream{data.data(), data.size()};
arm(datastream);
+ string request_description{};
// Format specified in https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=1.13
rfc4251::string keytype{datastream};
@@ -337,10 +340,10 @@ bool dissect_auth_data_ssh_cert (rfc4251::string const & data, string & request_
// check for and remove suffix to get the base keytype
std::string const suffix{"-cert-v01@openssh.com"};
if (keytype_str.length() <= suffix.length())
- return false;
+ return {};
auto suffix_start = keytype_str.end() - suffix.length();
if (!std::equal(suffix.begin(), suffix.end(), suffix_start))
- return false;
+ return {};
keytype_str.erase(suffix_start, keytype_str.end());
}
rfc4251::string nonce{datastream};
@@ -365,7 +368,7 @@ bool dissect_auth_data_ssh_cert (rfc4251::string const & data, string & request_
rfc4251::string pk{datastream};
key_to_be_signed << rfc4251::string{keytype_str} << pk;
} else {
- return false;
+ return {};
}
rfc4251::uint64 serial{datastream};
rfc4251::uint32 type{datastream};
@@ -380,14 +383,15 @@ bool dissect_auth_data_ssh_cert (rfc4251::string const & data, string & request_
request_description = "The request is for a certificate signature on key " + base64_encode(key_to_be_signed.str()) + ".";
- return true;
+ return request_description;
} catch (...) {
- return false;
+ return {};
}
-bool dissect_auth_data_ssh (rfc4251::string const & data, string & request_description) try {
+std::optional<string> dissect_auth_data_ssh (rfc4251::string const & data) try {
io::stream<io::array_source> datastream{data.data(), data.size()};
arm(datastream);
+ string request_description{};
// Format specified in RFC 4252 Section 7
rfc4251::string session_identifier{datastream};
@@ -450,11 +454,25 @@ bool dissect_auth_data_ssh (rfc4251::string const & data, string & request_descr
}
} catch (...) {}
- return true;
+ return request_description;
} catch (...) {
- return false;
+ return {};
+}
+
+string describe_sign_request (rfc4251::string const & data_to_be_signed) {
+ auto const dissectors = {
+ dissect_auth_data_ssh_cert,
+ dissect_auth_data_ssh,
+ };
+ std::optional<string> request_description;
+ for (auto const dissector : dissectors)
+ if (request_description = dissector(data_to_be_signed); request_description)
+ break;
+
+ return request_description.value_or("The request format is unknown.");
}
+
rfc4251::string handle_request (rfc4251::string const & r) {
io::stream<io::array_source> request{r.data(), r.size()};
rfc4251::string ret;
@@ -492,30 +510,19 @@ rfc4251::string handle_request (rfc4251::string const & r) {
case SSH2_AGENTC_SIGN_REQUEST:
{
rfc4251::string key{request};
- rfc4251::string data{request};
+ rfc4251::string data_to_be_signed{request};
rfc4251::uint32 flags{request};
bool allow{false};
if (allowed_pubkeys.count(key))
allow = true;
- else {
- if (auto it = confirmed_pubkeys.find(key); it != confirmed_pubkeys.end()) {
- string request_description;
- bool dissect_ok{false};
- if (!dissect_ok)
- dissect_ok = dissect_auth_data_ssh_cert(data, request_description);
- if (!dissect_ok)
- dissect_ok = dissect_auth_data_ssh(data, request_description);
- if (!dissect_ok)
- request_description = "The request format is unknown.";
-
- string question = "Something behind the ssh-agent-filter";
- if (saf_name.length())
- question += " named '" + saf_name + "'";
- question += " requested use of the key named '" + it->second + "'.\n";
- question += request_description;
- allow = confirm(question);
- }
+ else if (auto it = confirmed_pubkeys.find(key); it != confirmed_pubkeys.end()) {
+ string question = "Something behind the ssh-agent-filter";
+ if (saf_name.length())
+ question += " named '" + saf_name + "'";
+ question += " requested use of the key named '" + it->second + "'.\n";
+ question += describe_sign_request(data_to_be_signed);
+ allow = confirm(question);
}
if (allow) {