Beispiel #1
0
static void
remove_connections_read (NMRemoteSettings *settings, gpointer user_data)
{
	RemoveInfo *info = user_data;
	GSList *list, *iter;

	g_source_remove (info->timeout_id);

	g_message ("Removing Bluetooth connections for %s", info->str_bdaddr);

	list = nm_remote_settings_list_connections (settings);
	for (iter = list; iter != NULL; iter = g_slist_next (iter)) {
		NMConnection *connection = iter->data;
		NMSettingBluetooth *s_bt;
		const GByteArray *tmp;

		s_bt = nm_connection_get_setting_bluetooth (connection);
		if (s_bt) {
			tmp = nm_setting_bluetooth_get_bdaddr (s_bt);
			if (tmp && memcmp (tmp->data, info->bdaddr->data, tmp->len) == 0)
				nm_remote_connection_delete (NM_REMOTE_CONNECTION (connection), delete_cb, NULL);
		}
	}
	g_slist_free (list);

	remove_cleanup (info);
}
static gboolean
hwaddr_matches (NMDevice *device,
                NMConnection *connection,
                const guint8 *other_hwaddr,
                guint other_hwaddr_len,
                gboolean fail_if_no_hwaddr)
{
    NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
    NMSettingBluetooth *s_bt;
    const GByteArray *mac = NULL;
    gboolean matches = FALSE;
    GByteArray *devmac;

    s_bt = nm_connection_get_setting_bluetooth (connection);
    if (s_bt)
        mac = nm_setting_bluetooth_get_bdaddr (s_bt);

    if (mac) {
        devmac = nm_utils_hwaddr_atoba (priv->bdaddr, ARPHRD_ETHER);
        g_return_val_if_fail (devmac != NULL, FALSE);
        g_return_val_if_fail (devmac->len == mac->len, FALSE);

        if (other_hwaddr) {
            g_return_val_if_fail (other_hwaddr_len == devmac->len, FALSE);
            matches = (memcmp (mac->data, other_hwaddr, mac->len) == 0) ? TRUE : FALSE;
        } else
            matches = (memcmp (mac->data, devmac->data, mac->len) == 0) ? TRUE : FALSE;

        g_byte_array_free (devmac, TRUE);
        return matches;
    } else if (fail_if_no_hwaddr == FALSE)
        return TRUE;

    return FALSE;
}
static gboolean
connection_compatible (NMBluezDevice *self, NMConnection *connection)
{
	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
	NMSettingBluetooth *s_bt;
	const char *bt_type;
	const char *bdaddr;

	if (!nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME))
		return FALSE;

	s_bt = nm_connection_get_setting_bluetooth (connection);
	if (!s_bt)
		return FALSE;

	if (!priv->address)
		return FALSE;

	bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
	if (!bdaddr)
		return FALSE;
	if (!nm_utils_hwaddr_matches (bdaddr, -1, priv->address, -1))
		return FALSE;

	bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
	if (   g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)
	    && !(priv->capabilities & NM_BT_CAPABILITY_DUN))
		return FALSE;

	if (   g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)
	    && !(priv->capabilities & NM_BT_CAPABILITY_NAP))
		return FALSE;

	return TRUE;
}
Beispiel #4
0
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
	NMSettingConnection *s_con;
	NMSettingBluetooth *s_bt;
	const char *ctype;
	const GByteArray *mac;
	const char *hw_str;
	struct ether_addr *hw_mac;
	NMBluetoothCapabilities dev_caps;
	NMBluetoothCapabilities bt_type;

	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	s_con = nm_connection_get_setting_connection (connection);
	g_assert (s_con);

	ctype = nm_setting_connection_get_connection_type (s_con);
	if (strcmp (ctype, NM_SETTING_BLUETOOTH_SETTING_NAME) != 0) {
		g_set_error (error, NM_DEVICE_BT_ERROR, NM_DEVICE_BT_ERROR_NOT_BT_CONNECTION,
		             "The connection was not a Bluetooth connection.");
		return FALSE;
	}

	s_bt = nm_connection_get_setting_bluetooth (connection);
	if (!s_bt) {
		g_set_error (error, NM_DEVICE_BT_ERROR, NM_DEVICE_BT_ERROR_INVALID_BT_CONNECTION,
		             "The connection was not a valid Bluetooth connection.");
		return FALSE;
	}

	/* Check BT address */
	hw_str = nm_device_bt_get_hw_address (NM_DEVICE_BT (device));
	if (hw_str) {
		hw_mac = ether_aton (hw_str);
		if (!hw_mac) {
			g_set_error (error, NM_DEVICE_BT_ERROR, NM_DEVICE_BT_ERROR_INVALID_DEVICE_MAC,
			             "Invalid device MAC address.");
			return FALSE;
		}
		mac = nm_setting_bluetooth_get_bdaddr (s_bt);
		if (mac && hw_mac && memcmp (mac->data, hw_mac->ether_addr_octet, ETH_ALEN)) {
			g_set_error (error, NM_DEVICE_BT_ERROR, NM_DEVICE_BT_ERROR_MAC_MISMATCH,
			             "The MACs of the device and the connection didn't match.");
			return FALSE;
		}
	}

	dev_caps = nm_device_bt_get_capabilities (NM_DEVICE_BT (device));
	bt_type = get_connection_bt_type (connection);
	if (!(bt_type & dev_caps)) {
		g_set_error (error, NM_DEVICE_BT_ERROR, NM_DEVICE_BT_ERROR_MISSING_DEVICE_CAPS,
		             "The device missed BT capabilities required by the connection.");
		return FALSE;
	}

	return TRUE;
}
static gboolean
real_check_connection_compatible (NMDevice *device,
                                  NMConnection *connection,
                                  GError **error)
{
	NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
	NMSettingConnection *s_con;
	NMSettingBluetooth *s_bt;
	const GByteArray *array;
	char *str;
	int addr_match = FALSE;
	guint32 bt_type;

	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
	g_assert (s_con);

	if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME)) {
		g_set_error (error,
		             NM_BT_ERROR, NM_BT_ERROR_CONNECTION_NOT_BT,
		             "The connection was not a Bluetooth connection.");
		return FALSE;
	}

	s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
	if (!s_bt) {
		g_set_error (error,
		             NM_BT_ERROR, NM_BT_ERROR_CONNECTION_INVALID,
		             "The connection was not a valid Bluetooth connection.");
		return FALSE;
	}

	array = nm_setting_bluetooth_get_bdaddr (s_bt);
	if (!array || (array->len != ETH_ALEN)) {
		g_set_error (error,
		             NM_BT_ERROR, NM_BT_ERROR_CONNECTION_INVALID,
		             "The connection did not contain a valid Bluetooth address.");
		return FALSE;
	}

	bt_type = get_connection_bt_type (connection);
	if (!(bt_type & priv->capabilities)) {
		g_set_error (error,
		             NM_BT_ERROR, NM_BT_ERROR_CONNECTION_INCOMPATIBLE,
		             "The connection was not compatible with the device's capabilities.");
		return FALSE;
	}

	str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
	                       array->data[0], array->data[1], array->data[2],
	                       array->data[3], array->data[4], array->data[5]);
	addr_match = !strcmp (priv->bdaddr, str);
	g_free (str);

	return addr_match;
}
static void
populate_ui (CEPageBluetooth *self, NMConnection *connection)
{
	CEPageBluetoothPrivate *priv = CE_PAGE_BLUETOOTH_GET_PRIVATE (self);
	NMSettingBluetooth *setting = priv->setting;
	const char *bdaddr;

	bdaddr = nm_setting_bluetooth_get_bdaddr (setting);
	if (bdaddr)
		gtk_entry_set_text (priv->bdaddr, bdaddr);
}
static gboolean
match_connection_bdaddr (NMConnection *connection, const GByteArray *bdaddr)
{
	NMSettingBluetooth *s_bt;
	const GByteArray *tmp;

	s_bt = nm_connection_get_setting_bluetooth (connection);
	if (s_bt) {
		tmp = nm_setting_bluetooth_get_bdaddr (s_bt);
		if (tmp && memcmp (tmp->data, bdaddr->data, tmp->len) == 0)
			return TRUE;
	}
	return FALSE;
}
static void
get_property (GObject *object, guint prop_id,
              GValue *value, GParamSpec *pspec)
{
	NMSettingBluetooth *setting = NM_SETTING_BLUETOOTH (object);

	switch (prop_id) {
	case PROP_BDADDR:
		g_value_set_string (value, nm_setting_bluetooth_get_bdaddr (setting));
		break;
	case PROP_TYPE:
		g_value_set_string (value, nm_setting_bluetooth_get_connection_type (setting));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
	NMSettingBluetooth *s_bt;
	const char *hw_addr, *setting_addr;
	NMBluetoothCapabilities dev_caps;
	NMBluetoothCapabilities bt_type;

	if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->connection_compatible (device, connection, error))
		return FALSE;

	if (!nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) {
		g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
		             _("The connection was not a Bluetooth connection."));
		return FALSE;
	}

	/* Check BT address */
	hw_addr = nm_device_bt_get_hw_address (NM_DEVICE_BT (device));
	if (hw_addr) {
		if (!nm_utils_hwaddr_valid (hw_addr, ETH_ALEN)) {
			g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
			                     _("Invalid device Bluetooth address."));
			return FALSE;
		}
		s_bt = nm_connection_get_setting_bluetooth (connection);
		setting_addr = nm_setting_bluetooth_get_bdaddr (s_bt);
		if (setting_addr && !nm_utils_hwaddr_matches (setting_addr, -1, hw_addr, -1)) {
			g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
			                     _("The Bluetooth addresses of the device and the connection didn't match."));
			return FALSE;
		}
	}

	dev_caps = nm_device_bt_get_capabilities (NM_DEVICE_BT (device));
	bt_type = get_connection_bt_type (connection);
	if (!(bt_type & dev_caps)) {
		g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
		                     _("The device is lacking Bluetooth capabilities required by the connection."));
		return FALSE;
	}

	return TRUE;
}
static gboolean
check_bt_compatible (NMDeviceBt *device, NMConnection *connection, GError **error)
{
        NMSettingConnection *s_con;
        NMSettingBluetooth *s_bt;
        const GByteArray *array;
        char *str;
        const char *device_hw_str;
        int addr_match = FALSE;
        const char *bt_type_str;
        guint32 bt_type, bt_capab;

        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

        s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
        g_assert (s_con);

        if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME)) {
                g_set_error (error, 0, 0,
                             "The connection was not a Bluetooth connection.");
                return FALSE;
        }

        s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
        if (!s_bt) {
                g_set_error (error, 0, 0,
                             "The connection was not a valid Bluetooth connection.");
                return FALSE;
        }

        array = nm_setting_bluetooth_get_bdaddr (s_bt);
        if (!array || (array->len != ETH_ALEN)) {
                g_set_error (error, 0, 0,
                             "The connection did not contain a valid Bluetooth address.");
                return FALSE;
        }

        bt_type_str = nm_setting_bluetooth_get_connection_type (s_bt);
        g_assert (bt_type_str);

        bt_type = NM_BT_CAPABILITY_NONE;
        if (!strcmp (bt_type_str, NM_SETTING_BLUETOOTH_TYPE_DUN))
                bt_type = NM_BT_CAPABILITY_DUN;
        else if (!strcmp (bt_type_str, NM_SETTING_BLUETOOTH_TYPE_PANU))
                bt_type = NM_BT_CAPABILITY_NAP;

        bt_capab = nm_device_bt_get_capabilities (device);
        if (!(bt_type & bt_capab)) {
                g_set_error (error, 0, 0,
                             "The connection was not compatible with the device's capabilities.");
                return FALSE;
        }

        device_hw_str = nm_device_bt_get_hw_address (device);

        str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
                               array->data[0], array->data[1], array->data[2],
                               array->data[3], array->data[4], array->data[5]);
        addr_match = !strcmp (device_hw_str, str);
        g_free (str);

        return addr_match;
}
static gboolean
complete_connection (NMDevice *device,
                     NMConnection *connection,
                     const char *specific_object,
                     const GSList *existing_connections,
                     GError **error)
{
    NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
    NMSettingBluetooth *s_bt;
    const GByteArray *setting_bdaddr;
    struct ether_addr *devaddr = ether_aton (priv->bdaddr);
    const char *ctype;
    gboolean is_dun = FALSE, is_pan = FALSE;
    NMSettingGsm *s_gsm;
    NMSettingCdma *s_cdma;
    NMSettingSerial *s_serial;
    NMSettingPPP *s_ppp;
    const char *format = NULL, *preferred = NULL;

    s_gsm = nm_connection_get_setting_gsm (connection);
    s_cdma = nm_connection_get_setting_cdma (connection);
    s_serial = nm_connection_get_setting_serial (connection);
    s_ppp = nm_connection_get_setting_ppp (connection);

    s_bt = nm_connection_get_setting_bluetooth (connection);
    if (!s_bt) {
        s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new ();
        nm_connection_add_setting (connection, NM_SETTING (s_bt));
    }

    ctype = nm_setting_bluetooth_get_connection_type (s_bt);
    if (ctype) {
        if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_DUN))
            is_dun = TRUE;
        else if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_PANU))
            is_pan = TRUE;
    } else {
        if (s_gsm || s_cdma)
            is_dun = TRUE;
        else if (priv->capabilities & NM_BT_CAPABILITY_NAP)
            is_pan = TRUE;
    }

    if (is_pan) {
        /* Make sure the device supports PAN */
        if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) {
            g_set_error_literal (error,
                                 NM_SETTING_BLUETOOTH_ERROR,
                                 NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
                                 "PAN required but Bluetooth device does not support NAP");
            return FALSE;
        }

        /* PAN can't use any DUN-related settings */
        if (s_gsm || s_cdma || s_serial || s_ppp) {
            g_set_error_literal (error,
                                 NM_SETTING_BLUETOOTH_ERROR,
                                 NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
                                 "PAN incompatible with GSM, CDMA, or serial settings");
            return FALSE;
        }

        g_object_set (G_OBJECT (s_bt),
                      NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
                      NULL);

        format = _("PAN connection %d");
    } else if (is_dun) {
        /* Make sure the device supports PAN */
        if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) {
            g_set_error_literal (error,
                                 NM_SETTING_BLUETOOTH_ERROR,
                                 NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
                                 "DUN required but Bluetooth device does not support DUN");
            return FALSE;
        }

        /* Need at least a GSM or a CDMA setting */
        if (!s_gsm && !s_cdma) {
            g_set_error_literal (error,
                                 NM_SETTING_BLUETOOTH_ERROR,
                                 NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
                                 "Setting requires DUN but no GSM or CDMA setting is present");
            return FALSE;
        }

        g_object_set (G_OBJECT (s_bt),
                      NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN,
                      NULL);

        if (s_gsm) {
            format = _("GSM connection %d");
            if (!nm_setting_gsm_get_number (s_gsm))
                g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL);
        } else if (s_cdma) {
            format = _("CDMA connection %d");
            if (!nm_setting_cdma_get_number (s_cdma))
                g_object_set (G_OBJECT (s_cdma), NM_SETTING_GSM_NUMBER, "#777", NULL);
        } else
            format = _("DUN connection %d");
    } else {
        g_set_error_literal (error,
                             NM_SETTING_BLUETOOTH_ERROR,
                             NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
                             "Unknown/unhandled Bluetooth connection type");
        return FALSE;
    }

    nm_utils_complete_generic (connection,
                               NM_SETTING_BLUETOOTH_SETTING_NAME,
                               existing_connections,
                               format,
                               preferred,
                               is_dun ? FALSE : TRUE); /* No IPv6 yet for DUN */

    setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
    if (setting_bdaddr) {
        /* Make sure the setting BT Address (if any) matches the device's */
        if (memcmp (setting_bdaddr->data, devaddr->ether_addr_octet, ETH_ALEN)) {
            g_set_error_literal (error,
                                 NM_SETTING_BLUETOOTH_ERROR,
                                 NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
                                 NM_SETTING_BLUETOOTH_BDADDR);
            return FALSE;
        }
    } else {
        GByteArray *bdaddr;
        const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };

        /* Lock the connection to this device by default */
        if (memcmp (devaddr->ether_addr_octet, null_mac, ETH_ALEN)) {
            bdaddr = g_byte_array_sized_new (ETH_ALEN);
            g_byte_array_append (bdaddr, devaddr->ether_addr_octet, ETH_ALEN);
            g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NULL);
            g_byte_array_free (bdaddr, TRUE);
        }
    }

    return TRUE;
}