X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fwifi-eap-config.c;h=5b406423157543d2454ab794742fc088067c3ecf;hb=c2a32db4948b649d0c3ed1aed27d5501bd732f66;hp=1a47507dc4ad8521ec2d7d29f5c365b5751fa6c8;hpb=fb157ab16503ac464465092dbddf9c2063878f37;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git diff --git a/src/wifi-eap-config.c b/src/wifi-eap-config.c old mode 100644 new mode 100755 index 1a47507..5b40642 --- a/src/wifi-eap-config.c +++ b/src/wifi-eap-config.c @@ -1,7 +1,7 @@ /* * Network Configuration Module * - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,200 +17,534 @@ * */ +#include #include #include +#include -#include "wifi-eap-config.h" #include "log.h" -#include "wifi.h" - -static char *__get_ssid(const char *name) +#include "util.h" +#include "netdbus.h" +#include "wifi-agent.h" +#include "wifi-state.h" +#include "wifi-config.h" +#include "wifi-eap-config.h" +#include "neterror.h" + +#define CONNMAN_CONFIG_FIELD_TYPE "Type" +#define CONNMAN_CONFIG_FIELD_NAME "Name" +#define CONNMAN_CONFIG_FIELD_SSID "SSID" +#define CONNMAN_CONFIG_FIELD_EAP_METHOD "EAP" +#define CONNMAN_CONFIG_FIELD_IDENTITY "Identity" +#define CONNMAN_CONFIG_FIELD_PASSPHRASE "Passphrase" +#define CONNMAN_CONFIG_FIELD_PHASE2 "Phase2" +#define CONNMAN_CONFIG_FIELD_CA_CERT_FILE "CACertFile" +#define CONNMAN_CONFIG_FIELD_CLIENT_CERT_FILE "ClientCertFile" +#define CONNMAN_CONFIG_FIELD_PVT_KEY_FILE "PrivateKeyFile" +#define CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE "PrivateKeyPassphrase" +#define CONNMAN_CONFIG_FIELD_KEYMGMT_TYPE "KeymgmtType" + +static char *__get_encoded_ssid(const char *name) { - char *buf = NULL; - char buf_tmp[32] = {0,}; - int i = 0; - int len = 0; + char *str = NULL; + char *pstr = NULL; + int i = 0, len = 0; - if (NULL == name) + if (name == NULL) return NULL; len = strlen(name); - buf = g_try_malloc0(len * 2 + 1); - if (buf == NULL) + str = g_try_malloc0(len * 2 + 1); + if (str == NULL) return NULL; + pstr = str; for (i = 0; i < len; i++) { - snprintf(buf_tmp, 3, "%02x", name[i]); - strcat(buf, buf_tmp); + g_snprintf(pstr, 3, "%02x", name[i]); + pstr += 2; } - DBG("SSID - [%s]\n", buf); - - return buf; + return str; } -static gboolean __config_save(GKeyFile *keyfile, char *file_name) +static int __config_save(const char *ssid, GKeyFile *keyfile) { gchar *data = NULL; + gchar *config_file = NULL; gsize length = 0; FILE *file = NULL; - int ret = TRUE; + int err = 0; + + config_file = g_strdup_printf("%s/%s.config", CONNMAN_STORAGEDIR, ssid); + if (config_file == NULL) { + err = -ENOMEM; + goto out; + } data = g_key_file_to_data(keyfile, &length, NULL); - DBG("Data lenght-[%d]", length); - file = fopen(file_name, "w"); - if (NULL == file) { - DBG("fopen() fails!"); - ret = FALSE; - } else { - fputs(data, file); - fclose(file); - DBG("Wrote data successfully to [%s] file!", file_name); + file = fopen(config_file, "w"); + if (file == NULL) { + ERR("Failed to open %s", config_file); + + err = -EIO; + goto out; } + /* Do POSIX file operation to create and remove config files, + * Do not use g_file_set_contents, it breaks inotify operations */ + if (data && fputs(data, file) < 0) { + ERR("Failed to write %s", config_file); + + err = -EIO; + goto out; + } + +out: + if (file != NULL) + fclose(file); + g_free(data); + g_free(config_file); - return ret; + return err; } -static gboolean __config_delete(const char *ssid) +static int __config_delete(const char *ssid) { + int err = 0; + gchar *group_name = NULL; gchar *config_file = NULL; - gboolean ret = FALSE; + gchar *dirname = NULL; + gchar *cert_path = NULL; + GKeyFile *keyfile = NULL; + GError *error = NULL; - config_file = g_strdup_printf("%s/%s.config", CONNMAN_STORAGEDIR, - ssid); - if(config_file == NULL) - return FALSE; + config_file = g_strdup_printf("%s/%s.config", CONNMAN_STORAGEDIR, ssid); + if (config_file == NULL) + return -ENOMEM; + + keyfile = g_key_file_new(); - if (g_file_test(config_file, G_FILE_TEST_EXISTS) == FALSE) { - ret = TRUE; - } else if (g_file_test(config_file, G_FILE_TEST_IS_REGULAR) == TRUE) { - unlink(config_file); - ret = TRUE; + if (g_key_file_load_from_file(keyfile, config_file, 0, &error) != TRUE) { + ERR("Unable to load %s[%s]", config_file, error->message); + g_clear_error(&error); + + err = -EIO; + goto out; + } + + group_name = g_strdup_printf("service_%s", ssid); + + cert_path = g_key_file_get_string(keyfile, group_name, + CONNMAN_CONFIG_FIELD_CA_CERT_FILE, NULL); + DBG("Temporal %s", cert_path); + if (cert_path != NULL && remove(cert_path) != 0) + ERR("Failed to remove %s", cert_path); + g_free(cert_path); + + cert_path = g_key_file_get_string(keyfile, group_name, + CONNMAN_CONFIG_FIELD_CLIENT_CERT_FILE, NULL); + DBG("Temporal %s", cert_path); + if (cert_path != NULL && remove(cert_path) != 0) + ERR("Failed to remove %s", cert_path); + g_free(cert_path); + + cert_path = g_key_file_get_string(keyfile, group_name, + CONNMAN_CONFIG_FIELD_PVT_KEY_FILE, NULL); + DBG("Temporal %s", cert_path); + if (cert_path != NULL && remove(cert_path) != 0) + ERR("Failed to remove %s", cert_path); + g_free(cert_path); + + cert_path = g_key_file_get_string(keyfile, group_name, + CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE, NULL); + DBG("Temporal %s", cert_path); + if (cert_path != NULL && remove(cert_path) != 0) + ERR("Failed to remove %s", cert_path); + g_free(cert_path); + + dirname = g_strdup_printf("%s/%s", WIFI_CERT_STORAGEDIR, ssid); + if (dirname != NULL) { + if (g_file_test(dirname, G_FILE_TEST_EXISTS) == TRUE) + if (g_file_test(dirname, G_FILE_TEST_IS_DIR) == TRUE) + rmdir(dirname); + + g_free(dirname); } + if (remove(config_file) != 0) { + err = -EIO; + goto out; + } + +out: + g_key_file_free(keyfile); g_free(config_file); + g_free(group_name); - return ret; + return err; } -gboolean netconfig_iface_wifi_create_config(NetconfigWifi *wifi, - GHashTable *fields, GError **error) +static gboolean __netconfig_copy_config(const char *src, const char *dst) { - DBG("netconfig_iface_wifi_create_config"); - g_return_val_if_fail(wifi != NULL, FALSE); + gchar *buf = NULL; + gsize length = 0; + GError *error = NULL; + gboolean result; + + result = g_file_get_contents(src, &buf, &length, &error); + if (result != TRUE) { + ERR("Failed to read [%s]", error->message); + g_error_free(error); + + return result; + } + + result = g_file_set_contents(dst, buf, length, &error); + if (result != TRUE) { + ERR("Failed to write [%s]", error->message); + g_error_free(error); + } + + INFO("Successfully installed[%zd]", length); + g_free(buf); - gboolean ret = TRUE; + if (remove(src) != 0) + WARN("Failed to remove %s", src); + + return result; +} + +static gboolean __netconfig_create_config(GVariant *fields) +{ GKeyFile *keyfile = NULL; - GHashTableIter iter; - gpointer field, value; - gchar *file_name = NULL; - gchar *ssid_hex = NULL; - gchar *grp_name = NULL; - - g_hash_table_iter_init(&iter, fields); - while (g_hash_table_iter_next(&iter, &field, &value)) { - if (NULL != value) { - if (!strcmp(field, CONNMAN_CONFIG_FIELD_NAME)) { - ssid_hex = __get_ssid(value); + GVariantIter *iter; + gchar *encoded_ssid = NULL; + gchar *dirname = NULL; + gchar *group_name = NULL; + gchar *field, *value; + gboolean updated = FALSE; + gchar *cert_file = NULL; + gchar *cert_path = NULL; + int err = 0; + + g_variant_get(fields, "a{ss}", &iter); + while (g_variant_iter_loop(iter, "{ss}", &field, &value)) { + if (value != NULL) { + if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_NAME) == 0) { + encoded_ssid = __get_encoded_ssid(value); + + g_free(value); + g_free(field); break; - } else if (!strcmp(field, CONNMAN_CONFIG_FIELD_SSID)) { - ssid_hex = g_strdup_printf("%s", - (gchar *)value); + } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_SSID) == 0) { + encoded_ssid = g_strdup(value); + + g_free(field); + g_free(value); break; } } } - if (NULL == ssid_hex) { - DBG("Fail! Could not fetch the ssid"); - return FALSE; + if (encoded_ssid == NULL) { + ERR("Failed to fetch SSID"); + goto out; } /* Create unique service group name */ - grp_name = g_strdup_printf("service_%s", ssid_hex); - if(NULL == grp_name) { - DBG("Fail! Could not create the service group name"); - g_free(ssid_hex); - return FALSE; + group_name = g_strdup_printf("service_%s", encoded_ssid); + if (group_name == NULL) { + ERR("Failed to create service group name"); + goto out; } keyfile = g_key_file_new(); - if (NULL == keyfile) { - DBG("g_key_file_new() fails!"); - g_free(grp_name); - g_free(ssid_hex); - return FALSE; + if (keyfile == NULL) { + ERR("Failed to g_key_file_new"); + goto out; } - g_hash_table_iter_init(&iter, fields); - while (g_hash_table_iter_next(&iter, &field, &value)) { - DBG("Field - [%s] Value - [%s]", field, value); + g_variant_iter_free(iter); + + g_variant_get(fields, "a{ss}", &iter); + while (g_variant_iter_loop(iter, "{ss}", &field, &value)) { + if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_SSID) == 0 || + g_strcmp0(field, CONNMAN_CONFIG_FIELD_EAP_METHOD) == 0 || + g_strcmp0(field, CONNMAN_CONFIG_FIELD_PHASE2) || + g_strcmp0(field, CONNMAN_CONFIG_FIELD_KEYMGMT_TYPE) == 0) { + DBG("field: %s, value: %s", field, value); + + if (value != NULL) + g_key_file_set_string(keyfile, group_name, field, value); + } else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_CA_CERT_FILE) == 0 || + g_strcmp0(field, CONNMAN_CONFIG_FIELD_CLIENT_CERT_FILE) == 0 || + g_strcmp0(field, CONNMAN_CONFIG_FIELD_PVT_KEY_FILE) == 0 || + g_strcmp0(field, CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE) == 0) { + if (value != NULL) { + cert_file = strrchr(value, '/'); + if (cert_file == NULL) { + ERR("Failed to get cert file: %s", value); + g_free(field); + g_free(value); + goto out; + } + + cert_file++; + DBG("field: %s, value: %s", field, cert_file); + + dirname = g_strdup_printf("%s/%s", + WIFI_CERT_STORAGEDIR, encoded_ssid); + if (dirname == NULL) { + ERR("Failed to create dirname"); + g_free(field); + g_free(value); + goto out; + } + if (g_file_test(dirname, G_FILE_TEST_IS_DIR) != TRUE) { + if (mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | + S_IXGRP | S_IROTH | S_IXOTH) < 0) { + if (errno != EEXIST) { + g_free(dirname); + g_free(field); + g_free(value); + goto out; + } + } + } + g_free(dirname); + + cert_path = g_strdup_printf("%s/%s/%s", + WIFI_CERT_STORAGEDIR, encoded_ssid, cert_file); + if (cert_path == NULL) { + ERR("Failed to create cert path"); + g_free(field); + g_free(value); + goto out; + } + if (__netconfig_copy_config(value, cert_path) != TRUE) { + ERR("Failed to read cert file %s", value); + g_free(cert_path); + g_free(field); + g_free(value); + goto out; + } + + g_key_file_set_string(keyfile, group_name, field, cert_path); + g_free(cert_path); + } + } else { + DBG("field: %s, value: %s", field, value); - if (NULL != value) - g_key_file_set_string(keyfile, grp_name, field, value); + if (value != NULL) + g_key_file_set_string(keyfile, group_name, field, value); + } } - file_name = g_strdup_printf("%s/%s.config", CONNMAN_STORAGEDIR, - ssid_hex); - if(NULL == file_name) { - DBG("g_strdup_printf() fails. Could not save config!"); + err = __config_save((const char *)encoded_ssid, keyfile); + if (err < 0) + ERR("Failed to create configuration %s[%d]", encoded_ssid, err); + else { + DBG("Successfully created %s", encoded_ssid); + updated = TRUE; + } + +out: + if (keyfile) g_key_file_free(keyfile); - g_free(grp_name); - g_free(ssid_hex); - return FALSE; + + g_variant_iter_free(iter); + + g_free(group_name); + g_free(encoded_ssid); + + return updated; +} + +static gboolean _delete_configuration(const gchar *profile) +{ + gboolean ret = FALSE; + gchar *config_id = NULL; + + ret = wifi_config_get_config_id(profile, &config_id); + if (ret != TRUE) { + ERR("Fail to get config_id from [%s]", profile); + return ret; } + ERR("get config_id [%s] from [%s]", config_id, profile); - ret = __config_save(keyfile, file_name); - if (FALSE == ret) - DBG("Could not save config!"); - else - DBG("Saved config in [%s] successfully", file_name); + ret = wifi_config_remove_configuration(config_id); + if (ret != TRUE) + ERR("Fail to wifi_config_remove_configuration [%s]", config_id); - g_key_file_free(keyfile); - g_free(file_name); - g_free(grp_name); - g_free(ssid_hex); + if (config_id != NULL) + g_free(config_id); return ret; } -gboolean netconfig_iface_wifi_delete_config(NetconfigWifi *wifi, - gchar *profile, GError **error) +static gboolean __netconfig_delete_config(const char *profile) { - DBG("netconfig_iface_wifi_delete_config"); - g_return_val_if_fail(wifi != NULL, FALSE); - - gboolean ret = TRUE; - char *str1 = NULL; - char *str2 = NULL; - char *str3 = NULL; - char ssid[512] = ""; + char *wifi_ident = NULL; + char *essid = NULL; + char *mode = NULL; + char *ssid = NULL; int ssid_len = 0; + int err = 0; - str1 = strstr(profile, "wifi_"); - if (NULL != str1) { - str2 = strchr(str1 + 5, '_'); - if (NULL != str2) { - str3 = strchr(str2 + 1, '_'); - ssid_len = str3 - str2 - 1; - strncpy(ssid, str2 + 1, ssid_len); - DBG("ssid_len - [%d] SSID - [%s]", ssid_len, ssid); - - ret = __config_delete(ssid); - if (TRUE == ret) - DBG("Deleted the config file successfully"); - else - DBG("Deletion of config file failed"); - } else { - DBG("Fetching of SSID fails"); + if (NULL == profile) { + ERR("Invalid profile name"); + return FALSE; + } + + if (_delete_configuration(profile) != TRUE) + ERR("Fail to delete configuration [%s]", profile); + + wifi_ident = strstr(profile, "wifi_"); + if (wifi_ident == NULL) { + ERR("Invalid profile name"); + return FALSE; + } + + essid = strchr(wifi_ident + 5, '_'); + if (essid == NULL) { + ERR("Invalid profile name"); + return FALSE; + } + + essid++; + mode = strchr(essid, '_'); + + ssid_len = mode - essid; + + ssid = g_try_malloc0(ssid_len + 1); + if (ssid == NULL) { + ERR("Memory allocation failed"); + return FALSE; + } + + g_strlcpy(ssid, essid, ssid_len + 1); /* include NULL-terminated */ + err = __config_delete((const char *)ssid); + if (err < 0) { + ERR("Failed to delete configuration %s[%d]", ssid, err); + g_free(ssid); + return FALSE; + } + + DBG("Successfully deleted %s with length %d", ssid, ssid_len); + + g_free(ssid); + return TRUE; +} + +static void __netconfig_eap_state( + wifi_service_state_e state, void *user_data); + +static wifi_state_notifier netconfig_eap_notifier = { + .wifi_state_changed = __netconfig_eap_state, + .user_data = NULL, +}; + +static void __netconfig_eap_state( + wifi_service_state_e state, void *user_data) +{ + const char *wifi_profile = (const char *)user_data; + + if (wifi_profile == NULL) { + wifi_state_notifier_unregister(&netconfig_eap_notifier); + return; + } + + if (state != NETCONFIG_WIFI_CONNECTED && state != NETCONFIG_WIFI_FAILURE) + return; + + if (state == NETCONFIG_WIFI_FAILURE) + __netconfig_delete_config(wifi_profile); + + g_free(netconfig_eap_notifier.user_data); + netconfig_eap_notifier.user_data = NULL; + + wifi_state_notifier_unregister(&netconfig_eap_notifier); +} + +gboolean handle_create_eap_config(Wifi *wifi, GDBusMethodInvocation *context, + const gchar *service, GVariant *fields) +{ + gboolean updated = FALSE; + gboolean result = FALSE; + + g_return_val_if_fail(wifi != NULL, TRUE); + + DBG("Set agent fields for %s", service); + + if (netconfig_is_wifi_profile(service) != TRUE) { + netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_WRONG_PROFILE, "InvalidService"); + return TRUE; + } + + updated = __netconfig_create_config(fields); + if (updated == TRUE) { + wifi_complete_create_eap_config(wifi, context); + + if (g_strstr_len(service, strlen(service), "_hidden_") != NULL) { + GVariantIter *iter; + char *field, *value; + const char *name = NULL; + const char *identity = NULL; + const char *passphrase = NULL; + + g_variant_get(fields, "a{ss}", &iter); + + while (g_variant_iter_loop(iter, "{ss}", &field, &value)) { + if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_NAME) == 0) + name = (const char *)value; + else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_SSID) == 0) + name = (const char *)value; + else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_IDENTITY) == 0) + identity = (const char *)value; + else if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_PASSPHRASE) == 0) + passphrase = (const char *)value; + } + + netconfig_wifi_set_agent_field_for_eap_network( + name, identity, passphrase); + + g_variant_iter_free(iter); } + + result = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE, + service, CONNMAN_SERVICE_INTERFACE, "Connect", + NULL, __netconfig_wifi_connect_reply); + + if (netconfig_eap_notifier.user_data != NULL) { + g_free(netconfig_eap_notifier.user_data); + netconfig_eap_notifier.user_data = NULL; + + wifi_state_notifier_unregister(&netconfig_eap_notifier); + } + + netconfig_eap_notifier.user_data = g_strdup(service); + wifi_state_notifier_register(&netconfig_eap_notifier); } else { - DBG("Fetching of SSID fails"); + netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments"); } - return ret; + if (result != TRUE) + ERR("Fail to connect %s", service); + + return TRUE; +} + +gboolean handle_delete_eap_config(Wifi *wifi, GDBusMethodInvocation *context, + const gchar *profile) +{ + g_return_val_if_fail(wifi != NULL, TRUE); + + wifi_complete_delete_eap_config(wifi, context); + + __netconfig_delete_config((const char *)profile); + + return TRUE; }