/* * Copyright © 2012 Canonical Ltd. * Copyright © 2015 The Arctica Project * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: Ted Gould * Mike Gabriel */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "rdp-server.h" #include "defines.h" static void rdp_server_class_init (RdpServerClass *klass); static void rdp_server_init (RdpServer *self); static void rdp_server_dispose (GObject *object); static void rdp_server_finalize (GObject *object); static GVariant * get_properties (Server * server); G_DEFINE_TYPE (RdpServer, rdp_server, SERVER_TYPE); static void rdp_server_class_init (RdpServerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = rdp_server_dispose; object_class->finalize = rdp_server_finalize; ServerClass * server_class = SERVER_CLASS(klass); server_class->get_properties = get_properties; return; } static void rdp_server_init (RdpServer *self) { self->username = NULL; self->password = NULL; self->domain = NULL; self->domain_required = FALSE; return; } static void rdp_server_dispose (GObject *object) { G_OBJECT_CLASS (rdp_server_parent_class)->dispose (object); return; } /* Unlocks the memory before freeing */ static void password_clear (gpointer data) { char * pass = (char *)data; munlock(pass, strlen(pass)); g_free(pass); return; } static void rdp_server_finalize (GObject *object) { RdpServer * server = RDP_SERVER(object); g_clear_pointer(&server->username, g_free); g_clear_pointer(&server->password, password_clear); g_clear_pointer(&server->domain, g_free); G_OBJECT_CLASS (rdp_server_parent_class)->finalize (object); return; } static GVariant * get_properties (Server * server) { RdpServer * rserver = RDP_SERVER(server); GVariantBuilder propbuilder; g_variant_builder_init(&propbuilder, G_VARIANT_TYPE_ARRAY); GVariantBuilder namebuilder; g_variant_builder_init(&namebuilder, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value(&namebuilder, g_variant_new_string("username")); g_variant_builder_add_value(&namebuilder, g_variant_new_boolean(TRUE)); if (rserver->username == NULL) { g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(""))); } else { g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(rserver->username))); } g_variant_builder_add_value(&namebuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&namebuilder)); GVariantBuilder passbuilder; g_variant_builder_init(&passbuilder, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value(&passbuilder, g_variant_new_string("password")); g_variant_builder_add_value(&passbuilder, g_variant_new_boolean(TRUE)); if (rserver->password == NULL) { g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(""))); } else { g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(rserver->password))); } g_variant_builder_add_value(&passbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&passbuilder)); GVariantBuilder domainbuilder; g_variant_builder_init(&domainbuilder, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value(&domainbuilder, g_variant_new_string("domain")); g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(rserver->domain_required)); if (rserver->domain == NULL) { g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(""))); } else { g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(rserver->domain))); } g_variant_builder_add_value(&domainbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&domainbuilder)); return g_variant_builder_end(&propbuilder); } Server * rdp_server_new_from_keyfile (GKeyFile * keyfile, const gchar * groupname) { g_return_val_if_fail(keyfile != NULL, NULL); /* NOTE: No way to check if that's really a keyfile :-( */ g_return_val_if_fail(groupname != NULL, NULL); if (!g_key_file_has_group(keyfile, groupname)) { g_warning("Server specified but group '%s' was not found", groupname); return NULL; } RdpServer * server = g_object_new(RDP_SERVER_TYPE, NULL); if (g_key_file_has_key(keyfile, groupname, CONFIG_SERVER_NAME, NULL)) { gchar * keyname = g_key_file_get_string(keyfile, groupname, CONFIG_SERVER_NAME, NULL); server->parent.name = g_strdup(_(keyname)); g_free(keyname); } if (g_key_file_has_key(keyfile, groupname, CONFIG_SERVER_URI, NULL)) { server->parent.uri = g_key_file_get_string(keyfile, groupname, CONFIG_SERVER_URI, NULL); } return SERVER(server); } /* Build the RDP server from information in the JSON object */ Server * rdp_server_new_from_json (JsonObject * object) { RdpServer * server = g_object_new(RDP_SERVER_TYPE, NULL); if (json_object_has_member(object, JSON_SERVER_NAME)) { JsonNode * node = json_object_get_member(object, JSON_SERVER_NAME); if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { const gchar * name = json_node_get_string(node); server->parent.name = g_strdup(name); } } if (json_object_has_member(object, JSON_URI)) { JsonNode * node = json_object_get_member(object, JSON_URI); if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { const gchar * uri = json_node_get_string(node); server->parent.uri = g_strdup(uri); } } if (json_object_has_member(object, JSON_USERNAME)) { JsonNode * node = json_object_get_member(object, JSON_USERNAME); if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { const gchar * username = json_node_get_string(node); server->username = g_strdup(username); } } if (json_object_has_member(object, JSON_PASSWORD)) { JsonNode * node = json_object_get_member(object, JSON_PASSWORD); if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { const gchar * password = json_node_get_string(node); server->password = g_strdup(password); mlock(server->password, strlen(server->password)); } } if (json_object_has_member(object, JSON_DOMAIN)) { JsonNode * node = json_object_get_member(object, JSON_DOMAIN); if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { const gchar * domain = json_node_get_string(node); server->domain = g_strdup(domain); } } if (json_object_has_member(object, JSON_DOMAIN_REQ)) { JsonNode * node = json_object_get_member(object, JSON_DOMAIN_REQ); if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_BOOLEAN) { server->domain_required = json_node_get_boolean(node); } } return SERVER(server); }