libnetconf-cpp: support specifying callback for keyboard-interactive auth
Change-Id: Id51e0b65ac2e28698b69a358df3c554579618bf6
diff --git a/src/netconf-client.cpp b/src/netconf-client.cpp
index 73d8433..f1cdfe2 100644
--- a/src/netconf-client.cpp
+++ b/src/netconf-client.cpp
@@ -6,6 +6,7 @@
*
*/
+#include <cstring>
#include <libyang/Tree_Data.hpp>
#include <mutex>
extern "C" {
@@ -13,6 +14,7 @@
}
#include <sstream>
#include "netconf-client.h"
+#include "UniqueResource.h"
namespace libnetconf {
@@ -58,6 +60,13 @@
nc_reply_free(reinterpret_cast<nc_reply*>(reply));
}
+char *ssh_auth_interactive_cb(const char *auth_name, const char *instruction, const char *prompt, int echo, void *priv)
+{
+ const auto cb = static_cast<const client::KbdInteractiveCb*>(priv);
+ auto res = (*cb)(auth_name, instruction, prompt, echo);
+ return ::strdup(res.c_str());
+}
+
template <auto fn>
using deleter_from_fn = std::integral_constant<decltype(fn), fn>;
@@ -222,6 +231,27 @@
return session;
}
+std::unique_ptr<Session> Session::connectKbdInteractive(const std::string& host, const uint16_t port, const std::string& user, const KbdInteractiveCb& callback)
+{
+ impl::ClientInit::instance();
+
+ std::lock_guard lk(impl::clientOptions);
+ auto cb_guard = make_unique_resource([user, &callback]() {
+ nc_client_ssh_set_username(user.c_str());
+ nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 5);
+ nc_client_ssh_set_auth_interactive_clb(impl::ssh_auth_interactive_cb, static_cast<void *>(&const_cast<KbdInteractiveCb&>(callback)));
+ }, []() {
+ nc_client_ssh_set_auth_interactive_clb(nullptr, nullptr);
+ nc_client_ssh_set_username(nullptr);
+ });
+
+ auto session = std::make_unique<Session>(nc_connect_ssh(host.c_str(), port, nullptr));
+ if (!session->m_session) {
+ throw std::runtime_error{"nc_connect_ssh failed"};
+ }
+ return session;
+}
+
std::unique_ptr<Session> Session::connectSocket(const std::string& path)
{
impl::ClientInit::instance();