summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gsupplicant/gsupplicant.h14
-rw-r--r--gsupplicant/supplicant.c121
-rw-r--r--plugins/wifi.c47
3 files changed, 167 insertions, 15 deletions
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index 8461c494..5d8c6179 100644
--- a/gsupplicant/gsupplicant.h
+++ b/gsupplicant/gsupplicant.h
@@ -102,14 +102,14 @@ struct _GSupplicantSSID {
unsigned int ssid_len;
GSupplicantMode mode;
GSupplicantSecurity security;
- unsigned int eap_method;
+ const char *eap;
const char *passphrase;
- char *identity;
- char *ca_cert_path;
- char *client_cert_path;
- char *private_key_path;
- char *private_key_passphrase;
- char *phase2_auth;
+ const char *identity;
+ const char *ca_cert_path;
+ const char *client_cert_path;
+ const char *private_key_path;
+ const char *private_key_passphrase;
+ const char *phase2_auth;
};
typedef struct _GSupplicantSSID GSupplicantSSID;
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index c1679b52..6e4b5fb4 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -2063,6 +2063,126 @@ static void add_network_security_psk(DBusMessageIter *dict,
&ssid->passphrase);
}
+static void add_network_security_tls(DBusMessageIter *dict,
+ GSupplicantSSID *ssid)
+{
+ /*
+ * For TLS, we at least need:
+ * The client certificate
+ * The client private key file
+ * The client private key file password
+ *
+ * The Authority certificate is optional.
+ */
+ if (ssid->client_cert_path == NULL)
+ return;
+
+ if (ssid->private_key_path == NULL)
+ return;
+
+ if (ssid->private_key_passphrase == NULL)
+ return;
+
+ if (ssid->ca_cert_path)
+ supplicant_dbus_dict_append_basic(dict, "ca_cert",
+ DBUS_TYPE_STRING, &ssid->ca_cert_path);
+
+ supplicant_dbus_dict_append_basic(dict, "private_key",
+ DBUS_TYPE_STRING,
+ &ssid->private_key_path);
+ supplicant_dbus_dict_append_basic(dict, "private_key_passwd",
+ DBUS_TYPE_STRING,
+ &ssid->private_key_passphrase);
+ supplicant_dbus_dict_append_basic(dict, "client_cert",
+ DBUS_TYPE_STRING,
+ &ssid->client_cert_path);
+}
+
+static void add_network_security_peap(DBusMessageIter *dict,
+ GSupplicantSSID *ssid)
+{
+ char *phase2_auth;
+
+ /*
+ * For PEAP/TTLS, we at least need
+ * The authority certificate
+ * The 2nd phase authentication method
+ * The 2nd phase passphrase
+ *
+ * The Client certificate is optional although strongly required
+ * When setting it, we need in addition
+ * The Client private key file
+ * The Client private key file password
+ */
+ if (ssid->passphrase == NULL)
+ return;
+
+ if (ssid->ca_cert_path == NULL)
+ return;
+
+ if (ssid->phase2_auth == NULL)
+ return;
+
+ if (ssid->client_cert_path) {
+ if (ssid->private_key_path == NULL)
+ return;
+
+ if (ssid->private_key_passphrase == NULL)
+ return;
+
+ supplicant_dbus_dict_append_basic(dict, "client_cert",
+ DBUS_TYPE_STRING,
+ &ssid->client_cert_path);
+
+ supplicant_dbus_dict_append_basic(dict, "private_key",
+ DBUS_TYPE_STRING,
+ &ssid->private_key_path);
+
+ supplicant_dbus_dict_append_basic(dict, "private_key_passwd",
+ DBUS_TYPE_STRING,
+ &ssid->private_key_passphrase);
+
+ }
+
+ phase2_auth = g_strdup_printf("\"auth=%s\"", ssid->phase2_auth);
+
+ supplicant_dbus_dict_append_basic(dict, "password",
+ DBUS_TYPE_STRING,
+ &ssid->passphrase);
+
+ supplicant_dbus_dict_append_basic(dict, "ca_cert",
+ DBUS_TYPE_STRING,
+ &ssid->ca_cert_path);
+
+ supplicant_dbus_dict_append_basic(dict, "phase2",
+ DBUS_TYPE_STRING,
+ &ssid->phase2_auth);
+
+ g_free(phase2_auth);
+}
+
+static void add_network_security_eap(DBusMessageIter *dict,
+ GSupplicantSSID *ssid)
+{
+ if (ssid->eap == NULL || ssid->identity == NULL)
+ return;
+
+ if (g_strcmp0(ssid->eap, "tls") == 0) {
+ add_network_security_tls(dict, ssid);
+ } else if (g_strcmp0(ssid->eap, "peap") == 0 ||
+ g_strcmp0(ssid->eap, "ttls") == 0) {
+ add_network_security_peap(dict, ssid);
+ } else
+ return;
+
+ supplicant_dbus_dict_append_basic(dict, "eap",
+ DBUS_TYPE_STRING,
+ &ssid->eap);
+ supplicant_dbus_dict_append_basic(dict, "identity",
+ DBUS_TYPE_STRING,
+ &ssid->identity);
+}
+
static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
{
char *key_mgmt;
@@ -2080,6 +2200,7 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
break;
case G_SUPPLICANT_SECURITY_IEEE8021X:
key_mgmt = "WPA-EAP";
+ add_network_security_eap(dict, ssid);
break;
}
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 4cde53ec..f8bd87e4 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -538,13 +538,50 @@ static GSupplicantSecurity network_security(const char *security)
return G_SUPPLICANT_SECURITY_UNKNOWN;
}
+static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
+{
+ const char *security;
+
+ memset(ssid, 0, sizeof(*ssid));
+ ssid->ssid = connman_network_get_blob(network, "WiFi.SSID",
+ &ssid->ssid_len);
+ security = connman_network_get_string(network, "WiFi.Security");
+ ssid->security = network_security(security);
+ ssid->passphrase = connman_network_get_string(network,
+ "WiFi.Passphrase");
+ ssid->eap = connman_network_get_string(network, "WiFi.EAP");
+
+ /*
+ * If our private key password is unset,
+ * we use the supplied passphrase. That is needed
+ * for PEAP where 2 passphrases (identity and client
+ * cert may have to be provided.
+ */
+ if (connman_network_get_string(network,
+ "WiFi.PrivateKeyPassphrase") == NULL)
+ connman_network_set_string(network,
+ "WiFi.PrivateKeyPassphrase",
+ ssid->passphrase);
+ /* We must have an identity for both PEAP and TLS */
+ ssid->identity = connman_network_get_string(network, "WiFi.Identity");
+ ssid->ca_cert_path = connman_network_get_string(network,
+ "WiFi.CACertFile");
+ ssid->client_cert_path = connman_network_get_string(network,
+ "WiFi.ClientCertFile");
+ ssid->private_key_path = connman_network_get_string(network,
+ "WiFi.PrivateKeyFile");
+ ssid->private_key_passphrase = connman_network_get_string(network,
+ "WiFi.PrivateKeyPassphrase");
+ ssid->phase2_auth = connman_network_get_string(network, "WiFi.Phase2");
+
+}
+
static int network_connect(struct connman_network *network)
{
struct connman_device *device = connman_network_get_device(network);
struct wifi_data *wifi;
GSupplicantInterface *interface;
GSupplicantSSID ssid;
- const char *security;
DBG("network %p", network);
@@ -557,13 +594,7 @@ static int network_connect(struct connman_network *network)
interface = wifi->interface;
- memset(&ssid, 0, sizeof(ssid));
- ssid.ssid = connman_network_get_blob(network, "WiFi.SSID",
- &ssid.ssid_len);
- security = connman_network_get_string(network, "WiFi.Security");
- ssid.security = network_security(security);
- ssid.passphrase = connman_network_get_string(network,
- "WiFi.Passphrase");
+ ssid_init(&ssid, network);
wifi->network = connman_network_ref(network);