2
* Copyright (C) 2003 Sun Microsystems, Inc.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; either version 2 of the
7
* License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful, but
10
* WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20
* Mark McLoughlin <mark@skynet.ie>
25
#include "vino-server.h"
29
#ifdef VINO_ENABLE_HTTP_SERVER
30
#include "vino-http.h"
32
#include "vino-input.h"
33
#include "vino-cursor.h"
34
#include "vino-prompt.h"
35
#include "vino-util.h"
36
#include "vino-enums.h"
39
/* If an authentication attempt failes, delay the next
40
* authentication attempt for 5 seconds.
42
#define VINO_SERVER_AUTH_DEFER_LEN 5
44
struct _VinoServerPrivate
46
rfbScreenInfoPtr rfb_screen;
50
VinoCursorData *cursor_data;
53
GIOChannel *io_channel;
58
VinoAuthMethod auth_methods;
61
#ifdef VINO_ENABLE_HTTP_SERVER
66
guint prompt_enabled : 1;
68
guint require_encryption : 1;
69
guint last_auth_failed : 1;
74
rfbClientPtr rfb_client;
75
GIOChannel *io_channel;
79
/* Deferred authentication */
83
} VinoServerClientInfo;
92
PROP_REQUIRE_ENCRYPTION,
97
static enum rfbNewClientAction vino_server_auth_client (VinoServer *server,
98
VinoServerClientInfo *client,
102
static void vino_server_setup_framebuffer (VinoServer *server);
103
static void vino_server_release_framebuffer (VinoServer *server);
105
static gpointer parent_class;
108
vino_server_handle_client_gone (rfbClientPtr rfb_client)
110
VinoServer *server = VINO_SERVER (rfb_client->screen->screenData);
111
VinoServerClientInfo *client = NULL;
114
g_return_if_fail (VINO_IS_SERVER (server));
116
dprintf (RFB, "Client with fd == %d gone\n", rfb_client->sock);
118
vino_prompt_remove_client (server->priv->prompt, rfb_client);
120
for (l = server->priv->clients; l; l = l->next)
122
client = (VinoServerClientInfo *) l->data;
124
if (rfb_client == client->rfb_client)
126
dprintf (RFB, "Found client %p ... cleaning up\n", client->rfb_client);
128
if (client->auth_timeout)
129
g_source_remove (client->auth_timeout);
130
client->auth_timeout = 0;
132
if (client->auth_response)
133
g_free (client->auth_response);
134
client->auth_response = NULL;
135
client->auth_resp_len = 0;
137
if (client->update_timeout)
138
g_source_remove (client->update_timeout);
139
client->update_timeout = 0;
141
g_source_remove (client->io_watch);
142
client->io_watch = 0;
144
g_io_channel_unref (client->io_channel);
145
client->io_channel = NULL;
148
server->priv->clients = g_slist_delete_link (server->priv->clients, l);
153
if (!server->priv->clients)
154
vino_server_release_framebuffer (server);
158
vino_server_update_client (rfbClientPtr rfb_client)
160
VinoServer *server = VINO_SERVER (rfb_client->screen->screenData);
161
const char *cursor_source;
162
const char *cursor_mask;
166
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
168
if (vino_cursor_get_x_source (server->priv->cursor_data,
170
&cursor_source, &cursor_mask))
172
rfbCursorPtr rfb_cursor;
174
rfb_cursor = rfbMakeXCursor (width, height, cursor_source, cursor_mask);
175
rfbSetCursor (rfb_client->screen, rfb_cursor, TRUE);
178
vino_cursor_get_position (server->priv->cursor_data, &x, &y);
179
rfbSetCursorPosition (rfb_client->screen, NULL, x, y);
181
rfbUpdateClient (rfb_client);
183
if (rfb_client->sock == -1)
185
rfbClientConnectionGone (rfb_client);
193
vino_server_update_client_timeout (rfbClientPtr rfb_client)
195
if (rfb_client->onHold)
198
vino_server_update_client (rfb_client);
204
vino_server_set_client_on_hold (VinoServer *server,
205
VinoServerClientInfo *client,
208
rfbClientPtr rfb_client = client->rfb_client;
210
dprintf (RFB, "Setting client '%s' on hold: %s\n",
211
rfb_client->host, on_hold ? "(true)" : "(false)");
213
rfb_client->onHold = on_hold;
215
/* We don't process any pending data from an client which is
216
* on hold, so don't let it starve the rest of the mainloop.
218
g_source_set_priority (g_main_context_find_source_by_id (NULL, client->io_watch),
219
on_hold ? G_PRIORITY_LOW : G_PRIORITY_DEFAULT);
223
if (!client->update_timeout)
224
client->update_timeout = g_timeout_add (50,
225
(GSourceFunc) vino_server_update_client_timeout,
230
if (client->update_timeout)
231
g_source_remove (client->update_timeout);
232
client->update_timeout = 0;
236
static inline gboolean
237
more_data_pending (int fd)
239
struct pollfd pollfd = { fd, POLLIN|POLLPRI, 0 };
241
return poll (&pollfd, 1, 0) == 1;
245
vino_server_client_data_pending (GIOChannel *source,
246
GIOCondition condition,
247
rfbClientPtr rfb_client)
249
if (rfb_client->onHold)
253
rfbProcessClientMessage (rfb_client);
254
} while (more_data_pending (rfb_client->sock));
256
return vino_server_update_client (rfb_client);
259
static enum rfbNewClientAction
260
vino_server_handle_new_client (rfbClientPtr rfb_client)
262
VinoServer *server = VINO_SERVER (rfb_client->screen->screenData);
263
VinoServerClientInfo *client;
265
g_return_val_if_fail (VINO_IS_SERVER (server), RFB_CLIENT_REFUSE);
267
dprintf (RFB, "New client on fd %d\n", rfb_client->sock);
269
if (!server->priv->fb)
270
vino_server_setup_framebuffer (server);
272
client = g_new0 (VinoServerClientInfo, 1);
274
rfb_client->clientData = client;
276
client->rfb_client = rfb_client;
278
client->rfb_client->clientGoneHook = vino_server_handle_client_gone;
280
client->io_channel = g_io_channel_unix_new (rfb_client->sock);
282
client->io_watch = g_io_add_watch (client->io_channel,
284
(GIOFunc) vino_server_client_data_pending,
287
server->priv->clients = g_slist_prepend (server->priv->clients, client);
289
vino_server_set_client_on_hold (server, client, server->priv->on_hold);
291
return server->priv->on_hold ? RFB_CLIENT_ON_HOLD : RFB_CLIENT_ACCEPT;
295
vino_server_handle_prompt_response (VinoServer *server,
296
rfbClientPtr rfb_client,
297
VinoPromptResponse response)
299
g_return_if_fail (VINO_IS_SERVER (server));
300
g_return_if_fail (rfb_client != NULL);
304
case VINO_RESPONSE_ACCEPT:
305
vino_server_set_client_on_hold (server, rfb_client->clientData, FALSE);
307
case VINO_RESPONSE_REJECT:
308
rfbCloseClient (rfb_client);
309
rfbClientConnectionGone (rfb_client);
311
case VINO_RESPONSE_INVALID:
312
g_assert_not_reached ();
317
static enum rfbNewClientAction
318
vino_server_handle_authenticated_client (rfbClientPtr rfb_client)
320
VinoServer *server = VINO_SERVER (rfb_client->screen->screenData);
321
VinoServerClientInfo *client = (VinoServerClientInfo *) rfb_client->clientData;
323
g_return_val_if_fail (VINO_IS_SERVER (server), RFB_CLIENT_REFUSE);
325
if (!server->priv->prompt_enabled)
326
return RFB_CLIENT_ACCEPT;
328
vino_prompt_add_client (server->priv->prompt, rfb_client);
330
vino_server_set_client_on_hold (server, client, TRUE);
332
return RFB_CLIENT_ON_HOLD;
336
vino_server_new_connection_pending (GIOChannel *source,
337
GIOCondition condition,
340
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
342
rfbProcessNewConnection (server->priv->rfb_screen);
348
vino_server_handle_key_event (rfbBool down,
350
rfbClientPtr rfb_client)
352
VinoServer *server = VINO_SERVER (rfb_client->screen->screenData);
354
g_return_if_fail (VINO_IS_SERVER (server));
356
if (server->priv->view_only)
359
vino_input_handle_key_event (server->priv->screen, keySym, down);
363
vino_server_handle_pointer_event (int buttonMask,
366
rfbClientPtr rfb_client)
368
VinoServer *server = VINO_SERVER (rfb_client->screen->screenData);
370
g_return_if_fail (VINO_IS_SERVER (server));
372
if (server->priv->view_only)
375
vino_input_handle_pointer_event (server->priv->screen, buttonMask, x, y);
379
vino_server_handle_clipboard_event (char *str,
381
rfbClientPtr rfb_client)
383
VinoServer *server = VINO_SERVER (rfb_client->screen->screenData);
385
g_return_if_fail (VINO_IS_SERVER (server));
387
if (server->priv->view_only)
390
vino_input_handle_clipboard_event (server->priv->screen, str, len);
394
vino_server_auth_client_deferred (VinoServerClientInfo *client)
396
VinoServer *server = VINO_SERVER (client->rfb_client->screen->screenData);
397
enum rfbNewClientAction result;
399
result = vino_server_auth_client (server,
401
client->auth_response,
402
client->auth_resp_len);
404
if (result == RFB_CLIENT_ACCEPT)
405
vino_server_set_client_on_hold (server, client, FALSE);
407
rfbAuthPasswordChecked (client->rfb_client, result);
409
g_free (client->auth_response);
410
client->auth_response = NULL;
411
client->auth_resp_len = 0;
412
client->auth_timeout = 0;
418
vino_server_defer_client_auth (VinoServer *server,
419
VinoServerClientInfo *client,
420
const char *response,
423
client->auth_resp_len = length;
424
client->auth_response = g_new (char, length);
425
memcpy (client->auth_response, response, length);
427
vino_server_set_client_on_hold (server, client, TRUE);
429
client->auth_timeout = g_timeout_add (VINO_SERVER_AUTH_DEFER_LEN * 1000,
430
(GSourceFunc) vino_server_auth_client_deferred,
434
static enum rfbNewClientAction
435
vino_server_auth_client (VinoServer *server,
436
VinoServerClientInfo *client,
437
const char *response,
440
rfbClientPtr rfb_client;
443
if (!(server->priv->auth_methods & VINO_AUTH_VNC))
446
if (!server->priv->vnc_password)
449
if (!(password = vino_base64_unencode (server->priv->vnc_password)))
451
g_warning ("Failed to base64 unencode VNC password\n");
455
rfb_client = client->rfb_client;
457
vncEncryptBytes (client->rfb_client->authChallenge, password);
459
memset (password, 0, strlen (password));
462
if (memcmp (rfb_client->authChallenge, response, length))
464
memset (rfb_client->authChallenge, 0, CHALLENGESIZE);
465
g_warning ("VNC authentication failure from '%s'\n", rfb_client->host);
469
memset (rfb_client->authChallenge, 0, CHALLENGESIZE);
471
server->priv->last_auth_failed = FALSE;
473
return RFB_CLIENT_ACCEPT;
476
/* Delay the next authentication attempt so as to make
477
* brute force guessing of the password infeasible.
479
server->priv->last_auth_failed = TRUE;
480
return RFB_CLIENT_REFUSE;
483
static enum rfbNewClientAction
484
vino_server_check_vnc_password (rfbClientPtr rfb_client,
485
const char *response,
488
VinoServer *server = VINO_SERVER (rfb_client->screen->screenData);
489
VinoServerClientInfo *client = (VinoServerClientInfo *) rfb_client->clientData;
491
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
493
if (!response || length != CHALLENGESIZE)
495
server->priv->last_auth_failed = TRUE;
496
return RFB_CLIENT_REFUSE;
499
if (server->priv->last_auth_failed)
501
g_warning ("Deferring authentication of '%s' for %d seconds\n",
502
rfb_client->host, VINO_SERVER_AUTH_DEFER_LEN);
503
vino_server_defer_client_auth (server, client, response, length);
504
return RFB_CLIENT_ON_HOLD;
507
return vino_server_auth_client (server, client, response, length);
511
vino_server_handle_damage_notify (VinoServer *server)
516
g_return_if_fail (VINO_IS_SERVER (server));
518
rects = vino_fb_get_damage (server->priv->fb, &n_rects, TRUE);
520
for (i = 0; i < n_rects; i++)
521
rfbMarkRectAsModified (server->priv->rfb_screen,
524
rects [i].x + rects [i].width,
525
rects [i].y + rects [i].height);
531
vino_server_init_pixel_format (VinoServer *server,
532
rfbScreenInfoPtr rfb_screen)
535
rfbPixelFormat *format = &rfb_screen->rfbServerFormat;
536
gulong red_mask, green_mask, blue_mask;
538
rfb_screen->bitsPerPixel = vino_fb_get_bits_per_pixel (server->priv->fb);
539
rfb_screen->depth = vino_fb_get_depth (server->priv->fb);
540
rfb_screen->paddedWidthInBytes = vino_fb_get_rowstride (server->priv->fb);
542
format->bitsPerPixel = rfb_screen->bitsPerPixel;
543
format->depth = rfb_screen->depth;
545
vino_fb_get_color_masks (server->priv->fb,
546
&red_mask, &green_mask, &blue_mask);
548
format->redShift = 0;
549
while (!(red_mask & (1 << format->redShift)))
552
format->greenShift = 0;
553
while (!(green_mask & (1 << format->greenShift)))
554
format->greenShift++;
556
format->blueShift = 0;
557
while (!(blue_mask & (1 << format->blueShift)))
560
format->redMax = red_mask >> format->redShift;
561
format->greenMax = green_mask >> format->greenShift;
562
format->blueMax = blue_mask >> format->blueShift;
565
"Initialized pixel format: %dbpp, depth = %d\n"
566
"\tred: mask = %.8lx, max = %d, shift = %d\n"
567
"\tgreen: mask = %.8lx, max = %d, shift = %d\n"
568
"\tblue: mask = %.8lx, max = %d, shift = %d\n",
569
format->bitsPerPixel, format->depth,
570
red_mask, format->redMax, format->redShift,
571
green_mask, format->greenMax, format->greenShift,
572
blue_mask, format->blueMax, format->blueShift);
576
vino_server_screen_size_changed (VinoServer *server)
578
g_return_if_fail (VINO_IS_SERVER (server));
580
rfbNewFramebuffer (server->priv->rfb_screen,
581
vino_fb_get_pixels (server->priv->fb),
582
gdk_screen_get_width (server->priv->screen),
583
gdk_screen_get_height (server->priv->screen),
586
vino_server_init_pixel_format (server, server->priv->rfb_screen);
590
vino_server_setup_framebuffer (VinoServer *server)
592
g_return_if_fail (server->priv->fb == NULL);
593
g_return_if_fail (server->priv->cursor_data == NULL);
595
server->priv->fb = vino_fb_new (server->priv->screen);
597
g_signal_connect_swapped (server->priv->fb, "size-changed",
598
G_CALLBACK (vino_server_screen_size_changed),
600
g_signal_connect_swapped (server->priv->fb, "damage-notify",
601
G_CALLBACK (vino_server_handle_damage_notify),
604
server->priv->rfb_screen->frameBuffer = vino_fb_get_pixels (server->priv->fb);
606
vino_server_init_pixel_format (server, server->priv->rfb_screen);
608
server->priv->cursor_data = vino_cursor_init (server->priv->screen);
612
vino_server_release_framebuffer (VinoServer *server)
614
g_return_if_fail (server->priv->fb != NULL);
615
g_return_if_fail (server->priv->cursor_data != NULL);
617
if (server->priv->cursor_data)
618
vino_cursor_finalize (server->priv->cursor_data);
619
server->priv->cursor_data = NULL;
621
server->priv->rfb_screen->frameBuffer = NULL;
623
g_object_unref (server->priv->fb);
624
server->priv->fb = NULL;
628
vino_server_init_from_screen (VinoServer *server,
631
rfbScreenInfoPtr rfb_screen;
633
g_return_if_fail (server->priv->screen == NULL);
634
g_return_if_fail (screen != NULL);
636
server->priv->screen = screen;
638
server->priv->prompt = vino_prompt_new (screen);
640
g_signal_connect_swapped (server->priv->prompt, "response",
641
G_CALLBACK (vino_server_handle_prompt_response),
644
/* libvncserver NOTE:
645
* we don't pass in argc or argv
646
* samplesPerPixel is totally unused (3 below)
647
* bitsPerSample and bytesPerPixel get set in
650
server->priv->rfb_screen = rfb_screen =
651
rfbGetScreen (NULL, NULL,
652
gdk_screen_get_width (screen),
653
gdk_screen_get_height (screen),
656
/* libvncserver NOTE:
657
* DeferUpdateTime is the number of milliseconds to wait
658
* before actually responding to a frame buffer update
660
* setting autoPort enables autoProbing a port between
663
rfb_screen->rfbDeferUpdateTime = 0;
664
rfb_screen->autoPort = TRUE;
665
rfb_screen->rfbAlwaysShared = TRUE;
667
rfbInitServer (rfb_screen);
669
/* libvncserver NOTE:
670
* there's no user_data for newClientHook. You have
673
rfb_screen->screenData = server;
674
rfb_screen->newClientHook = vino_server_handle_new_client;
675
rfb_screen->authenticatedClientHook = vino_server_handle_authenticated_client;
677
/* libvncserver NOTE:
678
* all these hooks should take an rfbClientPtr as the
679
* first argument rather than the last.
681
rfb_screen->kbdAddEvent = vino_server_handle_key_event;
682
rfb_screen->ptrAddEvent = vino_server_handle_pointer_event;
683
rfb_screen->setXCutText = vino_server_handle_clipboard_event;
685
rfb_screen->passwordCheck = vino_server_check_vnc_password;
687
dprintf (RFB, "Creating watch for listening socket %d - port %d\n",
688
rfb_screen->rfbListenSock, rfb_screen->rfbPort);
690
server->priv->io_channel = g_io_channel_unix_new (rfb_screen->rfbListenSock);
691
server->priv->io_watch =
692
g_io_add_watch (server->priv->io_channel,
694
(GIOFunc) vino_server_new_connection_pending,
697
#ifdef VINO_ENABLE_HTTP_SERVER
698
server->priv->http = vino_http_get (rfb_screen->rfbPort);
703
vino_server_finalize (GObject *object)
705
VinoServer *server = VINO_SERVER (object);
707
#ifdef VINO_ENABLE_HTTP_SERVER
708
if (server->priv->http)
710
vino_http_remove_rfb_port (server->priv->http,
711
server->priv->rfb_screen->rfbPort);
712
g_object_unref (server->priv->http);
714
server->priv->http = NULL;
715
#endif /* VINO_ENABLE_HTTP_SERVER */
717
if (server->priv->io_watch)
718
g_source_remove (server->priv->io_watch);
719
server->priv->io_watch = 0;
721
if (server->priv->io_channel)
722
g_io_channel_unref (server->priv->io_channel);
723
server->priv->io_channel = NULL;
725
if (server->priv->rfb_screen)
726
rfbScreenCleanup (server->priv->rfb_screen);
727
server->priv->rfb_screen = NULL;
729
/* ClientGoneHook should get invoked for each
730
* client from rfbScreenCleanup()
732
g_assert (server->priv->clients == NULL);
734
if (server->priv->vnc_password)
735
g_free (server->priv->vnc_password);
736
server->priv->vnc_password = NULL;
738
if (server->priv->prompt)
739
g_object_unref (server->priv->prompt);
740
server->priv->prompt = NULL;
742
if (server->priv->cursor_data)
743
vino_cursor_finalize (server->priv->cursor_data);
744
server->priv->cursor_data = NULL;
746
if (server->priv->fb)
747
g_object_unref (server->priv->fb);
748
server->priv->fb = NULL;
750
g_free (server->priv);
753
if (G_OBJECT_CLASS (parent_class)->finalize)
754
G_OBJECT_CLASS (parent_class)->finalize (object);
758
vino_server_set_property (GObject *object,
763
VinoServer *server = VINO_SERVER (object);
768
vino_server_init_from_screen (server, g_value_get_object (value));
771
vino_server_set_on_hold (server, g_value_get_boolean (value));
773
case PROP_PROMPT_ENABLED:
774
vino_server_set_prompt_enabled (server, g_value_get_boolean (value));
777
vino_server_set_view_only (server, g_value_get_boolean (value));
779
case PROP_REQUIRE_ENCRYPTION:
780
vino_server_set_require_encryption (server, g_value_get_boolean (value));
782
case PROP_AUTH_METHODS:
783
vino_server_set_auth_methods (server, g_value_get_flags (value));
785
case PROP_VNC_PASSWORD:
786
vino_server_set_vnc_password (server, g_value_get_string (value));
789
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
795
vino_server_get_property (GObject *object,
800
VinoServer *server = VINO_SERVER (object);
805
g_value_set_object (value, server->priv->screen);
808
g_value_set_boolean (value, server->priv->on_hold);
810
case PROP_PROMPT_ENABLED:
811
g_value_set_boolean (value, server->priv->prompt_enabled);
814
g_value_set_boolean (value, server->priv->view_only);
816
case PROP_REQUIRE_ENCRYPTION:
817
g_value_set_boolean (value, server->priv->view_only);
819
case PROP_AUTH_METHODS:
820
g_value_set_flags (value, server->priv->auth_methods);
822
case PROP_VNC_PASSWORD:
823
g_value_set_string (value, server->priv->vnc_password);
826
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
832
vino_server_instance_init (VinoServer *server)
834
server->priv = g_new0 (VinoServerPrivate, 1);
838
vino_server_class_init (VinoServerClass *klass)
840
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
842
parent_class = g_type_class_peek_parent (klass);
844
gobject_class->finalize = vino_server_finalize;
845
gobject_class->set_property = vino_server_set_property;
846
gobject_class->get_property = vino_server_get_property;
848
g_object_class_install_property (gobject_class,
850
g_param_spec_object ("screen",
852
_("The screen for which to create a VNC server"),
854
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
856
g_object_class_install_property (gobject_class,
858
g_param_spec_boolean ("on-hold",
860
_("Place all clients on hold"),
862
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
864
g_object_class_install_property (gobject_class,
866
g_param_spec_boolean ("prompt-enabled",
868
_("Prompt the user about connection attempts"),
870
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
872
g_object_class_install_property (gobject_class,
874
g_param_spec_boolean ("view-only",
876
_("Disallow keyboard/pointer input from clients"),
878
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
880
g_object_class_install_property (gobject_class,
881
PROP_REQUIRE_ENCRYPTION,
882
g_param_spec_boolean ("require-encryption",
883
_("Require Encryption"),
884
_("Require clients to use encryption"),
886
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
888
g_object_class_install_property (gobject_class,
890
g_param_spec_flags ("auth-methods",
891
_("Authentication methods"),
892
_("The authentication methods this server should allow"),
893
VINO_TYPE_AUTH_METHOD,
895
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
897
g_object_class_install_property (gobject_class,
899
g_param_spec_string ("vnc-password",
901
_("The password (base64 encoded) used to authenticate types using the VncAuth method"),
903
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
907
vino_server_get_type (void)
909
static GType object_type = 0;
913
static const GTypeInfo object_info =
915
sizeof (VinoServerClass),
916
(GBaseInitFunc) NULL,
917
(GBaseFinalizeFunc) NULL,
918
(GClassInitFunc) vino_server_class_init,
919
NULL, /* class_finalize */
920
NULL, /* class_data */
923
(GInstanceInitFunc) vino_server_instance_init,
926
object_type = g_type_register_static (G_TYPE_OBJECT,
936
vino_server_new (GdkScreen *screen,
939
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
941
return g_object_new (VINO_TYPE_SERVER,
943
"view-only", view_only,
948
vino_server_get_screen (VinoServer *server)
950
g_return_val_if_fail (VINO_IS_SERVER (server), NULL);
952
return server->priv->screen;
956
vino_server_get_view_only (VinoServer *server)
958
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
960
return server->priv->view_only;
964
vino_server_set_view_only (VinoServer *server,
967
g_return_if_fail (VINO_IS_SERVER (server));
969
view_only = view_only != FALSE;
971
if (server->priv->view_only != view_only)
973
server->priv->view_only = view_only;
975
g_object_notify (G_OBJECT (server), "view-only");
980
vino_server_get_on_hold (VinoServer *server)
982
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
984
return server->priv->on_hold;
988
vino_server_set_on_hold (VinoServer *server,
991
g_return_if_fail (VINO_IS_SERVER (server));
993
on_hold = on_hold != FALSE;
995
if (server->priv->on_hold != on_hold)
999
server->priv->on_hold = on_hold;
1001
for (l = server->priv->clients; l; l = l->next)
1003
VinoServerClientInfo *client = l->data;
1005
/* If a client is on hold before we have initialized,
1006
* we want to leave it on hold until the deferred
1007
* authentication or the prompt has completed.
1009
* FIXME: this isn't correct, though - e.g if we're
1010
* in the middle of prompting and you toggle the
1011
* server on and off then the client gets through.
1013
if (client->rfb_client->state == RFB_NORMAL)
1014
vino_server_set_client_on_hold (server, client, on_hold);
1017
g_object_notify (G_OBJECT (server), "on-hold");
1022
vino_server_get_prompt_enabled (VinoServer *server)
1024
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
1026
return server->priv->prompt_enabled;
1030
vino_server_set_prompt_enabled (VinoServer *server,
1031
gboolean prompt_enabled)
1033
g_return_if_fail (VINO_IS_SERVER (server));
1035
prompt_enabled = prompt_enabled != FALSE;
1037
if (server->priv->prompt_enabled != prompt_enabled)
1039
server->priv->prompt_enabled = prompt_enabled;
1041
g_object_notify (G_OBJECT (server), "prompt-enabled");
1046
vino_server_update_security_types (VinoServer *server)
1048
rfbClearSecurityTypes (server->priv->rfb_screen);
1049
rfbClearAuthTypes (server->priv->rfb_screen);
1052
rfbAddSecurityType (server->priv->rfb_screen, rfbTLS);
1055
if (server->priv->auth_methods & VINO_AUTH_VNC)
1057
rfbAddAuthType (server->priv->rfb_screen, rfbVncAuth);
1059
if (!server->priv->require_encryption)
1061
rfbAddSecurityType (server->priv->rfb_screen, rfbVncAuth);
1064
if (server->priv->auth_methods & VINO_AUTH_NONE)
1066
rfbAddAuthType (server->priv->rfb_screen, rfbNoAuth);
1068
if (!server->priv->require_encryption)
1070
rfbAddSecurityType (server->priv->rfb_screen, rfbNoAuth);
1074
vino_server_set_require_encryption (VinoServer *server,
1075
gboolean require_encryption)
1077
g_return_if_fail (VINO_IS_SERVER (server));
1079
require_encryption = require_encryption != FALSE;
1081
if (server->priv->require_encryption != require_encryption)
1083
server->priv->require_encryption = require_encryption;
1085
vino_server_update_security_types (server);
1087
g_object_notify (G_OBJECT (server), "require-encryption");
1092
vino_server_get_require_encryption (VinoServer *server)
1094
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
1096
return server->priv->require_encryption;
1100
vino_server_set_auth_methods (VinoServer *server,
1101
VinoAuthMethod auth_methods)
1103
g_return_if_fail (VINO_IS_SERVER (server));
1104
g_return_if_fail (auth_methods != VINO_AUTH_INVALID);
1106
if (server->priv->auth_methods != auth_methods)
1108
server->priv->auth_methods = auth_methods;
1110
vino_server_update_security_types (server);
1112
g_object_notify (G_OBJECT (server), "auth-methods");
1117
vino_server_get_auth_methods (VinoServer *server)
1119
g_return_val_if_fail (VINO_IS_SERVER (server), VINO_AUTH_INVALID);
1121
return server->priv->auth_methods;
1125
vino_server_set_vnc_password (VinoServer *server,
1126
const char *vnc_password)
1128
g_return_if_fail (VINO_IS_SERVER (server));
1130
if (server->priv->vnc_password)
1131
g_free (server->priv->vnc_password);
1133
server->priv->vnc_password = g_strdup (vnc_password);
1135
g_object_notify (G_OBJECT (server), "vnc-password");
1138
G_CONST_RETURN char *
1139
vino_server_get_vnc_password (VinoServer *server)
1141
g_return_val_if_fail (VINO_IS_SERVER (server), NULL);
1143
return server->priv->vnc_password;