VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/CloudGateway.cpp@ 108379

最後變更 在這個檔案從108379是 107583,由 vboxsync 提交於 2 月 前

src/VBox/Main/src-client/CloudGateway.cpp: Fixed warnings found by Parfait (assignment unused) [build fix]. jiraref:VBP-1424

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 9.5 KB
 
1/* $Id: CloudGateway.cpp 107583 2025-01-09 10:19:23Z vboxsync $ */
2/** @file
3 * Implementation of local and cloud gateway management.
4 */
5
6/*
7 * Copyright (C) 2019-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.alldomusa.eu.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define LOG_GROUP LOG_GROUP_MAIN_CONSOLE
29
30/* Make sure all the stdint.h macros are included - must come first! */
31#ifndef __STDC_LIMIT_MACROS
32# define __STDC_LIMIT_MACROS
33#endif
34#ifndef __STDC_CONSTANT_MACROS
35# define __STDC_CONSTANT_MACROS
36#endif
37
38#include "LoggingNew.h"
39#include "ApplianceImpl.h"
40#include "CloudNetworkImpl.h"
41#include "CloudGateway.h"
42
43#include <iprt/http.h>
44#include <iprt/inifile.h>
45#include <iprt/net.h>
46#include <iprt/path.h>
47#include <iprt/vfs.h>
48#include <iprt/uri.h>
49#ifdef DEBUG
50#include <iprt/file.h>
51#include <VBox/com/utils.h>
52#endif
53
54#ifdef VBOX_WITH_LIBSSH
55/* Prevent inclusion of Winsock2.h */
56#define _WINSOCK2API_
57#include <libssh/libssh.h>
58#endif /* VBOX_WITH_LIBSSH */
59
60
61static HRESULT setMacAddress(const Utf8Str& str, RTMAC& mac)
62{
63 int vrc = RTNetStrToMacAddr(str.c_str(), &mac);
64 if (RT_FAILURE(vrc))
65 {
66 LogRel(("CLOUD-NET: Invalid MAC address '%s'\n", str.c_str()));
67 return E_INVALIDARG;
68 }
69 return S_OK;
70}
71
72
73HRESULT GatewayInfo::setCloudMacAddress(const Utf8Str& mac)
74{
75 return setMacAddress(mac, mCloudMacAddress);
76}
77
78
79HRESULT GatewayInfo::setLocalMacAddress(const Utf8Str& mac)
80{
81 return setMacAddress(mac, mLocalMacAddress);
82}
83
84
85class CloudError
86{
87public:
88 CloudError(HRESULT hrc, const Utf8Str& strText) : mHrc(hrc), mText(strText) {};
89 HRESULT getRc() { return mHrc; };
90 Utf8Str getText() { return mText; };
91
92private:
93 HRESULT mHrc;
94 Utf8Str mText;
95};
96
97
98static void handleErrors(HRESULT hrc, const char *pszFormat, ...)
99{
100 if (FAILED(hrc))
101 {
102 va_list va;
103 va_start(va, pszFormat);
104 Utf8Str strError(pszFormat, va);
105 va_end(va);
106 LogRel(("CLOUD-NET: %s (hrc=%x)\n", strError.c_str(), hrc));
107 throw CloudError(hrc, strError);
108 }
109
110}
111
112
113class CloudClient
114{
115public:
116 CloudClient(ComPtr<IVirtualBox> virtualBox, const Bstr& strProvider, const Bstr& strProfile);
117 ~CloudClient() {};
118
119 void startCloudGateway(const ComPtr<ICloudNetwork> &network, GatewayInfo& gateway);
120 void stopCloudGateway(const GatewayInfo& gateway);
121
122private:
123 ComPtr<ICloudProviderManager> mManager;
124 ComPtr<ICloudProvider> mProvider;
125 ComPtr<ICloudProfile> mProfile;
126 ComPtr<ICloudClient> mClient;
127};
128
129
130CloudClient::CloudClient(ComPtr<IVirtualBox> virtualBox, const Bstr& strProvider, const Bstr& strProfile)
131{
132 HRESULT hrc = virtualBox->COMGETTER(CloudProviderManager)(mManager.asOutParam());
133 handleErrors(hrc, "Failed to obtain cloud provider manager object");
134 hrc = mManager->GetProviderByShortName(strProvider.raw(), mProvider.asOutParam());
135 handleErrors(hrc, "Failed to obtain cloud provider '%ls'", strProvider.raw());
136 hrc = mProvider->GetProfileByName(strProfile.raw(), mProfile.asOutParam());
137 handleErrors(hrc, "Failed to obtain cloud profile '%ls'", strProfile.raw());
138 hrc = mProfile->CreateCloudClient(mClient.asOutParam());
139 handleErrors(hrc, "Failed to create cloud client");
140}
141
142
143void CloudClient::startCloudGateway(const ComPtr<ICloudNetwork> &network, GatewayInfo& gateway)
144{
145 ComPtr<IProgress> progress;
146 ComPtr<ICloudNetworkGatewayInfo> gatewayInfo;
147 HRESULT hrc = mClient->StartCloudNetworkGateway(network, Bstr(gateway.mPublicSshKey).raw(),
148 gatewayInfo.asOutParam(), progress.asOutParam());
149 handleErrors(hrc, "Failed to launch compute instance");
150 hrc = progress->WaitForCompletion(-1);
151 handleErrors(hrc, "Failed to launch compute instance (wait)");
152
153 Bstr instanceId;
154 hrc = gatewayInfo->COMGETTER(InstanceId)(instanceId.asOutParam());
155 handleErrors(hrc, "Failed to get launched compute instance id");
156 gateway.mGatewayInstanceId = instanceId;
157
158 Bstr publicIP;
159 hrc = gatewayInfo->COMGETTER(PublicIP)(publicIP.asOutParam());
160 handleErrors(hrc, "Failed to get cloud gateway public IP address");
161 gateway.mCloudPublicIp = publicIP;
162
163 Bstr secondaryPublicIP;
164 hrc = gatewayInfo->COMGETTER(SecondaryPublicIP)(secondaryPublicIP.asOutParam());
165 handleErrors(hrc, "Failed to get cloud gateway secondary public IP address");
166 gateway.mCloudSecondaryPublicIp = secondaryPublicIP;
167
168 Bstr macAddress;
169 hrc = gatewayInfo->COMGETTER(MacAddress)(macAddress.asOutParam());
170 handleErrors(hrc, "Failed to get cloud gateway public IP address");
171 gateway.setCloudMacAddress(macAddress);
172}
173
174
175void CloudClient::stopCloudGateway(const GatewayInfo& gateway)
176{
177 ComPtr<IProgress> progress;
178 HRESULT hrc = mClient->TerminateInstance(Bstr(gateway.mGatewayInstanceId).raw(), progress.asOutParam());
179 handleErrors(hrc, "Failed to terminate compute instance");
180#if 0
181 /* Someday we may want to wait until the cloud gateway has terminated. */
182 hrc = progress->WaitForCompletion(-1);
183 handleErrors(hrc, "Failed to terminate compute instance (wait)");
184#endif
185}
186
187
188HRESULT startCloudGateway(ComPtr<IVirtualBox> virtualBox, ComPtr<ICloudNetwork> network, GatewayInfo& gateway)
189{
190 HRESULT hrc;
191
192 try
193 {
194 hrc = network->COMGETTER(Provider)(gateway.mCloudProvider.asOutParam());
195 AssertComRCReturnRC(hrc);
196 hrc = network->COMGETTER(Profile)(gateway.mCloudProfile.asOutParam());
197 AssertComRCReturnRC(hrc);
198 CloudClient client(virtualBox, gateway.mCloudProvider, gateway.mCloudProfile);
199 client.startCloudGateway(network, gateway); /* Throws CloudError on failure. */
200 }
201 catch (CloudError e)
202 {
203 hrc = e.getRc();
204 }
205
206 return hrc;
207}
208
209
210HRESULT stopCloudGateway(ComPtr<IVirtualBox> virtualBox, GatewayInfo& gateway)
211{
212 if (gateway.mGatewayInstanceId.isEmpty())
213 return S_OK;
214
215 LogRel(("CLOUD-NET: Terminating cloud gateway instance '%s'...\n", gateway.mGatewayInstanceId.c_str()));
216
217 HRESULT hrc = S_OK;
218 try {
219 CloudClient client(virtualBox, gateway.mCloudProvider, gateway.mCloudProfile);
220 client.stopCloudGateway(gateway);
221#if 0
222# ifdef DEBUG
223 char szKeyPath[RTPATH_MAX];
224
225 int vrc = GetVBoxUserHomeDirectory(szKeyPath, sizeof(szKeyPath), false /* fCreateDir */);
226 if (RT_SUCCESS(vrc))
227 {
228 vrc = RTPathAppend(szKeyPath, sizeof(szKeyPath), "gateway-key.pem");
229 AssertRCReturn(vrc, vrc);
230 vrc = RTFileDelete(szKeyPath);
231 if (RT_FAILURE(vrc))
232 LogRel(("WARNING! Failed to delete private key %s with vrc=%d\n", szKeyPath, vrc));
233 }
234 else
235 LogRel(("WARNING! Failed to get VirtualBox user home directory with '%Rrc'\n", vrc));
236# endif /* DEBUG */
237#endif
238 }
239 catch (CloudError e)
240 {
241 hrc = e.getRc();
242 LogRel(("CLOUD-NET: Failed to terminate cloud gateway instance (hrc=%x).\n", hrc));
243 }
244 gateway.mGatewayInstanceId.setNull();
245 return hrc;
246}
247
248
249HRESULT generateKeys(GatewayInfo& gateway)
250{
251#ifndef VBOX_WITH_LIBSSH
252 RT_NOREF(gateway);
253 return E_NOTIMPL;
254#else /* VBOX_WITH_LIBSSH */
255 ssh_key single_use_key;
256 int iRcSsh = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &single_use_key);
257 if (iRcSsh != SSH_OK)
258 {
259 LogRel(("Failed to generate a key pair. iRcSsh = %d\n", iRcSsh));
260 return E_FAIL;
261 }
262
263 char *pstrKey = NULL;
264 iRcSsh = ssh_pki_export_privkey_base64(single_use_key, NULL, NULL, NULL, &pstrKey);
265 if (iRcSsh != SSH_OK)
266 {
267 LogRel(("Failed to export private key. iRcSsh = %d\n", iRcSsh));
268 return E_FAIL;
269 }
270 gateway.mPrivateSshKey = pstrKey;
271#if 0
272# ifdef DEBUG
273 char szConfigPath[RTPATH_MAX];
274
275 vrc = GetVBoxUserHomeDirectory(szConfigPath, sizeof(szConfigPath), false /* fCreateDir */);
276 if (RT_SUCCESS(vrc))
277 {
278 vrc = RTPathAppend(szConfigPath, sizeof(szConfigPath), "gateway-key.pem");
279 AssertRCReturn(vrc, E_FAIL);
280 iRcSsh = ssh_pki_export_privkey_file(single_use_key, NULL, NULL, NULL, szConfigPath);
281 if (iRcSsh != SSH_OK)
282 {
283 LogRel(("Failed to export private key to %s with iRcSsh=%d\n", szConfigPath, iRcSsh));
284 return E_FAIL;
285 }
286# ifndef RT_OS_WINDOWS
287 vrc = RTPathSetMode(szConfigPath, RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); /* Satisfy ssh client */
288 AssertRCReturn(vrc, E_FAIL);
289# endif
290 }
291 else
292 {
293 LogRel(("Failed to get VirtualBox user home directory with '%Rrc'\n", vrc));
294 return E_FAIL;
295 }
296# endif /* DEBUG */
297#endif
298 ssh_string_free_char(pstrKey);
299 pstrKey = NULL;
300 iRcSsh = ssh_pki_export_pubkey_base64(single_use_key, &pstrKey);
301 if (iRcSsh != SSH_OK)
302 {
303 LogRel(("Failed to export public key. iRcSsh = %d\n", iRcSsh));
304 return E_FAIL;
305 }
306 gateway.mPublicSshKey = Utf8StrFmt("ssh-rsa %s single-use-key", pstrKey);
307 ssh_string_free_char(pstrKey);
308 ssh_key_free(single_use_key);
309
310 return S_OK;
311#endif /* VBOX_WITH_LIBSSH */
312}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette