90
98
self->json_stream = NULL;
91
99
self->pass_stream = NULL;
101
self->min_network = NM_STATE_CONNECTED_GLOBAL;
102
self->last_network = NM_STATE_DISCONNECTED;
103
self->nm_client = NULL;
106
/* Start as unavailable */
107
self->parent.state = SERVER_STATE_UNAVAILABLE;
109
if (global_client == NULL) {
110
global_client = nm_client_new();
112
if (global_client != NULL) {
113
g_object_add_weak_pointer(G_OBJECT(global_client), (gpointer *)&global_client);
114
self->nm_client = global_client;
117
self->nm_client = g_object_ref(global_client);
120
if (self->nm_client != NULL) {
121
self->nm_signal = g_signal_connect(self->nm_client, "notify::" NM_CLIENT_STATE, G_CALLBACK(nm_state_changed), self);
124
self->verify_server = TRUE;
125
self->verified_server = FALSE;
126
self->session = NULL;
128
/* Need the soup session before the state changed */
129
self->session = soup_session_sync_new();
131
nm_state_changed(self->nm_client, NULL, self);
132
evaluate_state(self);
137
/* Small function to try and figure out the state of the server and set the
138
status appropriately */
140
evaluate_state (UccsServer * server)
142
ServerState tempstate = SERVER_STATE_ALLGOOD;
144
if (server->exec == NULL) {
145
tempstate = SERVER_STATE_UNAVAILABLE;
148
if (server->last_network < server->min_network) {
149
tempstate = SERVER_STATE_UNAVAILABLE;
152
if (server->verify_server && !server->verified_server && server->min_network > NM_STATE_DISCONNECTED) {
153
tempstate = SERVER_STATE_UNAVAILABLE;
156
if (tempstate != server->parent.state) {
157
server->parent.state = tempstate;
158
g_signal_emit_by_name(server, SERVER_SIGNAL_STATE_CHANGED, server->parent.state);
298
/* Callback from the message getting complete */
300
verify_server_cb (SoupSession * session, SoupMessage * message, gpointer user_data)
302
UccsServer * server = UCCS_SERVER(user_data);
303
guint statuscode = 404;
305
g_object_get(G_OBJECT(message), SOUP_MESSAGE_STATUS_CODE, &statuscode, NULL);
306
g_debug("Verification came back with status: %d", statuscode);
308
if (statuscode == 200) {
309
server->verified_server = TRUE;
311
server->verified_server = FALSE;
314
evaluate_state(server);
319
/* Set up the process to verify the server */
321
verify_server (UccsServer * server)
323
g_return_if_fail(server->session != NULL);
325
if (server->parent.uri == NULL) {
329
SoupMessage * message = soup_message_new("HEAD", server->parent.uri);
330
soup_session_queue_message(server->session, message, verify_server_cb, server);
331
g_debug("Getting HEAD from: %s", server->parent.uri);
336
/* Callback for when the Network Manger state changes */
338
nm_state_changed (NMClient *client, const GParamSpec *pspec, gpointer user_data)
340
g_return_if_fail(IS_UCCS_SERVER(user_data));
341
UccsServer * server = UCCS_SERVER(user_data);
343
if (server->nm_client == NULL || !nm_client_get_manager_running(server->nm_client)) {
344
server->last_network = NM_STATE_DISCONNECTED;
346
server->last_network = nm_client_get_state(server->nm_client);
349
if (server->last_network == NM_STATE_DISCONNECTED) {
350
server->verified_server = FALSE;
351
soup_session_abort(server->session);
354
if (server->last_network == NM_STATE_CONNECTED_GLOBAL && server->verify_server && !server->verified_server) {
355
verify_server(server);
358
evaluate_state(server);
363
/* Get the properties that can be sent by the greeter for this server */
212
364
static GVariant *
213
365
get_properties (Server * server)
234
386
return g_variant_builder_end(&propbuilder);
389
/* Set the exec value for the server */
391
uccs_server_set_exec (UccsServer * server, const gchar * exec)
393
g_return_val_if_fail(IS_UCCS_SERVER(server), NULL);
395
g_clear_pointer(&server->exec, g_free);
398
server->exec = g_find_program_in_path(exec);
401
evaluate_state(server);
406
/* Build a new uccs server from a keyfile and a group in it */
238
uccs_server_new_from_keyfile (GKeyFile * keyfile, const gchar * name)
408
uccs_server_new_from_keyfile (GKeyFile * keyfile, const gchar * groupname)
240
410
g_return_val_if_fail(keyfile != NULL, NULL); /* NOTE: No way to check if that's really a keyfile :-( */
241
g_return_val_if_fail(name != NULL, NULL);
243
gchar * groupname = g_strdup_printf("%s %s", CONFIG_UCCS_PREFIX, name);
411
g_return_val_if_fail(groupname != NULL, NULL);
245
413
if (!g_key_file_has_group(keyfile, groupname)) {
246
g_warning("Server '%s' specified but group '%s' was not found", name, groupname);
414
g_warning("Server specified but group '%s' was not found", groupname);
251
418
UccsServer * server = g_object_new(UCCS_SERVER_TYPE, NULL);
253
if (g_key_file_has_key(keyfile, groupname, "Name", NULL)) {
254
server->parent.name = g_key_file_get_string(keyfile, groupname, CONFIG_SERVER_NAME, NULL);
420
if (g_key_file_has_key(keyfile, groupname, CONFIG_SERVER_NAME, NULL)) {
421
gchar * keyname = g_key_file_get_string(keyfile, groupname, CONFIG_SERVER_NAME, NULL);
422
server->parent.name = g_strdup(_(keyname));
257
if (g_key_file_has_key(keyfile, groupname, "URI", NULL)) {
426
if (g_key_file_has_key(keyfile, groupname, CONFIG_SERVER_URI, NULL)) {
258
427
server->parent.uri = g_key_file_get_string(keyfile, groupname, CONFIG_SERVER_URI, NULL);
261
430
if (g_key_file_has_key(keyfile, groupname, CONFIG_UCCS_EXEC, NULL)) {
262
g_free(server->exec);
263
431
gchar * key = g_key_file_get_string(keyfile, groupname, CONFIG_UCCS_EXEC, NULL);
264
server->exec = g_find_program_in_path(key);
432
uccs_server_set_exec(server, key);
436
if (g_key_file_has_key(keyfile, groupname, CONFIG_UCCS_NETWORK, NULL)) {
437
gchar * key = g_key_file_get_string(keyfile, groupname, CONFIG_UCCS_NETWORK, NULL);
439
if (g_strcmp0(key, CONFIG_UCCS_NETWORK_NONE) == 0) {
440
server->min_network = NM_STATE_DISCONNECTED;
441
} else if (g_strcmp0(key, CONFIG_UCCS_NETWORK_GLOBAL) == 0) {
442
server->min_network = NM_STATE_CONNECTED_GLOBAL;
444
/* NOTE: There is a possibility for other network types to be added here,
445
but they can be tricky to test. Feel free to patch it, but please include
451
if (g_key_file_has_key(keyfile, groupname, CONFIG_UCCS_VERIFY, NULL)) {
452
server->verify_server = g_key_file_get_boolean(keyfile, groupname, CONFIG_UCCS_VERIFY, NULL);
455
evaluate_state(server);
269
457
return SERVER(server);
285
473
JsonObject * object = json_node_get_object(node);
286
if (!json_object_has_member(object, "Protocol")) {
290
JsonNode * proto_node = json_object_get_member(object, "Protocol");
291
if (JSON_NODE_TYPE(proto_node) != JSON_NODE_VALUE) {
294
if (json_node_get_value_type(proto_node) != G_TYPE_STRING) {
298
const gchar * proto = json_node_get_string(proto_node);
299
Server * newserver = NULL;
301
if (g_strcmp0(proto, "ICA") == 0 || g_strcmp0(proto, "ica") == 0) {
302
newserver = citrix_server_new_from_json(object);
304
else if (g_strcmp0(proto, "freerdp") == 0 || g_strcmp0(proto, "rdp") == 0 || g_strcmp0(proto, "RDP") == 0 || g_strcmp0(proto, "FreeRDP") == 0) {
305
newserver = rdp_server_new_from_json(object);
308
if (newserver == NULL) continue;
310
server->subservers = g_list_append(server->subservers, newserver);
474
Server * newserver = server_new_from_json(object);
475
if (newserver != NULL) {
476
server->subservers = g_list_append(server->subservers, newserver);
366
533
g_warning("Malformed 'RemoteDesktopServer' entry. Not an array but a: %s", json_node_type_name(rds_node));
537
if (json_object_has_member(root_object, "DefaultServer")) {
538
JsonNode * ds_node = json_object_get_member(root_object, "DefaultServer");
539
if (JSON_NODE_TYPE(ds_node) == JSON_NODE_VALUE && json_node_get_value_type(ds_node) == G_TYPE_STRING) {
540
const gchar * default_server_name = json_node_get_string(ds_node);
541
if (default_server_name != NULL) {
543
for (lserver = server->subservers; lserver != NULL; lserver = g_list_next(lserver)) {
544
Server * serv = SERVER(lserver->data);
546
if (g_strcmp0(serv->name, default_server_name) == 0) {
547
serv->last_used = TRUE;
551
if (lserver == NULL && strlen(default_server_name) > 0) {
552
g_warning("Could not find the 'DefaultServer' server.");
557
g_warning("Malformed 'DefaultServer' entry. Not a string value");
370
562
g_debug("No 'RemoteDesktopServers' found");
476
669
* cache or from the network.
479
uccs_server_unlock (UccsServer * server, const gchar * address, const gchar * username, const gchar * password, void (*callback) (UccsServer * server, gboolean unlocked, gpointer user_data), gpointer user_data)
672
uccs_server_unlock (UccsServer * server, const gchar * address, const gchar * username, const gchar * password, gboolean allowcache, void (*callback) (UccsServer * server, gboolean unlocked, gpointer user_data), gpointer user_data)
481
674
g_return_if_fail(IS_UCCS_SERVER(server));
482
675
g_return_if_fail(username != NULL);
498
if (server->username != NULL && (server->password != NULL || password == NULL)) {
499
/* We've got stored values, but those weren't them */
501
if (callback != NULL) {
502
callback(server, FALSE, user_data);
508
691
g_return_if_fail(server->exec != NULL); /* Shouldn't happen, but I'd feel safer if we checked */
693
/* If we're not going to allow the cache, just clear it right away */
510
698
/* We're changing the username and password, if there were other
511
699
people who had it, they need to know we're different now */
513
server->username = g_strdup(username);
514
server->password = g_strdup(password);
700
if (g_strcmp0(username, server->username) != 0 ||
701
g_strcmp0(password, server->password) != 0) {
705
g_clear_pointer(&server->username, g_free);
706
g_clear_pointer(&server->password, g_free);
708
server->username = g_strdup(username);
709
server->password = g_strdup(password);
516
712
/* Add ourselves to the queue */
517
713
json_callback_t * json_callback = g_new0(json_callback_t, 1);
597
793
return null_server_array();
600
if (g_list_length(server->subservers) == 0) {
601
return null_server_array();
604
796
GVariantBuilder array;
605
797
g_variant_builder_init(&array, G_VARIANT_TYPE_ARRAY);
607
800
for (lserver = server->subservers; lserver != NULL; lserver = g_list_next(lserver)) {
608
801
Server * serv = SERVER(lserver->data);
803
/* We only want servers that are all good */
804
if (serv->state != SERVER_STATE_ALLGOOD) {
609
809
g_variant_builder_add_value(&array, server_get_variant(serv));
812
if (servercnt == 0) {
813
g_variant_builder_clear(&array);
814
return null_server_array();
612
817
return g_variant_builder_end(&array);