~andrew-bugs-launchpad-net/remote-help-assistant/0.2

« back to all changes in this revision

Viewing changes to share/remote-help-assistant/vnc_interaction.py

  • Committer: Andrew Sayers
  • Date: 2009-04-08 12:09:23 UTC
  • Revision ID: andrew-bazaar@pileofstuff.org-20090408120923-517pl9uswvhxlozf
Started unit testing, removed signature-sending

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
        print >> sys.stderr, misc.now(), "- VNC server", self.__pid, "killed"
82
82
 
83
83
    ## Constructor
84
 
    def __init__(self, append_sockno, cmd, output):
 
84
    def __init__(self, append_sockno, cmd):
85
85
 
86
86
        server, port = misc.listen_sockets('127.0.0.1', 5900, 5920)
87
87
 
95
95
        if self.__pid:
96
96
            two_way_pipe.From_socket.__init__(self, ('127.0.0.1', port), socket.AF_INET)
97
97
            self.write(password) #pylint: disable-msg=I0011,E1101
98
 
            output.write(self.read(12, 1)) #pylint: disable-msg=I0011,E1101
99
98
 
100
99
        else:
101
100
            sock = server.accept()[0]
121
120
 
122
121
## Get a VNC or shell server
123
122
#
 
123
# @param allow_control share control of the desktop?
 
124
# @param force_server (DEBUGGING ONLY) force a specific server to be used
 
125
#
124
126
# This function tries to start the best server that's available, in
125
127
# the appropriate mode.  Servers are tried in this order:
126
128
#
152
154
# should be ignored.  The client speaks first in the RDP protocol,
153
155
# so adding RDP support would mean sending an 'RDP 001.001\\n'
154
156
# message, similar to SHL 001.001.
155
 
def get_server(output, allow_control):
 
157
def get_server(allow_control, force_server=None):
156
158
 
157
159
    # First, try x11vnc.  This is preferred because it makes the least demands on the system (i.e. no KDE and no GNOME)
158
 
    if os.path.exists('/usr/bin/x11vnc'):
 
160
    if (force_server is None or "x11vnc" == force_server) and os.path.exists('/usr/bin/x11vnc'):
159
161
 
160
162
        print >> sys.stderr, misc.now(), "- Trying x11vnc..."
161
163
 
169
171
 
170
172
        print >> sys.stderr, misc.now(), "- Got x11vnc"
171
173
 
172
 
        return 'RFB', From_vnc_server(False, server_command, output)
 
174
        return From_vnc_server(False, server_command)
173
175
 
174
176
    # Second, try to start a krfb session.  This is better than vino because it's easier to start and there's less lag for some reason.
175
 
    if os.path.exists('/usr/bin/krfb'):
 
177
    if (force_server is None or "krfb" == force_server) and os.path.exists('/usr/bin/krfb'):
176
178
 
177
179
        print >> sys.stderr, misc.now(), "- Trying krfb..."
178
180
 
195
197
 
196
198
        krfbrc.close()
197
199
 
198
 
        ret = From_vnc_server(True, ['/usr/bin/krfb', '--config', misc.CONFIG_DIR + '/krfbrc', '--kinetd'], output)
 
200
        ret = From_vnc_server(True, ['/usr/bin/krfb', '--config', misc.CONFIG_DIR + '/krfbrc', '--kinetd'])
199
201
        os.remove(misc.CONFIG_DIR + '/krfbrc')
200
202
 
201
203
        print >> sys.stderr, misc.now(), "- Got krfb"
202
204
 
203
 
        return 'RFB', ret
204
 
 
205
 
    # Try to start a vino session.  This is the final option because it can't be started on the command-line,
206
 
    # and (as of 12 July 2008) only supports IPv6
207
 
    try:
208
 
        print >> sys.stderr, misc.now(), "- Trying vino..."
209
 
 
210
 
        import gconf
211
 
        gconf_client = gconf.client_get_default()
212
 
 
213
 
        vino_info = (
214
 
            gconf_client.get('/desktop/gnome/remote_access/enabled'),
215
 
            gconf_client.get('/desktop/gnome/remote_access/local_only'),
216
 
            gconf_client.get('/desktop/gnome/remote_access/prompt_enabled'),
217
 
            gconf_client.get('/desktop/gnome/remote_access/view_only'),
218
 
            gconf_client.get('/desktop/gnome/remote_access/require_encryption'),
219
 
            gconf_client.get('/desktop/gnome/remote_access/lock_screen_on_disconnect'),
220
 
            gconf_client.get('/desktop/gnome/remote_access/authentication_methods'),
221
 
            gconf_client.get('/desktop/gnome/remote_access/use_alternative_port')
222
 
            )
