WPA-EAP support for GSupplicant
authorSamuel Ortiz <sameo@linux.intel.com>
Thu, 16 Sep 2010 14:43:27 +0000 (16:43 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Mon, 20 Sep 2010 13:14:17 +0000 (15:14 +0200)
gsupplicant/gsupplicant.h
gsupplicant/supplicant.c
plugins/wifi.c

index 8461c49..5d8c617 100644 (file)
@@ -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;
index c1679b5..6e4b5fb 100644 (file)
@@ -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;
        }
 
index 4cde53e..f8bd87e 100644 (file)
@@ -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);