tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DbusWifiScanner.cpp (5531B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include <gio/gio.h>
      6 #include "DbusWifiScanner.h"
      7 #include "nsWifiAccessPoint.h"
      8 #include "mozilla/GUniquePtr.h"
      9 #include "mozilla/RefPtr.h"
     10 #include "mozilla/GRefPtr.h"
     11 #include "nsAppShell.h"
     12 
     13 namespace mozilla {
     14 
     15 WifiScannerImpl::WifiScannerImpl() { MOZ_COUNT_CTOR(WifiScannerImpl); }
     16 
     17 WifiScannerImpl::~WifiScannerImpl() { MOZ_COUNT_DTOR(WifiScannerImpl); }
     18 
     19 nsresult WifiScannerImpl::GetAccessPointsFromWLAN(
     20    AccessPointArray& aAccessPoints) {
     21  nsAppShell::DBusConnectionCheck();
     22  RefPtr<GDBusProxy> proxy = dont_AddRef(g_dbus_proxy_new_for_bus_sync(
     23      G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
     24      "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager",
     25      "org.freedesktop.NetworkManager", nullptr, nullptr));
     26  if (!proxy) {
     27    return NS_ERROR_FAILURE;
     28  }
     29 
     30  RefPtr<GVariant> result =
     31      dont_AddRef(g_dbus_proxy_get_cached_property(proxy, "Devices"));
     32  if (!result ||
     33      !g_variant_is_of_type(result, G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) {
     34    return NS_ERROR_FAILURE;
     35  }
     36 
     37  gsize num = g_variant_n_children(result);
     38  for (gsize i = 0; i < num; i++) {
     39    const char* devicePath =
     40        g_variant_get_string(g_variant_get_child_value(result, i), nullptr);
     41    if (!devicePath || !AddDevice(devicePath, aAccessPoints)) {
     42      return NS_ERROR_FAILURE;
     43    }
     44  }
     45 
     46  return NS_OK;
     47 }
     48 
     49 bool WifiScannerImpl::AddDevice(const char* aDevicePath,
     50                                AccessPointArray& aAccessPoints) {
     51  nsAppShell::DBusConnectionCheck();
     52  RefPtr<GDBusProxy> proxy = dont_AddRef(g_dbus_proxy_new_for_bus_sync(
     53      G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
     54      "org.freedesktop.NetworkManager", aDevicePath,
     55      "org.freedesktop.NetworkManager.Device", nullptr, nullptr));
     56  if (!proxy) {
     57    return false;
     58  }
     59 
     60  RefPtr<GVariant> deviceType =
     61      dont_AddRef(g_dbus_proxy_get_cached_property(proxy, "DeviceType"));
     62  if (!deviceType || !g_variant_is_of_type(deviceType, G_VARIANT_TYPE_UINT32)) {
     63    return false;
     64  }
     65 
     66  // http://projects.gnome.org/NetworkManager/developers/api/07/spec-07.html
     67  // Refer to NM_DEVICE_TYPE_WIFI under NM_DEVICE_TYPE.
     68  const uint32_t NM_DEVICE_TYPE_WIFI = 2;
     69  if (g_variant_get_uint32(deviceType) != NM_DEVICE_TYPE_WIFI) {
     70    // Don't probe non-wifi devices
     71    return true;
     72  }
     73 
     74  nsAppShell::DBusConnectionCheck();
     75  proxy = dont_AddRef(g_dbus_proxy_new_for_bus_sync(
     76      G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
     77      "org.freedesktop.NetworkManager", aDevicePath,
     78      "org.freedesktop.NetworkManager.Device.Wireless", nullptr, nullptr));
     79  if (!proxy) {
     80    return false;
     81  }
     82 
     83  RefPtr<GVariant> points =
     84      dont_AddRef(g_dbus_proxy_get_cached_property(proxy, "AccessPoints"));
     85  if (!points ||
     86      !g_variant_is_of_type(points, G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) {
     87    return false;
     88  }
     89 
     90  gsize num = g_variant_n_children(points);
     91  for (gsize i = 0; i < num; i++) {
     92    const char* ap =
     93        g_variant_get_string(g_variant_get_child_value(points, i), nullptr);
     94    if (!ap || !AddAPProperties(ap, aAccessPoints)) {
     95      return false;
     96    }
     97  }
     98  return true;
     99 }
    100 
    101 bool WifiScannerImpl::AddAPProperties(const char* aApPath,
    102                                      AccessPointArray& aAccessPoints) {
    103  nsAppShell::DBusConnectionCheck();
    104  RefPtr<GDBusProxy> proxy = dont_AddRef(g_dbus_proxy_new_for_bus_sync(
    105      G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
    106      "org.freedesktop.NetworkManager", aApPath,
    107      "org.freedesktop.NetworkManager.AccessPoint", nullptr, nullptr));
    108  if (!proxy) {
    109    return false;
    110  }
    111 
    112  RefPtr<nsWifiAccessPoint> ap = new nsWifiAccessPoint();
    113 
    114  RefPtr<GVariant> ssid =
    115      dont_AddRef(g_dbus_proxy_get_cached_property(proxy, "Ssid"));
    116  if (!ssid || !g_variant_is_of_type(ssid, G_VARIANT_TYPE_BYTESTRING)) {
    117    return false;
    118  }
    119  const uint32_t MAX_SSID_LEN = 32;
    120  gsize len = 0;
    121  const char* ssidString = static_cast<const char*>(
    122      g_variant_get_fixed_array(ssid, &len, sizeof(guint8)));
    123  if (ssidString && len && len <= MAX_SSID_LEN) {
    124    ap->setSSID(ssidString, len);
    125  }
    126 
    127  RefPtr<GVariant> hwAddress =
    128      dont_AddRef(g_dbus_proxy_get_cached_property(proxy, "HwAddress"));
    129  if (!hwAddress || !g_variant_is_of_type(hwAddress, G_VARIANT_TYPE_STRING)) {
    130    return false;
    131  }
    132  GUniquePtr<gchar> address(g_variant_dup_string(hwAddress, nullptr));
    133  SetMac(address.get(), ap);
    134 
    135  RefPtr<GVariant> st =
    136      dont_AddRef(g_dbus_proxy_get_cached_property(proxy, "Strength"));
    137  if (!st || !g_variant_is_of_type(st, G_VARIANT_TYPE_BYTE)) {
    138    return false;
    139  }
    140 
    141  uint8_t strength = g_variant_get_byte(st);   // in %
    142  int signal_strength = (strength / 2) - 100;  // strength to dB
    143  ap->setSignal(signal_strength);
    144 
    145  aAccessPoints.AppendElement(ap);
    146  return true;
    147 }
    148 
    149 bool WifiScannerImpl::SetMac(char* aHwAddress, nsWifiAccessPoint* aAp) {
    150  // hwAddress format is XX:XX:XX:XX:XX:XX. Need to convert to XXXXXX format.
    151  const uint32_t MAC_LEN = 6;
    152  uint8_t macAddress[MAC_LEN];
    153  char* savedPtr = nullptr;
    154  char* token = strtok_r(aHwAddress, ":", &savedPtr);
    155  for (unsigned char& macAddres : macAddress) {
    156    if (!token) {
    157      return false;
    158    }
    159    macAddres = strtoul(token, nullptr, 16);
    160    token = strtok_r(nullptr, ":", &savedPtr);
    161  }
    162  aAp->setMac(macAddress);
    163  return true;
    164 }
    165 
    166 }  // namespace mozilla