223
 
 
224
 
        n = gconf.Value('string')
225
 
        n.set_string('none')
226
 
        lst = gconf.Value('list')
227
 
        lst.set_list_type('string')
228
 
        lst.set_list([n])
229
 
        gconf_client.set_bool('/desktop/gnome/remote_access/local_only', True)
230
 
        gconf_client.set_bool('/desktop/gnome/remote_access/prompt_enabled', False)
231
 
        gconf_client.set_bool('/desktop/gnome/remote_access/view_only', not allow_control)
232
 
        gconf_client.set_bool('/desktop/gnome/remote_access/require_encryption', False)
233
 
        gconf_client.set_bool('/desktop/gnome/remote_access/lock_screen_on_disconnect', False)
234
 
        gconf_client.set     ('/desktop/gnome/remote_access/authentication_methods', lst)
235
 
        gconf_client.set_bool('/desktop/gnome/remote_access/enabled', True)
236
 
        gconf_client.set_bool('/desktop/gnome/remote_access/use_alternative_port', False)
237
 
 
238
 
        # vino has a bad habit of listening on IPv6 only, and can take a while to start up
239
 
        count = 0
240
 
        sock = None
241
 
        while sock is None and count < 4:
242
 
            count = count + 1
243
 
            try:
244
 
                sock = From_vino('127.0.0.1', socket.AF_INET, vino_info)
245
 
            except socket.error:
 
205
        return ret
 
206
 
 
207
    if force_server is None or "vino" == force_server:
 
208
        # Try to start a vino session.  This is the final option because it can't be started on the command-line,
 
209
        # and (as of 12 July 2008) only supports IPv6
 
210
        try:
 
211
            print >> sys.stderr, misc.now(), "- Trying vino..."
 
212
 
 
213
            import gconf
 
214
            gconf_client = gconf.client_get_default()
 
215
 
 
216
            vino_info = (
 
217
                gconf_client.get('/desktop/gnome/remote_access/enabled'),
 
218
                gconf_client.get('/desktop/gnome/remote_access/local_only'),
 
219
                gconf_client.get('/desktop/gnome/remote_access/prompt_enabled'),
 
220
                gconf_client.get('/desktop/gnome/remote_access/view_only'),
 
221
                gconf_client.get('/desktop/gnome/remote_access/require_encryption'),
 
222
                gconf_client.get('/desktop/gnome/remote_access/lock_screen_on_disconnect'),
 
223
                gconf_client.get('/desktop/gnome/remote_access/authentication_methods'),
 
224
                gconf_client.get('/desktop/gnome/remote_access/use_alternative_port')
 
225
                )
 
226
 
 
227
            n = gconf.Value('string')
 
228
            n.set_string('none')
 
229
            lst = gconf.Value('list')
 
230
            lst.set_list_type('string')
 
231
            lst.set_list([n])
 
232
            gconf_client.set_bool('/desktop/gnome/remote_access/local_only', True)
 
233
            gconf_client.set_bool('/desktop/gnome/remote_access/prompt_enabled', False)
 
234
            gconf_client.set_bool('/desktop/gnome/remote_access/view_only', not allow_control)
 
235
            gconf_client.set_bool('/desktop/gnome/remote_access/require_encryption', False)
 
236
            gconf_client.set_bool('/desktop/gnome/remote_access/lock_screen_on_disconnect', False)
 
237
            gconf_client.set     ('/desktop/gnome/remote_access/authentication_methods', lst)
 
238
            gconf_client.set_bool('/desktop/gnome/remote_access/enabled', True)
 
239
            gconf_client.set_bool('/desktop/gnome/remote_access/use_alternative_port', False)
 
240
 
 
241
            # vino has a bad habit of listening on IPv6 only, and can take a while to start up
 
242
            count = 0
 
243
            sock = None
 
244
            while sock is None and count < 4:
 
245
                count = count + 1
246
246
                try:
247
 
                    sock = From_vino('::1', socket.AF_INET6, vino_info)
 
247
                    sock = From_vino('127.0.0.1', socket.AF_INET, vino_info)
248
248
                except socket.error:
249
 
                    time.sleep(1)
250
 
 
251
 
        if sock:
252
 
            output.write(sock.read(12, 1)) #pylint: disable-msg=I0011,E1101
253
 
 
254
 
            # In case anybody tries to ride in on our coat-tails
255
 
            # Note: at the time of writing, this doesn't work.
256
 
            # Hopefully, future vinos will use the prompt_enabled
257
 
            # setting from when the connection was established.
