Skip to content

Commit 17fad92

Browse files
authored
Bugfix/Ensure libssh is initialized (#4812)
After migrating libssh to vcpkg, it started linking statically against the binary. With dynamic linkage, the DllMain function was [already calling ssh_init()](https://github.com/canonical/libssh/blob/f23d1454e50d0dbb314edd9bf4227ab72303484b/src/init.c#L257) so everything was working as intended. This is no longer the case since DllMain is not being invoked in static linkage. Linux and macOS are still fine since there's the [libssh_constructor](https://github.com/canonical/libssh/blob/f23d1454e50d0dbb314edd9bf4227ab72303484b/src/init.c#L59) func marked with `__attribute__((constructor))`, which works with gcc/clang but not with MSVC. This PR ensures that the library is initialized before first use for both the daemon and the CLI. <!-- Please include a summary of the changes and the motivation behind them. --> - What does this PR do? Ensures libssh is initialized. - Why is this change needed? Fix broken SSH in Windows. MULTI-2535
2 parents 13a02c9 + 54f99ab commit 17fad92

6 files changed

Lines changed: 70 additions & 1 deletion

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (C) Canonical, Ltd.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; version 3.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License
14+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
*
16+
*/
17+
18+
#pragma once
19+
20+
namespace multipass
21+
{
22+
struct LibsshScopeGuard
23+
{
24+
LibsshScopeGuard();
25+
~LibsshScopeGuard();
26+
};
27+
} // namespace multipass

src/client/cli/main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <multipass/cli/client_common.h>
2121
#include <multipass/console.h>
2222
#include <multipass/constants.h>
23+
#include <multipass/ssh/libssh_scope_guard.h>
2324
#include <multipass/top_catch_all.h>
2425

2526
#include <QCoreApplication>
@@ -53,5 +54,7 @@ int main(int argc, char* argv[])
5354
// compatible with the version of the headers we compiled against.
5455
GOOGLE_PROTOBUF_VERIFY_VERSION;
5556

57+
multipass::LibsshScopeGuard libssh_guard;
58+
5659
return mp::top_catch_all("client", /* fallback_return = */ EXIT_FAILURE, main_impl, argc, argv);
5760
}

src/daemon/daemon_main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <multipass/logging/log.h>
2727
#include <multipass/platform_unix.h>
2828
#include <multipass/signal.h>
29+
#include <multipass/ssh/libssh_scope_guard.h>
2930
#include <multipass/top_catch_all.h>
3031
#include <multipass/utils.h>
3132
#include <multipass/version.h>
@@ -125,6 +126,8 @@ int main(int argc, char* argv[])
125126
// compatible with the version of the headers we compiled against.
126127
GOOGLE_PROTOBUF_VERIFY_VERSION;
127128

129+
multipass::LibsshScopeGuard libssh_guard;
130+
128131
mp::Signal app_ready_signal{};
129132
//
130133
// Register the signal handler as the first thing so the signal handler won't miss

src/daemon/daemon_main_win.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <multipass/format.h>
2727
#include <multipass/logging/log.h>
2828
#include <multipass/platform.h>
29+
#include <multipass/ssh/libssh_scope_guard.h>
2930
#include <multipass/ssl_cert_provider.h>
3031
#include <multipass/standard_paths.h>
3132
#include <multipass/utils.h>
@@ -203,6 +204,8 @@ try
203204
// compatible with the version of the headers we compiled against.
204205
GOOGLE_PROTOBUF_VERIFY_VERSION;
205206

207+
multipass::LibsshScopeGuard libssh_guard;
208+
206209
service_argv.assign(argv, argv + argc);
207210

208211
auto logger = mp::platform::make_logger(mpl::Level::info);

src/ssh/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ function(add_ssh_target TARGET_NAME)
1818
openssh_key_provider.cpp
1919
ssh_client_key_provider.cpp
2020
ssh_process.cpp
21-
ssh_session.cpp)
21+
ssh_session.cpp
22+
libssh_scope_guard.cpp)
2223

2324
target_link_libraries(${TARGET_NAME}
2425
fmt::fmt-header-only

src/ssh/libssh_scope_guard.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) Canonical, Ltd.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; version 3.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License
14+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
*
16+
*/
17+
18+
#include <multipass/ssh/libssh_scope_guard.h>
19+
20+
#include "libssh/libssh.h"
21+
22+
namespace mp = multipass;
23+
24+
mp::LibsshScopeGuard::LibsshScopeGuard()
25+
{
26+
ssh_init();
27+
}
28+
29+
mp::LibsshScopeGuard::~LibsshScopeGuard()
30+
{
31+
ssh_finalize();
32+
}

0 commit comments

Comments
 (0)