[network-manager-applet/dcbw/ap] editor: initial hotspot mode support
- From: Dan Williams <dcbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-applet/dcbw/ap] editor: initial hotspot mode support
- Date: Thu, 26 Feb 2015 21:31:02 +0000 (UTC)
commit ce40e7863aeb69637b75fa779d122d908cf73884
Author: Dan Williams <dcbw redhat com>
Date: Mon Sep 17 22:47:21 2012 -0500
editor: initial hotspot mode support
src/connection-editor/ce-page-wifi.ui | 3 +
src/connection-editor/page-wifi-security.c | 111 +++++++++++++++++-----------
src/connection-editor/page-wifi.c | 69 +++++++++---------
src/wireless-security/wireless-security.c | 9 ++
src/wireless-security/wireless-security.h | 3 +
src/wireless-security/ws-dynamic-wep.c | 1 +
src/wireless-security/ws-leap.c | 1 +
src/wireless-security/ws-wpa-eap.c | 1 +
8 files changed, 120 insertions(+), 78 deletions(-)
---
diff --git a/src/connection-editor/ce-page-wifi.ui b/src/connection-editor/ce-page-wifi.ui
index e2e544b..7765b6f 100644
--- a/src/connection-editor/ce-page-wifi.ui
+++ b/src/connection-editor/ce-page-wifi.ui
@@ -50,6 +50,9 @@
<row>
<col id="0" translatable="yes">Ad-hoc</col>
</row>
+ <row>
+ <col id="0" translatable="yes">Hotspot</col>
+ </row>
</data>
</object>
<object class="GtkTable" id="WifiPage">
diff --git a/src/connection-editor/page-wifi-security.c b/src/connection-editor/page-wifi-security.c
index 3e8d50e..a604f41 100644
--- a/src/connection-editor/page-wifi-security.c
+++ b/src/connection-editor/page-wifi-security.c
@@ -39,12 +39,13 @@ G_DEFINE_TYPE (CEPageWifiSecurity, ce_page_wifi_security, CE_TYPE_PAGE)
typedef struct {
GtkSizeGroup *group;
GtkComboBox *security_combo;
- gboolean adhoc;
+ NM80211Mode mode;
} CEPageWifiSecurityPrivate;
#define S_NAME_COLUMN 0
#define S_SEC_COLUMN 1
#define S_ADHOC_VALID_COLUMN 2
+#define S_HOTSPOT_VALID_COLUMN 3
static gboolean
find_proto (NMSettingWirelessSecurity *sec, const char *item)
@@ -182,7 +183,8 @@ add_security_item (CEPageWifiSecurity *self,
GtkListStore *model,
GtkTreeIter *iter,
const char *text,
- gboolean adhoc_valid)
+ gboolean adhoc_valid,
+ gboolean hotspot_valid)
{
wireless_security_set_changed_notify (sec, stuff_changed_cb, self);
gtk_list_store_append (model, iter);
@@ -190,6 +192,7 @@ add_security_item (CEPageWifiSecurity *self,
S_NAME_COLUMN, text,
S_SEC_COLUMN, sec,
S_ADHOC_VALID_COLUMN, adhoc_valid,
+ S_HOTSPOT_VALID_COLUMN, hotspot_valid,
-1);
wireless_security_unref (sec);
}
@@ -201,16 +204,47 @@ set_sensitive (GtkCellLayout *cell_layout,
GtkTreeIter *iter,
gpointer data)
{
- gboolean *adhoc = data;
- gboolean sensitive = TRUE, adhoc_valid = TRUE;
+ NM80211Mode *mode = data;
+ gboolean sensitive = TRUE;
- gtk_tree_model_get (tree_model, iter, S_ADHOC_VALID_COLUMN, &adhoc_valid, -1);
- if (*adhoc && !adhoc_valid)
- sensitive = FALSE;
+ if (*mode == NM_802_11_MODE_ADHOC)
+ gtk_tree_model_get (tree_model, iter, S_ADHOC_VALID_COLUMN, &sensitive, -1);
+ else if (*mode == NM_802_11_MODE_AP)
+ gtk_tree_model_get (tree_model, iter, S_HOTSPOT_VALID_COLUMN, &sensitive, -1);
g_object_set (cell, "sensitive", sensitive, NULL);
}
+static gboolean
+security_valid (NMUtilsSecurityType sectype, NM80211Mode mode)
+{
+ guint32 dev_caps = 0;
+
+ /* Fake some device capabilities here since we don't know about the
+ * NMDevice object to get the card's real capabilities.
+ */
+ dev_caps = NM_WIFI_DEVICE_CAP_CIPHER_WEP40
+ | NM_WIFI_DEVICE_CAP_CIPHER_WEP104
+ | NM_WIFI_DEVICE_CAP_CIPHER_TKIP
+ | NM_WIFI_DEVICE_CAP_CIPHER_CCMP
+ | NM_WIFI_DEVICE_CAP_WPA
+ | NM_WIFI_DEVICE_CAP_RSN;
+
+ switch (mode) {
+ case NM_802_11_MODE_AP:
+ return nm_utils_ap_mode_security_valid (sectype, NM_WIFI_DEVICE_CAP_AP);
+ case NM_802_11_MODE_ADHOC:
+ case NM_802_11_MODE_INFRA:
+ default:
+ return nm_utils_security_valid (sectype,
+ dev_caps,
+ FALSE,
+ (mode == NM_802_11_MODE_ADHOC),
+ 0, 0, 0);
+ }
+ g_assert_not_reached ();
+}
+
static void
finish_setup (CEPageWifiSecurity *self, gpointer unused, GError *error, gpointer user_data)
{
@@ -219,11 +253,9 @@ finish_setup (CEPageWifiSecurity *self, gpointer unused, GError *error, gpointer
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
NMConnection *connection = parent->connection;
- gboolean is_adhoc = FALSE;
+ NM80211Mode mode = NM_802_11_MODE_INFRA;
GtkListStore *sec_model;
GtkTreeIter iter;
- const char *mode;
- guint32 dev_caps = 0;
NMUtilsSecurityType default_type = NMU_SEC_NONE;
int active = -1;
int item = 0;
@@ -236,39 +268,31 @@ finish_setup (CEPageWifiSecurity *self, gpointer unused, GError *error, gpointer
s_wireless = nm_connection_get_setting_wireless (connection);
g_assert (s_wireless);
- combo = GTK_COMBO_BOX (gtk_builder_get_object (parent->builder, "wifi_security_combo"));
-
- dev_caps = NM_WIFI_DEVICE_CAP_CIPHER_WEP40
- | NM_WIFI_DEVICE_CAP_CIPHER_WEP104
- | NM_WIFI_DEVICE_CAP_CIPHER_TKIP
- | NM_WIFI_DEVICE_CAP_CIPHER_CCMP
- | NM_WIFI_DEVICE_CAP_WPA
- | NM_WIFI_DEVICE_CAP_RSN;
-
- mode = nm_setting_wireless_get_mode (s_wireless);
- if (mode && !strcmp (mode, "adhoc"))
- is_adhoc = TRUE;
- priv->adhoc = is_adhoc;
+ if (!g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), "adhoc"))
+ mode = NM_802_11_MODE_ADHOC;
+ else if (!g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), "ap"))
+ mode = NM_802_11_MODE_AP;
s_wireless_sec = nm_connection_get_setting_wireless_security (connection);
if (s_wireless_sec)
default_type = get_default_type_for_security (s_wireless_sec);
- sec_model = gtk_list_store_new (3, G_TYPE_STRING, wireless_security_get_type (), G_TYPE_BOOLEAN);
+ sec_model = gtk_list_store_new (4, G_TYPE_STRING, wireless_security_get_type (), G_TYPE_BOOLEAN,
G_TYPE_BOOLEAN);
- if (nm_utils_security_valid (NMU_SEC_NONE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+ if (security_valid (NMU_SEC_NONE, mode)) {
gtk_list_store_append (sec_model, &iter);
gtk_list_store_set (sec_model, &iter,
S_NAME_COLUMN, C_("Wi-Fi/Ethernet security", "None"),
S_ADHOC_VALID_COLUMN, TRUE,
+ S_HOTSPOT_VALID_COLUMN, TRUE,
-1);
if (default_type == NMU_SEC_NONE)
active = item;
item++;
}
- if (nm_utils_security_valid (NMU_SEC_STATIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+ if (security_valid (NMU_SEC_STATIC_WEP, mode)) {
WirelessSecurityWEPKey *ws_wep;
NMWepKeyType wep_type = NM_WEP_KEY_TYPE_KEY;
@@ -286,7 +310,7 @@ finish_setup (CEPageWifiSecurity *self, gpointer unused, GError *error, gpointer
if (ws_wep) {
add_security_item (self, WIRELESS_SECURITY (ws_wep), sec_model,
&iter, _("WEP 40/128-bit Key (Hex or ASCII)"),
- TRUE);
+ TRUE, TRUE);
if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type ==
NM_WEP_KEY_TYPE_KEY))
active = item;
item++;
@@ -295,74 +319,73 @@ finish_setup (CEPageWifiSecurity *self, gpointer unused, GError *error, gpointer
ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_PASSPHRASE, FALSE, FALSE);
if (ws_wep) {
add_security_item (self, WIRELESS_SECURITY (ws_wep), sec_model,
- &iter, _("WEP 128-bit Passphrase"), TRUE);
+ &iter, _("WEP 128-bit Passphrase"), TRUE, TRUE);
if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type ==
NM_WEP_KEY_TYPE_PASSPHRASE))
active = item;
item++;
}
}
- if (nm_utils_security_valid (NMU_SEC_LEAP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+ if (security_valid (NMU_SEC_LEAP, mode)) {
WirelessSecurityLEAP *ws_leap;
ws_leap = ws_leap_new (connection, FALSE);
if (ws_leap) {
add_security_item (self, WIRELESS_SECURITY (ws_leap), sec_model,
- &iter, _("LEAP"), FALSE);
+ &iter, _("LEAP"), FALSE, FALSE);
if ((active < 0) && (default_type == NMU_SEC_LEAP))
active = item;
item++;
}
}
- if (nm_utils_security_valid (NMU_SEC_DYNAMIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+ if (security_valid (NMU_SEC_DYNAMIC_WEP, mode)) {
WirelessSecurityDynamicWEP *ws_dynamic_wep;
ws_dynamic_wep = ws_dynamic_wep_new (connection, TRUE, FALSE);
if (ws_dynamic_wep) {
add_security_item (self, WIRELESS_SECURITY (ws_dynamic_wep), sec_model,
- &iter, _("Dynamic WEP (802.1x)"), FALSE);
+ &iter, _("Dynamic WEP (802.1x)"), FALSE, FALSE);
if ((active < 0) && (default_type == NMU_SEC_DYNAMIC_WEP))
active = item;
item++;
}
}
- if ( nm_utils_security_valid (NMU_SEC_WPA_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0)
- || nm_utils_security_valid (NMU_SEC_WPA2_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+ if (security_valid (NMU_SEC_WPA_PSK, mode) || security_valid (NMU_SEC_WPA2_PSK, mode)) {
WirelessSecurityWPAPSK *ws_wpa_psk;
ws_wpa_psk = ws_wpa_psk_new (connection, FALSE);
if (ws_wpa_psk) {
add_security_item (self, WIRELESS_SECURITY (ws_wpa_psk), sec_model,
- &iter, _("WPA & WPA2 Personal"), FALSE);
+ &iter, _("WPA & WPA2 Personal"), FALSE, TRUE);
if ((active < 0) && ((default_type == NMU_SEC_WPA_PSK) || (default_type ==
NMU_SEC_WPA2_PSK)))
active = item;
item++;
}
}
- if ( nm_utils_security_valid (NMU_SEC_WPA_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0)
- || nm_utils_security_valid (NMU_SEC_WPA2_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+ if (security_valid (NMU_SEC_WPA_ENTERPRISE, mode) || security_valid (NMU_SEC_WPA2_ENTERPRISE, mode)) {
WirelessSecurityWPAEAP *ws_wpa_eap;
ws_wpa_eap = ws_wpa_eap_new (connection, TRUE, FALSE);
if (ws_wpa_eap) {
add_security_item (self, WIRELESS_SECURITY (ws_wpa_eap), sec_model,
- &iter, _("WPA & WPA2 Enterprise"), FALSE);
+ &iter, _("WPA & WPA2 Enterprise"), FALSE, FALSE);
if ((active < 0) && ((default_type == NMU_SEC_WPA_ENTERPRISE) || (default_type ==
NMU_SEC_WPA2_ENTERPRISE)))
active = item;
item++;
}
}
+ combo = GTK_COMBO_BOX (gtk_builder_get_object (parent->builder, "wifi_security_combo"));
gtk_combo_box_set_model (combo, GTK_TREE_MODEL (sec_model));
gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", S_NAME_COLUMN, NULL);
- gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer, set_sensitive, &priv->adhoc,
NULL);
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer, set_sensitive, &priv->mode,
NULL);
gtk_combo_box_set_active (combo, active < 0 ? 0 : (guint32) active);
g_object_unref (G_OBJECT (sec_model));
@@ -461,14 +484,16 @@ validate (CEPage *page, NMConnection *connection, GError **error)
g_assert (s_wireless);
/* Kernel Ad-Hoc WPA support is busted; it creates open networks. Disable
- * WPA when Ad-Hoc is selected. set_sensitive() will pick up priv->adhoc
+ * WPA when Ad-Hoc is selected. set_sensitive() will pick up priv->mode
* and do the right thing.
*/
mode = nm_setting_wireless_get_mode (s_wireless);
if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0)
- priv->adhoc = TRUE;
+ priv->mode = NM_802_11_MODE_ADHOC;
+ else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0)
+ priv->mode = NM_802_11_MODE_AP;
else
- priv->adhoc = FALSE;
+ priv->mode = NM_802_11_MODE_INFRA;
sec = wireless_security_combo_get_active (self);
if (sec) {
@@ -486,7 +511,7 @@ validate (CEPage *page, NMConnection *connection, GError **error)
valid = FALSE;
}
- if (priv->adhoc) {
+ if (priv->mode == NM_802_11_MODE_ADHOC) {
if (!wireless_security_adhoc_compatible (sec)) {
g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, "Security not compatible
with Ad-Hoc mode");
valid = FALSE;
diff --git a/src/connection-editor/page-wifi.c b/src/connection-editor/page-wifi.c
index c6d0cc4..4671c92 100644
--- a/src/connection-editor/page-wifi.c
+++ b/src/connection-editor/page-wifi.c
@@ -238,14 +238,21 @@ mode_combo_changed_cb (GtkComboBox *combo,
CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
CEPage *parent = CE_PAGE (self);
GtkWidget *widget_band_label, *widget_chan_label, *widget_bssid_label;
- gboolean adhoc;
+ gboolean show_freq = FALSE;
+ gboolean show_bssid = TRUE;
switch (gtk_combo_box_get_active (GTK_COMBO_BOX (combo))) {
+ case 2: /* hotspot */
case 1: /* adhoc */
- adhoc = TRUE;
+ /* BSSID is random and is created by kernel for Ad-Hoc networks
+ * http://lxr.linux.no/linux+v3.7.6/net/mac80211/ibss.c#L685
+ * For AP-mode, the BSSID is the MAC address of the device.
+ */
+ show_bssid = FALSE;
+ show_freq = TRUE;
break;
default: /* infrastructure */
- adhoc = FALSE;
+ show_freq = FALSE;
break;
}
@@ -253,36 +260,19 @@ mode_combo_changed_cb (GtkComboBox *combo,
widget_chan_label = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_channel_label"));
widget_bssid_label = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_bssid_label"));
- if (adhoc) {
- /* For Ad-Hoc show Band and Channel */
- gtk_widget_show (widget_band_label);
- gtk_widget_show (GTK_WIDGET (priv->band));
- gtk_widget_show (widget_chan_label);
- gtk_widget_show (GTK_WIDGET (priv->channel));
+ gtk_widget_set_visible (widget_band_label, show_freq);
+ gtk_widget_set_sensitive (widget_band_label, show_freq);
+ gtk_widget_set_visible (GTK_WIDGET (priv->band), show_freq);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->band), show_freq);
+ gtk_widget_set_visible (widget_chan_label, show_freq);
+ gtk_widget_set_sensitive (widget_chan_label, show_freq);
+ gtk_widget_set_visible (GTK_WIDGET (priv->channel), show_freq);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), show_freq);
- /* and hide BSSID
- * BSSID is random and is created by kernel for Ad-Hoc networks
- * http://lxr.linux.no/linux+v3.7.6/net/mac80211/ibss.c#L685
- */
- gtk_widget_hide (widget_bssid_label);
- gtk_widget_hide (GTK_WIDGET (priv->bssid));
- } else {
- /* Do opposite for Infrastructure mode */
- gtk_widget_hide (widget_band_label);
- gtk_widget_hide (GTK_WIDGET (priv->band));
- gtk_widget_hide (widget_chan_label);
- gtk_widget_hide (GTK_WIDGET (priv->channel));
-
- gtk_widget_show (widget_bssid_label);
- gtk_widget_show (GTK_WIDGET (priv->bssid));
- }
-
- gtk_widget_set_sensitive (widget_band_label, adhoc);
- gtk_widget_set_sensitive (GTK_WIDGET (priv->band), adhoc);
- gtk_widget_set_sensitive (widget_chan_label, adhoc);
- gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), adhoc);
- gtk_widget_set_sensitive (widget_bssid_label, !adhoc);
- gtk_widget_set_sensitive (GTK_WIDGET (priv->bssid), !adhoc);
+ gtk_widget_set_visible (widget_bssid_label, show_bssid);
+ gtk_widget_set_sensitive (widget_bssid_label, show_bssid);
+ gtk_widget_set_visible (GTK_WIDGET (priv->bssid), show_bssid);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->bssid), show_bssid);
ce_page_changed (CE_PAGE (self));
}
@@ -339,8 +329,10 @@ populate_ui (CEPageWifi *self)
/* Default to Infrastructure */
gtk_combo_box_set_active (priv->mode, 0);
- if (mode && !strcmp (mode, "adhoc"))
+ if (!g_strcmp0 (mode, "adhoc"))
gtk_combo_box_set_active (priv->mode, 1);
+ if (!g_strcmp0 (mode, "ap"))
+ gtk_combo_box_set_active (priv->mode, 2);
mode_combo_changed_cb (priv->mode, self);
g_signal_connect (priv->mode, "changed", G_CALLBACK (mode_combo_changed_cb), self);
@@ -498,10 +490,17 @@ ui_to_setting (CEPageWifi *self)
ssid = ce_page_wifi_get_ssid (self);
- if (gtk_combo_box_get_active (priv->mode) == 1)
+ switch (gtk_combo_box_get_active (priv->mode)) {
+ case 1:
mode = "adhoc";
- else
+ break;
+ case 2:
+ mode = "ap";
+ break;
+ default:
mode = "infrastructure";
+ break;
+ }
switch (gtk_combo_box_get_active (priv->band)) {
case 1:
diff --git a/src/wireless-security/wireless-security.c b/src/wireless-security/wireless-security.c
index 12fee1e..9ca7f2d 100644
--- a/src/wireless-security/wireless-security.c
+++ b/src/wireless-security/wireless-security.c
@@ -186,6 +186,7 @@ wireless_security_init (gsize obj_size,
sec->destroy = destroy;
sec->adhoc_compatible = TRUE;
+ sec->hotspot_compatible = TRUE;
return sec;
}
@@ -198,6 +199,14 @@ wireless_security_adhoc_compatible (WirelessSecurity *sec)
return sec->adhoc_compatible;
}
+gboolean
+wireless_security_hotspot_compatible (WirelessSecurity *sec)
+{
+ g_return_val_if_fail (sec != NULL, FALSE);
+
+ return sec->hotspot_compatible;
+}
+
void
wireless_security_set_userpass (WirelessSecurity *sec,
const char *user,
diff --git a/src/wireless-security/wireless-security.h b/src/wireless-security/wireless-security.h
index 93a53a3..b4bef79 100644
--- a/src/wireless-security/wireless-security.h
+++ b/src/wireless-security/wireless-security.h
@@ -54,6 +54,7 @@ struct _WirelessSecurity {
gpointer changed_notify_data;
const char *default_field;
gboolean adhoc_compatible;
+ gboolean hotspot_compatible;
char *username, *password;
gboolean always_ask, show_password;
@@ -87,6 +88,8 @@ void wireless_security_update_secrets (WirelessSecurity *sec,
gboolean wireless_security_adhoc_compatible (WirelessSecurity *sec);
+gboolean wireless_security_hotspot_compatible (WirelessSecurity *sec);
+
void wireless_security_set_userpass (WirelessSecurity *sec,
const char *user,
const char *password,
diff --git a/src/wireless-security/ws-dynamic-wep.c b/src/wireless-security/ws-dynamic-wep.c
index a450edb..afa4555 100644
--- a/src/wireless-security/ws-dynamic-wep.c
+++ b/src/wireless-security/ws-dynamic-wep.c
@@ -115,6 +115,7 @@ ws_dynamic_wep_new (NMConnection *connection,
return NULL;
parent->adhoc_compatible = FALSE;
+ parent->hotspot_compatible = FALSE;
widget = ws_802_1x_auth_combo_init (parent,
"dynamic_wep_auth_combo",
diff --git a/src/wireless-security/ws-leap.c b/src/wireless-security/ws-leap.c
index 5a13a6f..e0ef43e 100644
--- a/src/wireless-security/ws-leap.c
+++ b/src/wireless-security/ws-leap.c
@@ -162,6 +162,7 @@ ws_leap_new (NMConnection *connection, gboolean secrets_only)
}
parent->adhoc_compatible = FALSE;
+ parent->hotspot_compatible = FALSE;
sec = (WirelessSecurityLEAP *) parent;
sec->editing_connection = secrets_only ? FALSE : TRUE;
sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD;
diff --git a/src/wireless-security/ws-wpa-eap.c b/src/wireless-security/ws-wpa-eap.c
index 3f88808..b53b017 100644
--- a/src/wireless-security/ws-wpa-eap.c
+++ b/src/wireless-security/ws-wpa-eap.c
@@ -116,6 +116,7 @@ ws_wpa_eap_new (NMConnection *connection,
return NULL;
parent->adhoc_compatible = FALSE;
+ parent->hotspot_compatible = FALSE;
widget = ws_802_1x_auth_combo_init (parent,
"wpa_eap_auth_combo",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]