258
 
            gconf_client.set_bool('/desktop/gnome/remote_access/prompt_enabled', True)
259
 
 
260
 
            print >> sys.stderr, misc.now(), "- Got vino"
261
 
 
262
 
            return 'RFB', sock
263
 
        else:
264
 
            print >> sys.stderr, misc.now(), "- Failed to start vino:", sys.exc_info()[0]
265
 
            gconf_client.set('/desktop/gnome/remote_access/enabled', vino_info[0])
266
 
            gconf_client.set('/desktop/gnome/remote_access/local_only', vino_info[1])
267
 
            gconf_client.set('/desktop/gnome/remote_access/prompt_enabled', vino_info[2])
268
 
            gconf_client.set('/desktop/gnome/remote_access/view_only', vino_info[3])
269
 
            gconf_client.set('/desktop/gnome/remote_access/require_encryption', vino_info[4])
270
 
            gconf_client.set('/desktop/gnome/remote_access/lock_screen_on_disconnect', vino_info[5])
271
 
            gconf_client.set('/desktop/gnome/remote_access/authentication_methods', vino_info[6])
272
 
            gconf_client.set('/desktop/gnome/remote_access/use_alternative_port', vino_info[7])
273
 
 
274
 
    except:
275
 
        if misc.DEBUG:
276
 
            print >> sys.stderr, misc.now(), "- Failed to start vino:", sys.exc_info()[0]
 
249
                    try:
 
250
                        sock = From_vino('::1', socket.AF_INET6, vino_info)
 
251
                    except socket.error:
 
252
                        time.sleep(1)
 
253
 
 
254
            if sock:
 
255
                # In case anybody tries to ride in on our coat-tails
 
256
                # Note: at the time of writing, this doesn't work.
 
257
                # Hopefully, future vinos will use the prompt_enabled
 
258
                # setting from when the connection was established.
 
259
                gconf_client.set_bool('/desktop/gnome/remote_access/prompt_enabled', True)
 
260
 
 
261
                print >> sys.stderr, misc.now(), "- Got vino"
 
262
 
 
263
                return sock
 
264
            else:
 
265
                print >> sys.stderr, misc.now(), "- Failed to start vino:", sys.exc_info()[0]
 
266
                gconf_client.set('/desktop/gnome/remote_access/enabled', vino_info[0])
 
267
                gconf_client.set('/desktop/gnome/remote_access/local_only', vino_info[1])
 
268
                gconf_client.set('/desktop/gnome/remote_access/prompt_enabled', vino_info[2])
 
269
                gconf_client.set('/desktop/gnome/remote_access/view_only', vino_info[3])
 
270
                gconf_client.set('/desktop/gnome/remote_access/require_encryption', vino_info[4])
 
271
                gconf_client.set('/desktop/gnome/remote_access/lock_screen_on_disconnect', vino_info[5])
 
272
                gconf_client.set('/desktop/gnome/remote_access/authentication_methods', vino_info[6])
 
273
                gconf_client.set('/desktop/gnome/remote_access/use_alternative_port', vino_info[7])
 
274
 
 
275
        except:
 
276
            if misc.DEBUG:
 
277
                print >> sys.stderr, misc.now(), "- Failed to start vino:", sys.exc_info()[0]
277
278
 
278
279
    return None
279
280
 
280
281
## Get a VNC or shell client
281
282
#
282
 
# This function is the counterpart to get_server().  It reads the
283
 
# signature sent by get_server(), and sets a client up
284
 
# accordingly.
285
 
def get_client(signature):
 
283
# This function is the counterpart to get_server().
 
284
def get_client():
286
285
    try:
287
 
        if misc.DEBUG:
288
 
            print >> sys.stderr, misc.now(), "- Session type: {", signature, "}"
289
 
 
290
 
        if 'RFB ' == signature[0:4]:
291
 
            sock = None
292
 
 
293
 
            while sock is None:
294
 
                sock, port = misc.listen_sockets('127.0.0.1', 5900, 5920)
295
 
 
296
 
            return 'RFB', sock, str(port)
297
 
 
298
 
        else: # Unknown connection type
299
 
            if misc.DEBUG > 1:
300
 
                print >> sys.stderr, misc.now(), "- Unknown connection type:", signature
301
 
            return False, None, ''
 
286
        sock = None
 
287
 
 
288
        while sock is None:
 
289
            sock, port = misc.listen_sockets('127.0.0.1', 5900, 5920)
 
290
 
 
291
        return sock, str(port)
302
292
 
303
293
    except:
304
294
        print >> sys.stderr, misc.now(), "- Unexpected error, stack trace follows"