VirtualBox

Changeset 94521 in vbox for trunk


Ignore:
Timestamp:
Apr 7, 2022 3:18:48 PM (3 years ago)
Author:
vboxsync
Message:

libs/libssh,Main,FE/VBoxManage,Devices/Network/DrvCloudTunnel|ai: Add support for proxies, bugref:9469

Location:
trunk/src/VBox
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvCloudTunnel.cpp

    r93394 r94521  
    8787    /** SSH connection timeout in seconds. */
    8888    long                    ulTimeoutInSecounds;
     89
     90    /** Primary proxy type. */
     91    char                    *pszPrimaryProxyType;
     92    /** Primary proxy server IP address. */
     93    char                    *pszPrimaryProxyHost;
     94    /** Primary proxy server port. */
     95    uint16_t                u16PrimaryProxyPort;
     96    /** Primary proxy user. */
     97    char                    *pszPrimaryProxyUser;
     98    /** Primary proxy password. */
     99    char                    *pszPrimaryProxyPassword;
     100
     101    /** Secondary proxy type. */
     102    char                    *pszSecondaryProxyType;
     103    /** Secondary proxy server IP address. */
     104    char                    *pszSecondaryProxyHost;
     105    /** Secondary proxy server port. */
     106    uint16_t                u16SecondaryProxyPort;
     107    /** Secondary proxy user. */
     108    char                    *pszSecondaryProxyUser;
     109    /** Secondary proxy password. */
     110    char                    *pszSecondaryProxyPassword;
     111
    89112    /** Cloud tunnel instance string. */
    90113    char                    *pszInstance;
     
    10251048        rc = drvCloudTunnelExecuteRemoteCommand(pThis, "sudo ip link set dev %s address %RTmac", pThis->pszCloudPrimaryInterface, pThis->targetMac.au8);
    10261049    if (RT_SUCCESS(rc))
     1050        rc = drvCloudTunnelExecuteRemoteCommand(pThis, "sudo ifconfig %s 0.0.0.0", pThis->pszCloudPrimaryInterface); /* Make sure no IP is configured on primary */
     1051    if (RT_SUCCESS(rc))
    10271052        rc = drvCloudTunnelExecuteRemoteCommand(pThis, "sudo ip link set dev %s master br0", pThis->pszCloudPrimaryInterface);
    10281053    if (RT_SUCCESS(rc))
     
    11271152
    11281153
    1129 static int drvCloudTunnelSwitchToSecondary(PDRVCLOUDTUNNEL pThis)
     1154static int drvCloudTunnelNewSession(PDRVCLOUDTUNNEL pThis, bool fPrimary)
    11301155{
    11311156    pThis->pSshSession = ssh_new();
     
    11391164        return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    11401165                                   N_("Failed to set SSH_OPTIONS_USER"));
    1141     if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_HOST, pThis->pszPrimaryIP) < 0)
     1166    if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_HOST, fPrimary ? pThis->pszPrimaryIP : pThis->pszSecondaryIP) < 0)
    11421167        return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    11431168                                   N_("Failed to set SSH_OPTIONS_HOST"));
     
    11471172                                   N_("Failed to set SSH_OPTIONS_TIMEOUT"));
    11481173
     1174    const char *pcszProxyType = fPrimary ? pThis->pszPrimaryProxyType : pThis->pszSecondaryProxyType;
     1175    if (pcszProxyType)
     1176    {
     1177        char szProxyCmd[1024];
     1178
     1179        const char *pcszProxyUser = fPrimary ? pThis->pszPrimaryProxyUser : pThis->pszSecondaryProxyUser;
     1180        if (pcszProxyUser)
     1181            RTStrPrintf(szProxyCmd, sizeof(szProxyCmd), "#VBoxProxy%s %s %u %s %s",
     1182                        fPrimary ? pThis->pszPrimaryProxyType : pThis->pszSecondaryProxyType,
     1183                        fPrimary ? pThis->pszPrimaryProxyHost : pThis->pszSecondaryProxyHost,
     1184                        fPrimary ? pThis->u16PrimaryProxyPort : pThis->u16SecondaryProxyPort,
     1185                        fPrimary ? pThis->pszPrimaryProxyUser : pThis->pszSecondaryProxyUser,
     1186                        fPrimary ? pThis->pszPrimaryProxyPassword : pThis->pszSecondaryProxyPassword);
     1187        else
     1188            RTStrPrintf(szProxyCmd, sizeof(szProxyCmd), "#VBoxProxy%s %s %u",
     1189                        fPrimary ? pThis->pszPrimaryProxyType : pThis->pszSecondaryProxyType,
     1190                        fPrimary ? pThis->pszPrimaryProxyHost : pThis->pszSecondaryProxyHost,
     1191                        fPrimary ? pThis->u16PrimaryProxyPort : pThis->u16SecondaryProxyPort);
     1192        LogRel(("%s: using proxy command '%s'\n", pThis->pszInstance, szProxyCmd));
     1193        if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_PROXYCOMMAND, szProxyCmd) < 0)
     1194            return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     1195                                    N_("Failed to set SSH_OPTIONS_PROXYCOMMAND"));
     1196    }
     1197
    11491198    int rc = ssh_connect(pThis->pSshSession);
    1150     if (rc != SSH_OK)
     1199    for (int cAttempt = 1; rc != SSH_OK && cAttempt <= 5; cAttempt++)
    11511200    {
    11521201        ssh_disconnect(pThis->pSshSession);
    11531202        /* One more time, just to be sure. */
    1154         LogRel(("%s: failed to connect to %s, retrying...\n", pThis->pszInstance, pThis->pszPrimaryIP));
     1203        LogRel(("%s: failed to connect to %s, retrying(#%d)...\n", pThis->pszInstance,
     1204                fPrimary ? pThis->pszPrimaryIP : pThis->pszSecondaryIP, cAttempt));
     1205        RTThreadSleep(10000); /* Sleep 10 seconds, then retry */
    11551206        rc = ssh_connect(pThis->pSshSession);
    11561207    }
    11571208    if (rc != SSH_OK)
    11581209        return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    1159                                    N_("CloudTunnel: Failed to connect to primary interface"));
     1210                                   N_("CloudTunnel: Failed to connect to %s interface"), fPrimary ? "primary" : "secondary");
    11601211
    11611212    rc = ssh_userauth_publickey(pThis->pSshSession, NULL, pThis->SshKey);
     
    11641215                                   N_("Failed to authenticate with public key"));
    11651216
     1217    return VINF_SUCCESS;
     1218}
     1219
     1220static int drvCloudTunnelSwitchToSecondary(PDRVCLOUDTUNNEL pThis)
     1221{
     1222    int rc = drvCloudTunnelNewSession(pThis, true /* fPrimary */);
    11661223    /*
    11671224     * Establish temporary console channel and configure the cloud instance
    11681225     * to bridge the tunnel channel to instance's primary interface.
    11691226     */
    1170     rc = drvCloudTunnelCloudInstanceInitialConfig(pThis);
     1227    if (RT_SUCCESS(rc))
     1228        rc = drvCloudTunnelCloudInstanceInitialConfig(pThis);
    11711229
    11721230    ssh_disconnect(pThis->pSshSession);
     
    11801238static int establishTunnel(PDRVCLOUDTUNNEL pThis)
    11811239{
    1182     pThis->pSshSession = ssh_new();
    1183     if (pThis->pSshSession == NULL)
    1184         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    1185                                    N_("CloudTunnel: Failed to allocate new SSH session"));
    1186     if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_LOG_VERBOSITY, &pThis->iSshVerbosity) < 0)
    1187         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    1188                                    N_("Failed to set SSH_OPTIONS_LOG_VERBOSITY"));
    1189     if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_USER, pThis->pszUser) < 0)
    1190         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    1191                                    N_("Failed to set SSH_OPTIONS_USER"));
    1192     if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_HOST, pThis->pszSecondaryIP) < 0)
    1193         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    1194                                    N_("Failed to set SSH_OPTIONS_HOST"));
    1195 
    1196     if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_TIMEOUT, &pThis->ulTimeoutInSecounds) < 0)
    1197         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    1198                                    N_("Failed to set SSH_OPTIONS_TIMEOUT"));
    1199 
    1200     int rc = ssh_connect(pThis->pSshSession);
    1201     if (rc != SSH_OK)
    1202     {
    1203         ssh_disconnect(pThis->pSshSession);
    1204         /* One more time, just to be sure. */
    1205         Log(("%s: failed to connect to %s, retrying...\n", pThis->pszInstance, pThis->pszSecondaryIP));
    1206         rc = ssh_connect(pThis->pSshSession);
    1207     }
    1208     if (rc != SSH_OK)
    1209         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    1210                                    N_("CloudTunnel: Failed to connect to secondary interface"));
    1211 
    1212     rc = ssh_userauth_publickey(pThis->pSshSession, NULL, pThis->SshKey);
    1213     if (rc != SSH_AUTH_SUCCESS)
    1214         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    1215                                    N_("Failed to authenticate with public key"));
    1216 
    1217     rc = drvCloudTunnelCloudInstanceFinalConfig(pThis);
     1240    int rc = drvCloudTunnelNewSession(pThis, false /* fPrimary */);
     1241    if (RT_SUCCESS(rc))
     1242        rc = drvCloudTunnelCloudInstanceFinalConfig(pThis);
    12181243    if (RT_SUCCESS(rc))
    12191244        rc = drvCloudTunnelOpenTunnelChannel(pThis);
     
    12621287/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
    12631288
     1289DECLINLINE(void) drvCloudTunnelStrFree(char **ppszString)
     1290{
     1291    if (*ppszString)
     1292    {
     1293        RTStrFree(*ppszString);
     1294        *ppszString = NULL;
     1295    }
     1296}
     1297
     1298DECLINLINE(void) drvCloudTunnelHeapFree(PPDMDRVINS pDrvIns, char **ppszString)
     1299{
     1300    if (*ppszString)
     1301    {
     1302        PDMDrvHlpMMHeapFree(pDrvIns, *ppszString);
     1303        *ppszString = NULL;
     1304    }
     1305}
     1306
    12641307/**
    12651308 * Destruct a driver instance.
     
    12861329    }
    12871330
    1288     if (pThis->pszCloudPrimaryInterface)
    1289     {
    1290         RTStrFree(pThis->pszCloudPrimaryInterface);
    1291         pThis->pszCloudPrimaryInterface = NULL;
    1292     }
    1293 
    1294     if (pThis->pszSecondaryIP)
    1295     {
    1296         RTStrFree(pThis->pszSecondaryIP);
    1297         pThis->pszSecondaryIP = NULL;
    1298     }
    1299 
    1300     if (pThis->pszPrimaryIP)
    1301     {
    1302         RTStrFree(pThis->pszPrimaryIP);
    1303         pThis->pszPrimaryIP = NULL;
    1304     }
    1305 
    1306     if (pThis->pszUser)
    1307     {
    1308         RTStrFree(pThis->pszUser);
    1309         pThis->pszUser = NULL;
    1310     }
    1311 
    1312     if (pThis->pszInstanceDev)
    1313     {
    1314         RTStrFree(pThis->pszInstanceDev);
    1315         pThis->pszInstanceDev = NULL;
    1316     }
    1317 
    1318     if (pThis->pszInstanceIo)
    1319     {
    1320         RTStrFree(pThis->pszInstanceIo);
    1321         pThis->pszInstanceIo = NULL;
    1322     }
    1323 
    1324     if (pThis->pszInstance)
    1325     {
    1326         RTStrFree(pThis->pszInstance);
    1327         pThis->pszInstance = NULL;
    1328     }
    1329 
    1330     if (pThis->pszOutputBuffer)
    1331     {
    1332         RTStrFree(pThis->pszOutputBuffer);
    1333         pThis->pszOutputBuffer = NULL;
    1334     }
    1335 
    1336     if (pThis->pszCommandBuffer)
    1337     {
    1338         RTStrFree(pThis->pszCommandBuffer);
    1339         pThis->pszCommandBuffer = NULL;
    1340     }
     1331    drvCloudTunnelStrFree(&pThis->pszCloudPrimaryInterface);
     1332
     1333    drvCloudTunnelHeapFree(pDrvIns, &pThis->pszPrimaryProxyType);
     1334    drvCloudTunnelStrFree(&pThis->pszPrimaryProxyHost);
     1335    drvCloudTunnelHeapFree(pDrvIns, &pThis->pszPrimaryProxyUser);
     1336    drvCloudTunnelStrFree(&pThis->pszPrimaryProxyPassword);
     1337
     1338    drvCloudTunnelHeapFree(pDrvIns, &pThis->pszSecondaryProxyType);
     1339    drvCloudTunnelStrFree(&pThis->pszSecondaryProxyHost);
     1340    drvCloudTunnelHeapFree(pDrvIns, &pThis->pszSecondaryProxyUser);
     1341    drvCloudTunnelStrFree(&pThis->pszSecondaryProxyPassword);
     1342
     1343    drvCloudTunnelStrFree(&pThis->pszSecondaryIP);
     1344    drvCloudTunnelStrFree(&pThis->pszPrimaryIP);
     1345    drvCloudTunnelStrFree(&pThis->pszUser);
     1346
     1347    drvCloudTunnelStrFree(&pThis->pszInstanceDev);
     1348    drvCloudTunnelStrFree(&pThis->pszInstanceIo);
     1349    drvCloudTunnelStrFree(&pThis->pszInstance);
     1350
     1351    drvCloudTunnelStrFree(&pThis->pszOutputBuffer);
     1352    drvCloudTunnelStrFree(&pThis->pszCommandBuffer);
    13411353
    13421354    ssh_key_free(pThis->SshKey);
     
    14421454                                            "|PrimaryIP"
    14431455                                            "|SecondaryIP"
    1444                                             "|TargetMAC",
    1445                                             "");
     1456                                            "|TargetMAC"
     1457
     1458                                            "|PrimaryProxyType"
     1459                                            "|PrimaryProxyHost"
     1460                                            "|PrimaryProxyPort"
     1461                                            "|PrimaryProxyUser"
     1462                                            "|PrimaryProxyPassword"
     1463                                            "|SecondaryProxyType"
     1464                                            "|SecondaryProxyHost"
     1465                                            "|SecondaryProxyPort"
     1466                                            "|SecondaryProxyUser"
     1467                                            "|SecondaryProxyPassword"
     1468
     1469                                            ,"");
    14461470
    14471471    /*
     
    15131537        return PDMDRV_SET_ERROR(pDrvIns, VERR_INVALID_BASE64_ENCODING,
    15141538                                N_("DrvCloudTunnel: Configuration error: Converting \"SshKey\" from base64 failed"));
     1539
     1540    /* PrimaryProxyType is optional */
     1541    rc = pHlp->pfnCFGMQueryStringAllocDef(pCfg, "PrimaryProxyType", &pThis->pszPrimaryProxyType, NULL);
     1542    if (RT_FAILURE(rc))
     1543        return PDMDRV_SET_ERROR(pDrvIns, rc,
     1544                                N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyType\" as string failed"));
     1545    if (pThis->pszPrimaryProxyType)
     1546    {
     1547        rc = pHlp->pfnCFGMQueryString(pCfg, "PrimaryProxyHost", szVal, sizeof(szVal));
     1548        if (RT_FAILURE(rc))
     1549            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1550                                    N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyHost\" as string failed"));
     1551        rc = RTNetStrToIPv4Addr(szVal, &tmpAddr);
     1552        if (RT_FAILURE(rc))
     1553            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1554                                    N_("DrvCloudTunnel: Configuration error: \"PrimaryProxyHost\" is not valid"));
     1555        else
     1556            pThis->pszPrimaryProxyHost = RTStrDup(szVal);
     1557
     1558        uint64_t u64Val;
     1559        rc = pHlp->pfnCFGMQueryInteger(pCfg, "PrimaryProxyPort", &u64Val);
     1560        if (RT_FAILURE(rc))
     1561            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1562                                    N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyPort\" as integer failed"));
     1563        if (u64Val > 0xFFFF)
     1564            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1565                                    N_("DrvCloudTunnel: Configuration error: \"PrimaryProxyPort\" is not valid"));
     1566        pThis->u16PrimaryProxyPort = (uint16_t)u64Val;
     1567
     1568        /* PrimaryProxyUser is optional */
     1569        rc = pHlp->pfnCFGMQueryStringAllocDef(pCfg, "PrimaryProxyUser", &pThis->pszPrimaryProxyUser, NULL);
     1570        if (RT_FAILURE(rc))
     1571            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1572                                    N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyUser\" as string failed"));
     1573        /* PrimaryProxyPassword must be present if PrimaryProxyUser is present */
     1574        if (pThis->pszPrimaryProxyUser)
     1575        {
     1576            rc = pHlp->pfnCFGMQueryPassword(pCfg, "PrimaryProxyPassword", szVal, sizeof(szVal));
     1577            if (RT_FAILURE(rc))
     1578                return PDMDRV_SET_ERROR(pDrvIns, rc,
     1579                                        N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyPassword\" as string failed"));
     1580            pThis->pszPrimaryProxyPassword = RTStrDup(szVal);
     1581        }
     1582    }
     1583
     1584    /* SecondaryProxyType is optional */
     1585    rc = pHlp->pfnCFGMQueryStringAllocDef(pCfg, "SecondaryProxyType", &pThis->pszSecondaryProxyType, NULL);
     1586    if (RT_FAILURE(rc))
     1587        return PDMDRV_SET_ERROR(pDrvIns, rc,
     1588                                N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyType\" as string failed"));
     1589    if (pThis->pszSecondaryProxyType)
     1590    {
     1591        if (RT_FAILURE(rc))
     1592            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1593                                    N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyType\" as string failed"));
     1594
     1595        rc = pHlp->pfnCFGMQueryString(pCfg, "SecondaryProxyHost", szVal, sizeof(szVal));
     1596        if (RT_FAILURE(rc))
     1597            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1598                                    N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyHost\" as string failed"));
     1599        rc = RTNetStrToIPv4Addr(szVal, &tmpAddr);
     1600        if (RT_FAILURE(rc))
     1601            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1602                                    N_("DrvCloudTunnel: Configuration error: \"SecondaryProxyHost\" is not valid"));
     1603        else
     1604            pThis->pszSecondaryProxyHost = RTStrDup(szVal);
     1605
     1606        uint64_t u64Val;
     1607        rc = pHlp->pfnCFGMQueryInteger(pCfg, "SecondaryProxyPort", &u64Val);
     1608        if (RT_FAILURE(rc))
     1609            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1610                                    N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyPort\" as integer failed"));
     1611        if (u64Val > 0xFFFF)
     1612            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1613                                    N_("DrvCloudTunnel: Configuration error: \"SecondaryProxyPort\" is not valid"));
     1614        pThis->u16SecondaryProxyPort = (uint16_t)u64Val;
     1615
     1616        /* SecondaryProxyUser is optional */
     1617        rc = pHlp->pfnCFGMQueryStringAllocDef(pCfg, "SecondaryProxyUser", &pThis->pszSecondaryProxyUser, NULL);
     1618        if (RT_FAILURE(rc))
     1619            return PDMDRV_SET_ERROR(pDrvIns, rc,
     1620                                    N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyUser\" as string failed"));
     1621        /* SecondaryProxyPassword must be present if SecondaryProxyUser is present */
     1622        if (pThis->pszSecondaryProxyUser)
     1623        {
     1624            rc = pHlp->pfnCFGMQueryPassword(pCfg, "SecondaryProxyPassword", szVal, sizeof(szVal));
     1625            if (RT_FAILURE(rc))
     1626                return PDMDRV_SET_ERROR(pDrvIns, rc,
     1627                                        N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyPassword\" as string failed"));
     1628            pThis->pszSecondaryProxyPassword = RTStrDup(szVal);
     1629        }
     1630    }
    15151631
    15161632    pThis->pszCommandBuffer = (char *)RTMemAlloc(DRVCLOUDTUNNEL_COMMAND_BUFFER_SIZE);
  • trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk

    r94290 r94521  
    3434        $(if-expr defined(VBOX_WITH_VMNET) && "$(KBUILD_TARGET)"=="darwin",VBOX_WITH_VMNET,) \
    3535        $(if $(VBOX_WITH_CLOUD_NET), VBOX_WITH_CLOUD_NET) \
    36         $(if $(VBOX_WITH_LIBCURL), VBOX_WITH_PROXY_INFO) \
    3736        $(if $(VBOX_WITH_AUDIO_OSS), VBOX_WITH_AUDIO_OSS) \
    3837        $(if $(VBOX_WITH_AUDIO_ALSA), VBOX_WITH_AUDIO_ALSA) \
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp

    r94238 r94521  
    21452145
    21462146
    2147 /* Disabled temporarily until proxy support is implemented in libssh */
    2148 #if 0
    2149 /**
    2150  * @returns COM status code.
    2151  * @retval  S_OK if url needs proxy.
    2152  * @retval  S_FALSE if noproxy for the URL.
    2153  */
    2154 static HRESULT getSystemProxyForUrl(const com::Utf8Str &strUrl, Bstr &strProxy)
    2155 {
    2156     /** @todo r=bird: LogRel is pointless here. */
    2157 #ifndef VBOX_WITH_PROXY_INFO
    2158     RT_NOREF(strUrl, strProxy);
    2159     LogRel(("CLOUD-NET: Proxy support is disabled. Using direct connection.\n"));
    2160     return S_FALSE;
    2161 #else /* VBOX_WITH_PROXY_INFO */
    2162     HRESULT hrc = E_FAIL;
    2163     RTHTTP  hHttp;
    2164     int rc = RTHttpCreate(&hHttp);
    2165     if (RT_SUCCESS(rc))
    2166     {
    2167         rc = RTHttpUseSystemProxySettings(hHttp);
    2168         if (RT_SUCCESS(rc))
    2169         {
    2170             RTHTTPPROXYINFO proxy;
    2171             rc = RTHttpQueryProxyInfoForUrl(hHttp, strUrl.c_str(), &proxy);
    2172             if (RT_SUCCESS(rc))
    2173             {
    2174                 const char *pcszProxyScheme = "";
    2175                 switch (proxy.enmProxyType)
    2176                 {
    2177                     case RTHTTPPROXYTYPE_NOPROXY:
    2178                         pcszProxyScheme = NULL;
    2179                         hrc = S_FALSE;
    2180                         break;
    2181                     case RTHTTPPROXYTYPE_HTTP:
    2182                         pcszProxyScheme = "http://";
    2183                         break;
    2184                     case RTHTTPPROXYTYPE_HTTPS:
    2185                         pcszProxyScheme = "https://";
    2186                         break;
    2187                     case RTHTTPPROXYTYPE_SOCKS4:
    2188                         pcszProxyScheme = "socks4://";
    2189                         break;
    2190                     case RTHTTPPROXYTYPE_SOCKS5:
    2191                         pcszProxyScheme = "socks://";
    2192                         break;
    2193                     case RTHTTPPROXYTYPE_INVALID:
    2194                     case RTHTTPPROXYTYPE_UNKNOWN:
    2195                     case RTHTTPPROXYTYPE_END:
    2196                     case RTHTTPPROXYTYPE_32BIT_HACK:
    2197                         break;
    2198                 }
    2199                 if (pcszProxyScheme && *pcszProxyScheme != '\0')
    2200                 {
    2201                     if (proxy.pszProxyUsername || proxy.pszProxyPassword)
    2202                         LogRel(("CLOUD-NET: Warning! Code doesn't yet handle proxy user or password. Sorry.\n"));
    2203                     if (proxy.uProxyPort != UINT32_MAX)
    2204                         strProxy.printf("%s%s:%d", pcszProxyScheme, proxy.pszProxyHost, proxy.uProxyPort);
    2205                     else
    2206                         strProxy.printf("%s%s", pcszProxyScheme, proxy.pszProxyHost);
    2207                     hrc = S_OK;
    2208                 }
    2209                 else if (pcszProxyScheme)
    2210                 {
    2211                     LogRel(("CLOUD-NET: Unknown proxy type %d. Using direct connection.\n", proxy.enmProxyType));
    2212                     AssertFailed();
    2213                 }
    2214                 RTHttpFreeProxyInfo(&proxy);
    2215             }
    2216             else
    2217                 LogRel(("CLOUD-NET: Failed to get proxy for %s (rc=%Rrc)\n", strUrl.c_str(), rc));
    2218         }
    2219         else
    2220             LogRel(("CLOUD-NET: Failed to use system proxy (rc=%Rrc)\n", rc));
    2221         RTHttpDestroy(hHttp);
    2222     }
    2223     else
    2224         LogRel(("CLOUD-NET: Failed to create HTTP context (rc=%Rrc)\n", rc));
    2225     return hrc;
    2226 #endif /* VBOX_WITH_PROXY_INFO */
    2227 }
    2228 #endif
    2229 
    2230 
    22312147static RTEXITCODE setupCloudNetworkEnv(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
    22322148{
     
    22402156        { "--tunnel-network-name",  't', RTGETOPT_REQ_STRING },
    22412157        { "--tunnel-network-range", 'r', RTGETOPT_REQ_STRING },
    2242         { "--proxy",                'p', RTGETOPT_REQ_STRING },
    22432158        { "--compartment-id",       'c', RTGETOPT_REQ_STRING }
    22442159    };
     
    22532168    Bstr strTunnelNetworkName;
    22542169    Bstr strTunnelNetworkRange;
    2255     Bstr strProxy;
    22562170    Bstr strCompartmentId;
    22572171
     
    22752189            case 'r':
    22762190                strTunnelNetworkRange=ValueUnion.psz;
    2277                 break;
    2278             case 'p':
    2279                 strProxy=ValueUnion.psz;
    22802191                break;
    22812192            case 'c':
  • trunk/src/VBox/Main/Makefile.kmk

    r94143 r94521  
    969969        $(if $(VBOX_WITH_USB),VBOX_WITH_USB,) \
    970970        $(if $(VBOX_WITH_VRDEAUTH_IN_VBOXSVC),VBOX_WITH_VRDEAUTH_IN_VBOXSVC,) \
    971         $(if $(VBOX_WITH_LIBCURL), VBOX_WITH_PROXY_INFO) \
    972971        $(if $(VBOX_WITH_IOMMU_AMD),VBOX_WITH_IOMMU_AMD,) \
    973972        $(if $(VBOX_WITH_IOMMU_INTEL),VBOX_WITH_IOMMU_INTEL,) \
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r94342 r94521  
    797797                        PCFGMNODE pCfg,  PCFGMNODE pLunL0, PCFGMNODE pInst, bool fAttachDetach, bool fIgnoreConnectFailure,
    798798                        PUVM pUVM, PCVMMR3VTABLE pVMM);
     799    int i_configProxy(ComPtr<IVirtualBox> virtualBox, PCFGMNODE pCfg, const char *pcszPrefix, const com::Utf8Str &strIpAddr);
     800
    799801    int i_configSerialPort(PCFGMNODE pInst, PortMode_T ePortMode, const char *pszPath, bool fServer);
    800802    static DECLCALLBACK(void) i_vmstateChangeCallback(PUVM pUVM, PCVMMR3VTABLE pVMM, VMSTATE enmState,
  • trunk/src/VBox/Main/src-client/CloudGateway.cpp

    r93312 r94521  
    194194}
    195195
    196 
    197 #if 0 /* Disabled until proxy support is implemented */
    198 static bool getProxyForIpAddr(ComPtr<IVirtualBox> virtualBox, const com::Utf8Str &strIpAddr, Bstr &strProxyType, Bstr &strProxyHost, Bstr &strProxyPort)
    199 {
    200 #ifndef VBOX_WITH_PROXY_INFO
    201     RT_NOREF(virtualBox, strIpAddr, strProxyType, strProxyHost, strProxyPort);
    202     LogRel(("CLOUD-NET: Proxy support is disabled. Using direct connection.\n"));
    203     return false;
    204 #else /* VBOX_WITH_PROXY_INFO */
    205     ComPtr<ISystemProperties> systemProperties;
    206     ProxyMode_T enmProxyMode;
    207     HRESULT hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
    208     if (FAILED(hrc))
    209     {
    210         LogRel(("CLOUD-NET: Failed to obtain system properties. hrc=%x\n", hrc));
    211         return false;
    212     }
    213     hrc = systemProperties->COMGETTER(ProxyMode)(&enmProxyMode);
    214     if (FAILED(hrc))
    215     {
    216         LogRel(("CLOUD-NET: Failed to obtain default machine folder. hrc=%x\n", hrc));
    217         return false;
    218     }
    219     if (enmProxyMode == ProxyMode_NoProxy)
    220         return false;
    221 
    222     Bstr proxyUrl;
    223     if (enmProxyMode == ProxyMode_Manual)
    224     {
    225         hrc = systemProperties->COMGETTER(ProxyURL)(proxyUrl.asOutParam());
    226         if (FAILED(hrc))
    227         {
    228             LogRel(("CLOUD-NET: Failed to obtain proxy URL. hrc=%x\n", hrc));
    229             return false;
    230         }
    231         Utf8Str strProxyUrl = proxyUrl;
    232         if (!strProxyUrl.contains("://"))
    233             strProxyUrl = "http://" + strProxyUrl;
    234         const char *pcszProxyUrl = strProxyUrl.c_str();
    235         RTURIPARSED Parsed;
    236         int rc = RTUriParse(pcszProxyUrl, &Parsed);
    237         if (RT_FAILURE(rc))
    238         {
    239             LogRel(("CLOUD-NET: Failed to parse proxy URL: %ls (rc=%d)\n", proxyUrl.raw(), rc));
    240             return false;
    241         }
    242         char *pszHost = RTUriParsedAuthorityHost(pcszProxyUrl, &Parsed);
    243         if (!pszHost)
    244         {
    245             LogRel(("CLOUD-NET: Failed to get proxy host name from proxy URL: %s\n", pcszProxyUrl));
    246             return false;
    247         }
    248         strProxyHost = pszHost;
    249         RTStrFree(pszHost);
    250         char *pszScheme = RTUriParsedScheme(pcszProxyUrl, &Parsed);
    251         if (!pszScheme)
    252         {
    253             LogRel(("CLOUD-NET: Failed to get proxy scheme from proxy URL: %s\n", pcszProxyUrl));
    254             return false;
    255         }
    256         strProxyType = Utf8Str(pszScheme).toUpper();
    257         RTStrFree(pszScheme);
    258         uint32_t uProxyPort  = RTUriParsedAuthorityPort(pcszProxyUrl, &Parsed);
    259         if (uProxyPort == UINT32_MAX)
    260         if (!pszScheme)
    261         {
    262             LogRel(("CLOUD-NET: Failed to get proxy port from proxy URL: %s\n", pcszProxyUrl));
    263             return false;
    264         }
    265         strProxyPort = BstrFmt("%d", uProxyPort);
    266     }
    267     else
    268     {
    269         /* Attempt to use system proxy settings (ProxyMode_System) */
    270         RTHTTP hHttp;
    271         int rc = RTHttpCreate(&hHttp);
    272         if (RT_FAILURE(rc))
    273         {
    274             LogRel(("CLOUD-NET: Failed to create HTTP context (rc=%Rrc)\n", rc));
    275             return false;
    276         }
    277         rc = RTHttpUseSystemProxySettings(hHttp);
    278         if (RT_FAILURE(rc))
    279         {
    280             LogRel(("CLOUD-NET: Failed to use system proxy (rc=%Rrc)\n", rc));
    281             RTHttpDestroy(hHttp);
    282             return false;
    283         }
    284 
    285         RTHTTPPROXYINFO proxy;
    286         rc = RTHttpQueryProxyInfoForUrl(hHttp, ("http://" + strIpAddr).c_str(), &proxy);
    287         if (RT_FAILURE(rc))
    288         {
    289             LogRel(("CLOUD-NET: Failed to get proxy for %s (rc=%Rrc)\n", strIpAddr.c_str(), rc));
    290             RTHttpDestroy(hHttp);
    291             return false;
    292         }
    293         switch (proxy.enmProxyType)
    294         {
    295             case RTHTTPPROXYTYPE_NOPROXY:
    296                 RTHttpFreeProxyInfo(&proxy);
    297                 RTHttpDestroy(hHttp);
    298                 return false;
    299             case RTHTTPPROXYTYPE_HTTP:
    300                 strProxyType = "HTTP";
    301                 break;
    302             case RTHTTPPROXYTYPE_HTTPS:
    303                 strProxyType = "HTTPS";
    304                 break;
    305             case RTHTTPPROXYTYPE_SOCKS4:
    306                 strProxyType = "SOCKS4";
    307                 break;
    308             case RTHTTPPROXYTYPE_SOCKS5:
    309                 strProxyType = "SOCKS5";
    310                 break;
    311             case RTHTTPPROXYTYPE_UNKNOWN:
    312             case RTHTTPPROXYTYPE_INVALID:
    313             case RTHTTPPROXYTYPE_END:
    314             case RTHTTPPROXYTYPE_32BIT_HACK:
    315                 break;
    316         }
    317         AssertStmt(strProxyType.isNotEmpty(), LogRel(("CLOUD-NET: Unknown proxy type: %d\n", proxy.enmProxyType)));
    318         strProxyHost = proxy.pszProxyHost;
    319         if (proxy.uProxyPort != UINT32_MAX)
    320             strProxyPort.printf("%d", proxy.uProxyPort);
    321         RTHttpFreeProxyInfo(&proxy);
    322         RTHttpDestroy(hHttp);
    323     }
    324     return true;
    325 #endif /* VBOX_WITH_PROXY_INFO */
    326 }
    327 #endif
    328196
    329197HRESULT stopCloudGateway(ComPtr<IVirtualBox> virtualBox, GatewayInfo& gateway)
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r94321 r94521  
    6666#endif
    6767#include <iprt/stream.h>
     68
     69#include <iprt/http.h>
     70#include <iprt/socket.h>
     71#include <iprt/uri.h>
    6872
    6973#include <VBox/vmm/vmmr3vtable.h>
     
    53625366
    53635367    return hrc;
     5368}
     5369
     5370
     5371/**
     5372 * Configure proxy parameters the Network configuration tree.
     5373 * Parameters may differ depending on the IP address being accessed.
     5374 *
     5375 * @returns VBox status code.
     5376 *
     5377 * @param   virtualBox          The VirtualBox object.
     5378 * @param   pCfg                Configuration node for the driver.
     5379 * @param   pcszPrefix          The prefix for CFGM parameters: "Primary" or "Secondary".
     5380 * @param   strIpAddr           The public IP address to be accessed via a proxy.
     5381 *
     5382 * @thread EMT
     5383 */
     5384int Console::i_configProxy(ComPtr<IVirtualBox> virtualBox, PCFGMNODE pCfg, const char *pcszPrefix, const com::Utf8Str &strIpAddr)
     5385{
     5386    RTHTTPPROXYINFO ProxyInfo;
     5387    ComPtr<ISystemProperties> systemProperties;
     5388    ProxyMode_T enmProxyMode;
     5389    HRESULT hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
     5390    if (FAILED(hrc))
     5391    {
     5392        LogRel(("CLOUD-NET: Failed to obtain system properties. hrc=%x\n", hrc));
     5393        return false;
     5394    }
     5395    hrc = systemProperties->COMGETTER(ProxyMode)(&enmProxyMode);
     5396    if (FAILED(hrc))
     5397    {
     5398        LogRel(("CLOUD-NET: Failed to obtain default machine folder. hrc=%x\n", hrc));
     5399        return VERR_INTERNAL_ERROR;
     5400    }
     5401
     5402    RTHTTP hHttp;
     5403    int rc = RTHttpCreate(&hHttp);
     5404    if (RT_FAILURE(rc))
     5405    {
     5406        LogRel(("CLOUD-NET: Failed to create HTTP context (rc=%Rrc)\n", rc));
     5407        return rc;
     5408    }
     5409
     5410    char *pszProxyType = NULL;
     5411
     5412    if (enmProxyMode == ProxyMode_Manual)
     5413    {
     5414        /*
     5415         * Unfortunately we cannot simply call RTHttpSetProxyByUrl because it never
     5416         * exposes proxy settings. Calling RTHttpQueryProxyInfoForUrl afterward
     5417         * won't help either as it uses system-wide proxy settings instead of
     5418         * parameters we would have set with RTHttpSetProxyByUrl. Hence we parse
     5419         * proxy URL ourselves here.
     5420         */
     5421        Bstr proxyUrl;
     5422        hrc = systemProperties->COMGETTER(ProxyURL)(proxyUrl.asOutParam());
     5423        if (FAILED(hrc))
     5424        {
     5425            LogRel(("CLOUD-NET: Failed to obtain proxy URL. hrc=%x\n", hrc));
     5426            return false;
     5427        }
     5428        Utf8Str strProxyUrl = proxyUrl;
     5429        if (!strProxyUrl.contains("://"))
     5430            strProxyUrl = "http://" + strProxyUrl;
     5431        const char *pcszProxyUrl = strProxyUrl.c_str();
     5432        RTURIPARSED Parsed;
     5433        rc = RTUriParse(pcszProxyUrl, &Parsed);
     5434        if (RT_FAILURE(rc))
     5435        {
     5436            LogRel(("CLOUD-NET: Failed to parse proxy URL: %ls (rc=%d)\n", proxyUrl.raw(), rc));
     5437            return false;
     5438        }
     5439
     5440        pszProxyType = RTUriParsedScheme(pcszProxyUrl, &Parsed);
     5441        if (!pszProxyType)
     5442        {
     5443            LogRel(("CLOUD-NET: Failed to get proxy scheme from proxy URL: %s\n", pcszProxyUrl));
     5444            return false;
     5445        }
     5446        RTStrToUpper(pszProxyType);
     5447
     5448        ProxyInfo.pszProxyHost = RTUriParsedAuthorityHost(pcszProxyUrl, &Parsed);
     5449        if (!ProxyInfo.pszProxyHost)
     5450        {
     5451            LogRel(("CLOUD-NET: Failed to get proxy host name from proxy URL: %s\n", pcszProxyUrl));
     5452            return false;
     5453        }
     5454        ProxyInfo.uProxyPort  = RTUriParsedAuthorityPort(pcszProxyUrl, &Parsed);
     5455        if (ProxyInfo.uProxyPort == UINT32_MAX)
     5456        {
     5457            LogRel(("CLOUD-NET: Failed to get proxy port from proxy URL: %s\n", pcszProxyUrl));
     5458            return false;
     5459        }
     5460        ProxyInfo.pszProxyUsername = RTUriParsedAuthorityUsername(pcszProxyUrl, &Parsed);
     5461        ProxyInfo.pszProxyPassword = RTUriParsedAuthorityPassword(pcszProxyUrl, &Parsed);
     5462    }
     5463    else if (enmProxyMode == ProxyMode_System)
     5464    {
     5465        hrc = RTHttpUseSystemProxySettings(hHttp);
     5466        if (RT_FAILURE(rc))
     5467        {
     5468            LogRel(("%s: RTHttpUseSystemProxySettings() failed: %Rrc", __FUNCTION__, rc));
     5469            RTHttpDestroy(hHttp);
     5470            return rc;
     5471        }
     5472        rc = RTHttpQueryProxyInfoForUrl(hHttp, ("http://" + strIpAddr).c_str(), &ProxyInfo);
     5473        RTHttpDestroy(hHttp);
     5474        if (RT_FAILURE(rc))
     5475        {
     5476            LogRel(("CLOUD-NET: Failed to get proxy for %s (rc=%Rrc)\n", strIpAddr.c_str(), rc));
     5477            return rc;
     5478        }
     5479
     5480        switch (ProxyInfo.enmProxyType)
     5481        {
     5482            case RTHTTPPROXYTYPE_NOPROXY:
     5483                /* Nothing to do */
     5484                return VINF_SUCCESS;
     5485            case RTHTTPPROXYTYPE_HTTP:
     5486                pszProxyType = RTStrDup("HTTP");
     5487                break;
     5488            case RTHTTPPROXYTYPE_HTTPS:
     5489            case RTHTTPPROXYTYPE_SOCKS4:
     5490            case RTHTTPPROXYTYPE_SOCKS5:
     5491                /* break; -- Fall through until support is implemented */
     5492            case RTHTTPPROXYTYPE_UNKNOWN:
     5493            case RTHTTPPROXYTYPE_INVALID:
     5494            case RTHTTPPROXYTYPE_END:
     5495            case RTHTTPPROXYTYPE_32BIT_HACK:
     5496                LogRel(("CLOUD-NET: Unsupported proxy type %u\n", ProxyInfo.enmProxyType));
     5497                RTHttpFreeProxyInfo(&ProxyInfo);
     5498                return VERR_INVALID_PARAMETER;
     5499        }
     5500    }
     5501    else
     5502    {
     5503        Assert(enmProxyMode == ProxyMode_NoProxy);
     5504        return VINF_SUCCESS;
     5505    }
     5506
     5507    /* Resolve proxy host name to IP address if necessary */
     5508    RTNETADDR addr;
     5509    RTSocketParseInetAddress(ProxyInfo.pszProxyHost, ProxyInfo.uProxyPort, &addr);
     5510    if (addr.enmType != RTNETADDRTYPE_IPV4)
     5511    {
     5512        LogRel(("CLOUD-NET: Unsupported address type %u\n", addr.enmType));
     5513        RTHttpFreeProxyInfo(&ProxyInfo);
     5514        return VERR_INVALID_PARAMETER;
     5515    }
     5516
     5517    InsertConfigString(pCfg, Utf8StrFmt("%sProxyType", pcszPrefix).c_str(), pszProxyType);
     5518    InsertConfigInteger(pCfg, Utf8StrFmt("%sProxyPort", pcszPrefix).c_str(), ProxyInfo.uProxyPort);
     5519    if (ProxyInfo.pszProxyHost)
     5520        InsertConfigString(pCfg, Utf8StrFmt("%sProxyHost", pcszPrefix).c_str(), Utf8StrFmt("%RTnaipv4", addr.uAddr.IPv4));
     5521    if (ProxyInfo.pszProxyUsername)
     5522        InsertConfigString(pCfg, Utf8StrFmt("%sProxyUser", pcszPrefix).c_str(), ProxyInfo.pszProxyUsername);
     5523    if (ProxyInfo.pszProxyPassword)
     5524        InsertConfigPassword(pCfg, Utf8StrFmt("%sProxyPassword", pcszPrefix).c_str(), ProxyInfo.pszProxyPassword);
     5525
     5526    RTHttpFreeProxyInfo(&ProxyInfo);
     5527    RTStrFree(pszProxyType);
     5528    return rc;
    53645529}
    53655530
     
    64606625                    InsertConfigString(pCfg, "SecondaryIP", mGateway.mCloudSecondaryPublicIp);
    64616626                    InsertConfigBytes(pCfg, "TargetMAC", &mGateway.mLocalMacAddress, sizeof(mGateway.mLocalMacAddress));
     6627                    hrc = i_configProxy(virtualBox, pCfg, "Primary", mGateway.mCloudPublicIp);
     6628                    if (FAILED(hrc))
     6629                    {
     6630                        return pVMM->pfnVMR3SetError(pUVM, hrc, RT_SRC_POS,
     6631                                                    N_("Failed to configure proxy for accessing cloud gateway instance via primary VNIC.\n"
     6632                                                        "Check VirtualBox.log for details."));
     6633                    }
     6634                    hrc = i_configProxy(virtualBox, pCfg, "Secondary", mGateway.mCloudSecondaryPublicIp);
     6635                    if (FAILED(hrc))
     6636                    {
     6637                        return pVMM->pfnVMR3SetError(pUVM, hrc, RT_SRC_POS,
     6638                                                    N_("Failed to configure proxy for accessing cloud gateway instance via secondary VNIC.\n"
     6639                                                        "Check VirtualBox.log for details."));
     6640                    }
    64626641                    networkName = bstr;
    64636642                    trunkType = Bstr(TRUNKTYPE_WHATEVER);
Note: See TracChangeset for help on using the changeset viewer.

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