2 * Network Configuration - EAPoL Service Module
4 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <gio/gunixfdlist.h>
29 #include "wifi-power.h"
30 #include "netsupplicant.h"
32 #define EAPOL_STORAGEDIR "/var/lib/connman/"
33 #define ETH_IFNAME "eth0"
35 #define CONNMAN_CONFIG_FIELD_EAP_METHOD "EAP"
36 #define CONNMAN_CONFIG_FIELD_IDENTITY "Identity"
37 #define CONNMAN_CONFIG_FIELD_PASSPHRASE "Passphrase"
38 #define CONNMAN_CONFIG_FIELD_ANONYMOUS_IDENTITY "AnonymousIdentity"
39 #define CONNMAN_CONFIG_FIELD_CA_CERT_FILE "CACertFile"
40 #define CONNMAN_CONFIG_FIELD_CLIENT_CERT_FILE "ClientCertFile"
41 #define CONNMAN_CONFIG_FIELD_PVT_KEY_FILE "PrivateKeyFile"
42 #define CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE "PrivateKeyPassphrase"
43 #define CONNMAN_CONFIG_FIELD_PAC_FILE "PacFile"
44 #define CONNMAN_CONFIG_FIELD_PHASE2 "Phase2"
45 #define CONNMAN_CONFIG_FIELD_PHASE1 "Phase1"
47 static Ethernet *ethernet_object = NULL;
48 static gboolean g_eap_enabled = FALSE;
49 netconfig_eapol_s eapol;
51 Ethernet *get_ethernet_object(void)
53 return ethernet_object;
56 static gboolean __netconfig_set_eap_config_file(GVariant *fields)
60 gchar *filename = NULL;
64 /* initialize eap settings */
65 memset(&eapol, 0, sizeof(netconfig_eapol_s));
68 /* create eapol conf file */
69 filename = g_strdup_printf("%s/%s-eapol.conf", EAPOL_STORAGEDIR, ETH_IFNAME);
71 ERR("Failed to allocate memory.");
76 fp = fopen(filename, "w");
78 ERR("Failed to open %s", filename);
83 /* update eapol conf file */
84 fprintf (fp, "network={\n");
85 fprintf (fp, "key_mgmt=WPA-EAP\n");
87 g_variant_get(fields, "a{ss}", &iter);
88 while (g_variant_iter_loop(iter, "{ss}", &field, &value)) {
89 if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_EAP_METHOD) == 0) {
91 fprintf (fp, "eap=%s\n", value);
92 eapol.eap_type = g_strdup(value);
94 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_IDENTITY) == 0) {
96 fprintf (fp, "identity=\"%s\"\n", value);
97 eapol.identity = g_strdup(value);
99 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_ANONYMOUS_IDENTITY) == 0) {
101 fprintf (fp, "anonymous_identity=\"%s\"\n", value);
102 eapol.anonymous_identity = g_strdup(value);
104 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PASSPHRASE) == 0) {
106 fprintf (fp, "password=\"%s\"\n", value);
107 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_CA_CERT_FILE) == 0) {
109 fprintf (fp, "ca_cert=\"%s\"\n", value);
110 eapol.ca_cert_file = g_strdup(value);
112 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_CLIENT_CERT_FILE) == 0) {
114 fprintf (fp, "client_cert=\"%s\"\n", value);
115 eapol.client_cert_file = g_strdup(value);
117 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PVT_KEY_FILE) == 0) {
119 fprintf (fp, "private_key=\"%s\"\n", value);
120 eapol.private_key_file = g_strdup(value);
122 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE) == 0) {
124 fprintf (fp, "private_key_passwd=\"%s\"\n", value);
125 eapol.private_key_password = g_strdup(value);
127 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PAC_FILE) == 0) {
129 fprintf (fp, "pac_file=\"%s\"\n", value);
130 eapol.pac_file = g_strdup(value);
132 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PHASE2) == 0) {
135 sprintf(str, "auth=%s", value);
136 fprintf (fp, "phase2=\"%s\"\n", str);
138 eapol.phase2 = g_strdup(value);
140 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PHASE1) == 0) {
144 if ((g_strcmp0(value, "VERSION_AUTO") == 0) ||
145 (g_strcmp0(value, "VERSION_0") == 0))
150 sprintf(str, "peapver=%d", peap_version);
151 fprintf (fp, "phase1=\"%s\"\n", str);
152 eapol.phase1 = peap_version;
157 fprintf (fp, "}"); /* closing of conf file */
166 static void __netconfig_cleanup_eapol()
168 g_free(eapol.eap_type);
169 g_free(eapol.identity);
170 g_free(eapol.anonymous_identity);
171 g_free(eapol.ca_cert_file);
172 g_free(eapol.client_cert_file);
173 g_free(eapol.private_key_file);
174 g_free(eapol.private_key_password);
175 g_free(eapol.pac_file);
176 g_free(eapol.phase2);
180 static int __netconfig_set_eapol_property(const gchar *service, gboolean use_eapol)
182 GVariant *params = NULL;
183 GVariant *message = NULL;
184 GVariantBuilder *builder;
186 const char *prop_eap_on_ethernet = "EapOverEthernet";
188 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
190 g_variant_builder_add(builder, "{sv}", "UseEapol", g_variant_new_boolean(use_eapol));
194 g_variant_builder_add(builder, "{sv}", "EAP",
195 g_variant_new_string(eapol.eap_type));
197 g_variant_builder_add(builder, "{sv}", "Identity",
198 g_variant_new_string(eapol.identity));
199 if (eapol.anonymous_identity)
200 g_variant_builder_add(builder, "{sv}", "AnonymousIdentity",
201 g_variant_new_string(eapol.anonymous_identity));
202 if (eapol.ca_cert_file)
203 g_variant_builder_add(builder, "{sv}", "CACertFile",
204 g_variant_new_string(eapol.ca_cert_file));
205 if (eapol.client_cert_file)
206 g_variant_builder_add(builder, "{sv}", "ClientCertFile",
207 g_variant_new_string(eapol.client_cert_file));
208 if (eapol.private_key_file)
209 g_variant_builder_add(builder, "{sv}", "PrivateKeyFile",
210 g_variant_new_string(eapol.private_key_file));
211 if (eapol.private_key_password)
212 g_variant_builder_add(builder, "{sv}", "PrivateKeyPassphrase",
213 g_variant_new_string(eapol.private_key_password));
215 g_variant_builder_add(builder, "{sv}", "Phase2",
216 g_variant_new_string(eapol.phase2));
218 if (eapol.phase1 >= 0)
219 g_variant_builder_add(builder, "{sv}", "Phase1",
220 g_variant_new_int32(eapol.phase1));
223 g_variant_builder_add(builder, "{sv}", "PacFile",
224 g_variant_new_string(eapol.pac_file));
226 __netconfig_cleanup_eapol();
229 params = g_variant_new("(sv)", prop_eap_on_ethernet, g_variant_builder_end(builder));
230 g_variant_builder_unref(builder);
232 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, service,
233 CONNMAN_SERVICE_INTERFACE, "SetProperty", params);
234 if (message == NULL) {
235 g_variant_unref(message);
239 g_variant_unref(message);
244 /*********************
245 * Handler Functions *
246 ********************/
248 gboolean handle_enable_eap(Ethernet *object, GDBusMethodInvocation *invocation,
249 const gchar *service, gboolean enable)
251 g_return_val_if_fail(object != NULL, TRUE);
253 DBG("%s EAPoL", enable ? "enable" : "disable");
255 if (netconfig_is_ethernet_profile(service) != TRUE) {
256 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_WRONG_PROFILE, "InvalidService");
260 /* TODO: Execute WPA Supplicant if not running */
261 __execute_supplicant(enable);
263 /* TODO: Make below variable interface specific and set
264 connMan profile associated with this interface as EAP enabled.
266 g_eap_enabled = enable;
268 if (enable == false) {
269 int err = __netconfig_set_eapol_property(service, false);
271 ERR("Failed to set eapol property.");
272 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_INTERNAL, "InternalError");
277 ethernet_complete_enable_eap(object, invocation);
281 gboolean handle_set_eap_config(Ethernet *object, GDBusMethodInvocation *invocation,
282 const gchar *service, GVariant *fields)
284 g_return_val_if_fail(object != NULL, TRUE);
286 DBG("handle_set_eap_config for service [%s]", service);
288 if (netconfig_is_ethernet_profile(service) != TRUE) {
289 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_WRONG_PROFILE, "InvalidService");
293 if (g_eap_enabled == FALSE) {
294 netconfig_error_dbus_method_return(invocation,
295 NETCONFIG_ERROR_INTERNAL,
300 /** Create conf file */
301 int err = __netconfig_set_eap_config_file(fields);
303 ERR("Failed to save eapol conf file.");
304 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_INTERNAL, "InternalError");
308 err = __netconfig_set_eapol_property(service, true);
310 ERR("Failed to set eapol property.");
311 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_INTERNAL, "InternalError");
315 ethernet_complete_set_eap_config(object, invocation);
319 /*****************************
320 * Initializations Functions *
321 ****************************/
322 void ethernet_object_create_and_init(void)
324 DBG("Create ethernet object.");
325 GDBusInterfaceSkeleton *interface_ethernet = NULL;
326 GDBusConnection *connection = NULL;
327 GDBusObjectManagerServer *server = netdbus_get_ethernet_manager();
331 connection = netdbus_get_connection();
332 g_dbus_object_manager_server_set_connection(server, connection);
335 ethernet_object = ethernet_skeleton_new();
336 interface_ethernet = G_DBUS_INTERFACE_SKELETON(ethernet_object);
338 /* EAP over Ethernet Service */
339 g_signal_connect(ethernet_object, "handle-enable-eap",
340 G_CALLBACK(handle_enable_eap), NULL);
341 g_signal_connect(ethernet_object, "handle-set-eap-config",
342 G_CALLBACK(handle_set_eap_config), NULL);
344 if (!g_dbus_interface_skeleton_export(interface_ethernet, connection,
345 NETCONFIG_ETHERNET_PATH, NULL)) {
346 ERR("Export NETCONFIG_ETHERNET_PATH for ethernet failed");
352 void ethernet_object_deinit(void)
354 DBG("Deinit ethernet object.");
356 g_object_unref(ethernet_object);