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 "/opt/usr/data/network/"
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_supported = 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) {
90 DBG("field: %s, value: %s", field, value);
93 fprintf (fp, "eap=%s\n", value);
94 eapol.eap_type = g_strdup(value);
96 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_IDENTITY) == 0) {
97 DBG("field: %s, value: %s", field, value);
100 fprintf (fp, "identity=\"%s\"\n", value);
101 eapol.identity = g_strdup(value);
103 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_ANONYMOUS_IDENTITY) == 0) {
104 DBG("field: %s, value: %s", field, value);
107 fprintf (fp, "anonymous_identity=\"%s\"\n", value);
108 eapol.anonymous_identity = g_strdup(value);
110 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PASSPHRASE) == 0) {
111 DBG("field: %s, value: %s", field, value);
114 fprintf (fp, "password=\"%s\"\n", value);
115 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_CA_CERT_FILE) == 0) {
116 DBG("field: %s, value: %s", field, value);
119 fprintf (fp, "ca_cert=\"%s\"\n", value);
120 eapol.ca_cert_file = g_strdup(value);
122 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_CLIENT_CERT_FILE) == 0) {
123 DBG("field: %s, value: %s", field, value);
126 fprintf (fp, "client_cert=\"%s\"\n", value);
127 eapol.client_cert_file = g_strdup(value);
129 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PVT_KEY_FILE) == 0) {
130 DBG("field: %s, value: %s", field, value);
133 fprintf (fp, "private_key=\"%s\"\n", value);
134 eapol.private_key_file = g_strdup(value);
136 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE) == 0) {
137 DBG("field: %s, value: %s", field, value);
140 fprintf (fp, "private_key_passwd=\"%s\"\n", value);
141 eapol.private_key_password = g_strdup(value);
143 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PAC_FILE) == 0) {
144 DBG("field: %s, value: %s", field, value);
147 fprintf (fp, "pac_file=\"%s\"\n", value);
148 eapol.pac_file = g_strdup(value);
150 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PHASE2) == 0) {
151 DBG("field: %s, value: %s", field, value);
155 sprintf(str, "auth=%s", value);
156 fprintf (fp, "phase2=\"%s\"\n", str);
158 eapol.phase2 = g_strdup(value);
160 } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PHASE1) == 0) {
161 DBG("field: %s, value: %s", field, value);
166 if ((g_strcmp0(value, "VERSION_AUTO") == 0) ||
167 (g_strcmp0(value, "VERSION_0") == 0))
172 sprintf(str, "peapver=%d", peap_version);
173 fprintf (fp, "phase1=\"%s\"\n", str);
174 eapol.phase1 = peap_version;
179 fprintf (fp, "}"); /* closing of conf file */
188 static void __netconfig_cleanup_eapol()
190 g_free(eapol.eap_type);
191 g_free(eapol.identity);
192 g_free(eapol.anonymous_identity);
193 g_free(eapol.ca_cert_file);
194 g_free(eapol.client_cert_file);
195 g_free(eapol.private_key_file);
196 g_free(eapol.private_key_password);
197 g_free(eapol.pac_file);
198 g_free(eapol.phase2);
202 static int __netconfig_set_eapol_property(const gchar *service, gboolean use_eapol)
204 GVariant *params = NULL;
205 GVariant *message = NULL;
206 GVariantBuilder *builder;
208 const char *prop_eap_on_ethernet = "EapOverEthernet";
210 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
212 g_variant_builder_add(builder, "{sv}", "UseEapol", g_variant_new_boolean(use_eapol));
216 g_variant_builder_add(builder, "{sv}", "EAP",
217 g_variant_new_string(eapol.eap_type));
219 g_variant_builder_add(builder, "{sv}", "Identity",
220 g_variant_new_string(eapol.identity));
221 if (eapol.anonymous_identity)
222 g_variant_builder_add(builder, "{sv}", "AnonymousIdentity",
223 g_variant_new_string(eapol.anonymous_identity));
224 if (eapol.ca_cert_file)
225 g_variant_builder_add(builder, "{sv}", "CACertFile",
226 g_variant_new_string(eapol.ca_cert_file));
227 if (eapol.client_cert_file)
228 g_variant_builder_add(builder, "{sv}", "ClientCertFile",
229 g_variant_new_string(eapol.client_cert_file));
230 if (eapol.private_key_file)
231 g_variant_builder_add(builder, "{sv}", "PrivateKeyFile",
232 g_variant_new_string(eapol.private_key_file));
233 if (eapol.private_key_password)
234 g_variant_builder_add(builder, "{sv}", "PrivateKeyPassphrase",
235 g_variant_new_string(eapol.private_key_password));
237 g_variant_builder_add(builder, "{sv}", "Phase2",
238 g_variant_new_string(eapol.phase2));
240 if (eapol.phase1 >= 0)
241 g_variant_builder_add(builder, "{sv}", "Phase1",
242 g_variant_new_int32(eapol.phase1));
245 g_variant_builder_add(builder, "{sv}", "PacFile",
246 g_variant_new_string(eapol.pac_file));
248 __netconfig_cleanup_eapol();
251 params = g_variant_new("(sv)", prop_eap_on_ethernet, g_variant_builder_end(builder));
252 g_variant_builder_unref(builder);
254 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, service,
255 CONNMAN_SERVICE_INTERFACE, "SetProperty", params);
256 if (message == NULL) {
257 g_variant_unref(message);
261 g_variant_unref(message);
266 /*********************
267 * Handler Functions *
268 ********************/
270 gboolean handle_enable_eap(Ethernet *object, GDBusMethodInvocation *invocation,
271 const gchar *service, gboolean enable)
273 g_return_val_if_fail(object != NULL, TRUE);
275 DBG("%s EAPoL", enable ? "enable" : "disable");
277 if (netconfig_is_ethernet_profile(service) != TRUE) {
278 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_WRONG_PROFILE, "InvalidService");
282 /* TODO: Execute WPA Supplicant if not running */
283 __execute_supplicant(enable);
285 /* TODO: Make below variable interface specific and set
286 connMan profile associated with this interface as EAP enabled.
288 g_eap_supported = enable;
290 if (enable == false) {
291 int err = __netconfig_set_eapol_property(service, false);
293 ERR("Failed to set eapol property.");
294 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_INTERNAL, "InternalError");
299 ethernet_complete_enable_eap(object, invocation);
303 gboolean handle_is_eap_supported(Ethernet *object, GDBusMethodInvocation *invocation)
305 g_return_val_if_fail(object != NULL, TRUE);
307 DBG("handle_is_eap_supported");
308 gboolean value = FALSE;
310 value = g_eap_supported;
312 ethernet_complete_is_eap_supported(object, invocation, value);
316 gboolean handle_set_eap_config(Ethernet *object, GDBusMethodInvocation *invocation,
317 const gchar *service, GVariant *fields)
319 g_return_val_if_fail(object != NULL, TRUE);
321 DBG("handle_set_eap_config for service [%s]", service);
323 if (netconfig_is_ethernet_profile(service) != TRUE) {
324 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_WRONG_PROFILE, "InvalidService");
328 if (g_eap_supported == FALSE) {
329 netconfig_error_dbus_method_return(invocation,
330 NETCONFIG_ERROR_INTERNAL,
335 /** Create conf file */
336 int err = __netconfig_set_eap_config_file(fields);
338 ERR("Failed to save eapol conf file.");
339 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_INTERNAL, "InternalError");
343 err = __netconfig_set_eapol_property(service, true);
345 ERR("Failed to set eapol property.");
346 netconfig_error_dbus_method_return(invocation, NETCONFIG_ERROR_INTERNAL, "InternalError");
350 ethernet_complete_set_eap_config(object, invocation);
354 /*****************************
355 * Initializations Functions *
356 ****************************/
357 void ethernet_object_create_and_init(void)
359 DBG("Create ethernet object.");
360 GDBusInterfaceSkeleton *interface_ethernet = NULL;
361 GDBusConnection *connection = NULL;
362 GDBusObjectManagerServer *server = netdbus_get_ethernet_manager();
366 connection = netdbus_get_connection();
367 g_dbus_object_manager_server_set_connection(server, connection);
370 ethernet_object = ethernet_skeleton_new();
371 interface_ethernet = G_DBUS_INTERFACE_SKELETON(ethernet_object);
373 /* EAP over Ethernet Service */
374 g_signal_connect(ethernet_object, "handle-enable-eap",
375 G_CALLBACK(handle_enable_eap), NULL);
376 g_signal_connect(ethernet_object, "handle-is-eap-supported",
377 G_CALLBACK(handle_is_eap_supported), NULL);
378 g_signal_connect(ethernet_object, "handle-set-eap-config",
379 G_CALLBACK(handle_set_eap_config), NULL);
381 if (!g_dbus_interface_skeleton_export(interface_ethernet, connection,
382 NETCONFIG_ETHERNET_PATH, NULL)) {
383 ERR("Export NETCONFIG_ETHERNET_PATH for ethernet failed");
389 void ethernet_object_deinit(void)
391 DBG("Deinit ethernet object.");
393 g_object_unref(ethernet_object);