~ubuntu-branches/ubuntu/precise/virtualbox/precise-updates

« back to all changes in this revision

Viewing changes to src/VBox/RDP/client/rdesktop.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-07-04 13:02:31 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110704130231-l843es6wqhx614n7
Tags: 4.0.10-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Add the Modaliases control field manually for maximum backportability.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- c-basic-offset: 8 -*-
2
2
   rdesktop: A Remote Desktop Protocol client.
3
3
   Entrypoint and utility functions
4
 
   Copyright (C) Matthew Chapman 1999-2008
 
4
   Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
 
5
   Copyright 2002-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
 
6
   Copyright 2010-2011 Henrik Andersson <hean01@cendio.se> for Cendio AB
5
7
 
6
 
   This program is free software; you can redistribute it and/or modify
 
8
   This program is free software: you can redistribute it and/or modify
7
9
   it under the terms of the GNU General Public License as published by
8
 
   the Free Software Foundation; either version 2 of the License, or
 
10
   the Free Software Foundation, either version 3 of the License, or
9
11
   (at your option) any later version.
10
12
 
11
13
   This program is distributed in the hope that it will be useful,
14
16
   GNU General Public License for more details.
15
17
 
16
18
   You should have received a copy of the GNU General Public License
17
 
   along with this program; if not, write to the Free Software
18
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20
*/
20
21
 
21
22
/*
37
38
#include <sys/times.h>          /* times */
38
39
#include <ctype.h>              /* toupper */
39
40
#include <errno.h>
 
41
#include <signal.h>
40
42
#include "rdesktop.h"
41
43
 
42
44
#ifdef VBOX
62
64
#include "ssl.h"
63
65
 
64
66
char g_title[64] = "";
65
 
char g_username[64];
 
67
char *g_username;
66
68
char g_hostname[16];
67
69
char g_keymapname[PATH_MAX] = "";
68
70
unsigned int g_keylayout = 0x409;       /* Defaults to US keyboard layout */
69
71
int g_keyboard_type = 0x4;      /* Defaults to US keyboard layout */
70
72
int g_keyboard_subtype = 0x0;   /* Defaults to US keyboard layout */
71
73
int g_keyboard_functionkeys = 0xc;      /* Defaults to US keyboard layout */
72
 
 
73
 
int g_width = 800;              /* width is special: If 0, the
74
 
                                   geometry will be fetched from
75
 
                                   _NET_WORKAREA. If negative,
76
 
                                   absolute value specifies the
77
 
                                   percent of the whole screen. */
 
74
int g_sizeopt = 0;              /* If non-zero, a special size has been
 
75
                                   requested. If 1, the geometry will be fetched
 
76
                                   from _NET_WORKAREA. If negative, absolute value
 
77
                                   specifies the percent of the whole screen. */
 
78
int g_width = 800;
78
79
int g_height = 600;
79
80
int g_xpos = 0;
80
81
int g_ypos = 0;
110
111
RD_BOOL g_owncolmap = False;
111
112
RD_BOOL g_ownbackstore = True;  /* We can't rely on external BackingStore */
112
113
RD_BOOL g_seamless_rdp = False;
 
114
RD_BOOL g_user_quit = False;
113
115
uint32 g_embed_wnd;
114
116
uint32 g_rdp5_performanceflags =
115
117
        RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
118
120
char g_redirect_server[64];
119
121
char g_redirect_domain[16];
120
122
char g_redirect_password[64];
121
 
char g_redirect_username[64];
 
123
char *g_redirect_username;
122
124
char g_redirect_cookie[128];
123
125
uint32 g_redirect_flags = 0;
124
126
 
 
127
uint32 g_reconnect_logonid = 0;
 
128
char g_reconnect_random[16];
 
129
RD_BOOL g_has_reconnect_random = False;
 
130
uint8 g_client_random[SEC_RANDOM_SIZE];
 
131
RD_BOOL g_pending_resize = False;
 
132
 
125
133
#ifdef WITH_RDPSND
126
134
RD_BOOL g_rdpsnd = False;
127
135
#endif
150
158
usage(char *program)
151
159
{
152
160
        fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
153
 
        fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2008 Matthew Chapman.\n");
 
161
        fprintf(stderr,
 
162
                "Version " PACKAGE_VERSION ". Copyright (C) 1999-2011 Matthew Chapman et al.\n");
154
163
#ifdef VBOX
155
 
        fprintf(stderr, "Modified for VirtualBox by " VBOX_VENDOR "\n");
 
164
        fprintf(stderr, "Modified for VirtualBox by " VBOX_VENDOR "\n");
156
165
#endif
157
166
        fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
158
167
 
243
252
        fprintf(stderr, "   -5: use RDP version 5 (default)\n");
244
253
}
245
254
 
246
 
static void
247
 
print_disconnect_reason(uint16 reason)
 
255
static int
 
256
handle_disconnect_reason(RD_BOOL deactivated, uint16 reason)
248
257
{
249
258
        char *text;
 
259
        int retval;
250
260
 
251
261
        switch (reason)
252
262
        {
253
263
                case exDiscReasonNoInfo:
254
264
                        text = "No information available";
 
265
                        if (deactivated)
 
266
                                retval = EX_OK;
 
267
                        else
 
268
                                retval = EXRD_UNKNOWN;
255
269
                        break;
256
270
 
257
271
                case exDiscReasonAPIInitiatedDisconnect:
 
272
                case exDiscReasonWindows7Disconnect:
258
273
                        text = "Server initiated disconnect";
 
274
                        retval = EXRD_API_DISCONNECT;
259
275
                        break;
260
276
 
261
277
                case exDiscReasonAPIInitiatedLogoff:
262
278
                        text = "Server initiated logoff";
 
279
                        retval = EXRD_API_LOGOFF;
263
280
                        break;
264
281
 
265
282
                case exDiscReasonServerIdleTimeout:
266
283
                        text = "Server idle timeout reached";
 
284
                        retval = EXRD_IDLE_TIMEOUT;
267
285
                        break;
268
286
 
269
287
                case exDiscReasonServerLogonTimeout:
270
288
                        text = "Server logon timeout reached";
 
289
                        retval = EXRD_LOGON_TIMEOUT;
271
290
                        break;
272
291
 
273
292
                case exDiscReasonReplacedByOtherConnection:
274
293
                        text = "The session was replaced";
 
294
                        retval = EXRD_REPLACED;
275
295
                        break;
276
296
 
277
297
                case exDiscReasonOutOfMemory:
278
298
                        text = "The server is out of memory";
 
299
                        retval = EXRD_OUT_OF_MEM;
279
300
                        break;
280
301
 
281
302
                case exDiscReasonServerDeniedConnection:
282
303
                        text = "The server denied the connection";
 
304
                        retval = EXRD_DENIED;
283
305
                        break;
284
306
 
285
307
                case exDiscReasonServerDeniedConnectionFips:
286
308
                        text = "The server denied the connection for security reason";
 
309
                        retval = EXRD_DENIED_FIPS;
287
310
                        break;
288
311
 
289
312
                case exDiscReasonLicenseInternal:
290
313
                        text = "Internal licensing error";
 
314
                        retval = EXRD_LIC_INTERNAL;
291
315
                        break;
292
316
 
293
317
                case exDiscReasonLicenseNoLicenseServer:
294
318
                        text = "No license server available";
 
319
                        retval = EXRD_LIC_NOSERVER;
295
320
                        break;
296
321
 
297
322
                case exDiscReasonLicenseNoLicense:
298
323
                        text = "No valid license available";
 
324
                        retval = EXRD_LIC_NOLICENSE;
299
325
                        break;
300
326
 
301
327
                case exDiscReasonLicenseErrClientMsg:
302
328
                        text = "Invalid licensing message";
 
329
                        retval = EXRD_LIC_MSG;
303
330
                        break;
304
331
 
305
332
                case exDiscReasonLicenseHwidDoesntMatchLicense:
306
333
                        text = "Hardware id doesn't match software license";
 
334
                        retval = EXRD_LIC_HWID;
307
335
                        break;
308
336
 
309
337
                case exDiscReasonLicenseErrClientLicense:
310
338
                        text = "Client license error";
 
339
                        retval = EXRD_LIC_CLIENT;
311
340
                        break;
312
341
 
313
342
                case exDiscReasonLicenseCantFinishProtocol:
314
343
                        text = "Network error during licensing protocol";
 
344
                        retval = EXRD_LIC_NET;
315
345
                        break;
316
346
 
317
347
                case exDiscReasonLicenseClientEndedProtocol:
318
348
                        text = "Licensing protocol was not completed";
 
349
                        retval = EXRD_LIC_PROTO;
319
350
                        break;
320
351
 
321
352
                case exDiscReasonLicenseErrClientEncryption:
322
353
                        text = "Incorrect client license enryption";
 
354
                        retval = EXRD_LIC_ENC;
323
355
                        break;
324
356
 
325
357
                case exDiscReasonLicenseCantUpgradeLicense:
326
358
                        text = "Can't upgrade license";
 
359
                        retval = EXRD_LIC_UPGRADE;
327
360
                        break;
328
361
 
329
362
                case exDiscReasonLicenseNoRemoteConnections:
330
363
                        text = "The server is not licensed to accept remote connections";
 
364
                        retval = EXRD_LIC_NOREMOTE;
331
365
                        break;
332
366
 
333
367
                default:
339
373
                        {
340
374
                                text = "Unknown reason";
341
375
                        }
 
376
                        retval = EXRD_UNKNOWN;
342
377
        }
343
 
        fprintf(stderr, "disconnect: %s.\n", text);
 
378
        if (reason != exDiscReasonNoInfo)
 
379
                fprintf(stderr, "disconnect: %s.\n", text);
 
380
 
 
381
        return retval;
344
382
}
345
383
 
346
384
static void
347
385
rdesktop_reset_state(void)
348
386
{
349
387
        rdp_reset_state();
 
388
#ifdef WITH_SCARD
 
389
        scard_reset_state();
 
390
#endif
 
391
#ifdef WITH_RDPSND
 
392
        rdpsnd_reset_state();
 
393
#endif
350
394
}
351
395
 
352
396
static RD_BOOL
447
491
{
448
492
        char server[64];
449
493
        char fullhostname[64];
450
 
        char domain[16];
 
494
        char domain[256];
451
495
        char password[64];
452
496
        char shell[256];
453
497
        char directory[256];
459
503
        char *locale = NULL;
460
504
        int username_option = 0;
461
505
        RD_BOOL geometry_option = False;
462
 
        int run_count = 0;      /* Session Directory support */
463
 
        RD_BOOL continue_connect = True;        /* Session Directory support */
464
506
#ifdef WITH_RDPSND
465
507
        char *rdpsnd_optarg = NULL;
466
508
#endif
474
516
        }
475
517
 
476
518
#endif
 
519
 
 
520
        /* Ignore SIGPIPE, since we are using popen() */
 
521
        struct sigaction act;
 
522
        memset(&act, 0, sizeof(act));
 
523
        act.sa_handler = SIG_IGN;
 
524
        sigemptyset(&act.sa_mask);
 
525
        act.sa_flags = 0;
 
526
        sigaction(SIGPIPE, &act, NULL);
 
527
 
477
528
        flags = RDP_LOGON_NORMAL;
478
529
        prompt_password = False;
479
530
        domain[0] = password[0] = shell[0] = directory[0] = 0;
511
562
                                break;
512
563
 
513
564
                        case 'u':
514
 
                                STRNCPY(g_username, optarg, sizeof(g_username));
 
565
                                g_username = (char *) xmalloc(strlen(optarg) + 1);
 
566
                                STRNCPY(g_username, optarg, strlen(optarg) + 1);
515
567
                                username_option = 1;
516
568
                                break;
517
569
 
564
616
                                g_fullscreen = False;
565
617
                                if (!strcmp(optarg, "workarea"))
566
618
                                {
567
 
                                        g_width = g_height = 0;
 
619
                                        g_sizeopt = 1;
568
620
                                        break;
569
621
                                }
570
622
 
572
624
                                if (g_width <= 0)
573
625
                                {
574
626
                                        error("invalid geometry\n");
575
 
                                        return 1;
 
627
                                        return EX_USAGE;
576
628
                                }
577
629
 
578
630
                                if (*p == 'x')
581
633
                                if (g_height <= 0)
582
634
                                {
583
635
                                        error("invalid geometry\n");
584
 
                                        return 1;
 
636
                                        return EX_USAGE;
585
637
                                }
586
638
 
587
639
                                if (*p == '%')
588
640
                                {
589
 
                                        g_width = -g_width;
 
641
                                        g_sizeopt = -g_width;
 
642
                                        g_width = 800;
590
643
                                        p++;
591
644
                                }
592
645
 
650
703
                                if (*p)
651
704
                                {
652
705
                                        error("invalid button size\n");
653
 
                                        return 1;
 
706
                                        return EX_USAGE;
654
707
                                }
655
708
 
656
709
                                break;
675
728
                                    && g_server_depth != 32)
676
729
                                {
677
730
                                        error("Invalid server colour depth.\n");
678
 
                                        return 1;
 
731
                                        return EX_USAGE;
679
732
                                }
680
733
                                break;
681
734
 
834
887
                        case '?':
835
888
                        default:
836
889
                                usage(argv[0]);
837
 
                                return 1;
 
890
                                return EX_USAGE;
838
891
                }
839
892
        }
840
893
 
841
894
        if (argc - optind != 1)
842
895
        {
843
896
                usage(argv[0]);
844
 
                return 1;
 
897
                return EX_USAGE;
845
898
        }
846
899
 
847
900
        STRNCPY(server, argv[optind], sizeof(server));
852
905
                if (g_win_button_size)
853
906
                {
854
907
                        error("You cannot use -S and -A at the same time\n");
855
 
                        return 1;
 
908
                        return EX_USAGE;
856
909
                }
857
910
                g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
858
911
                if (geometry_option)
859
912
                {
860
913
                        error("You cannot use -g and -A at the same time\n");
861
 
                        return 1;
 
914
                        return EX_USAGE;
862
915
                }
863
916
                if (g_fullscreen)
864
917
                {
865
918
                        error("You cannot use -f and -A at the same time\n");
866
 
                        return 1;
 
919
                        return EX_USAGE;
867
920
                }
868
921
                if (g_hide_decorations)
869
922
                {
870
923
                        error("You cannot use -D and -A at the same time\n");
871
 
                        return 1;
 
924
                        return EX_USAGE;
872
925
                }
873
926
                if (g_embed_wnd)
874
927
                {
875
928
                        error("You cannot use -X and -A at the same time\n");
876
 
                        return 1;
 
929
                        return EX_USAGE;
877
930
                }
878
931
                if (!g_use_rdp5)
879
932
                {
880
933
                        error("You cannot use -4 and -A at the same time\n");
881
 
                        return 1;
 
934
                        return EX_USAGE;
882
935
                }
883
 
                g_width = -100;
 
936
                g_sizeopt = -100;
884
937
                g_grab_keyboard = False;
885
938
        }
886
939
 
890
943
                if ((pw == NULL) || (pw->pw_name == NULL))
891
944
                {
892
945
                        error("could not determine username, use -u\n");
893
 
                        return 1;
 
946
                        return EX_OSERR;
894
947
                }
895
 
 
896
 
                STRNCPY(g_username, pw->pw_name, sizeof(g_username));
 
948
                /* +1 for trailing \0 */
 
949
                int pwlen = strlen(pw->pw_name) + 1;
 
950
                g_username = (char *) xmalloc(pwlen);
 
951
                STRNCPY(g_username, pw->pw_name, pwlen);
897
952
        }
898
953
 
899
954
#ifdef HAVE_ICONV
915
970
                if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
916
971
                {
917
972
                        error("could not determine local hostname, use -n\n");
918
 
                        return 1;
 
973
                        return EX_OSERR;
919
974
                }
920
975
 
921
976
                p = strchr(fullhostname, '.');
951
1006
 
952
1007
#ifdef RDP2VNC
953
1008
        rdp2vnc_connect(server, flags, domain, password, shell, directory);
954
 
        return 0;
 
1009
        return EX_OK;
955
1010
#else
956
1011
 
957
1012
        if (!ui_init())
958
 
                return 1;
 
1013
                return EX_OSERR;
959
1014
 
960
1015
#ifdef WITH_RDPSND
961
1016
        if (g_rdpsnd)
962
1017
        {
963
1018
                if (!rdpsnd_init(rdpsnd_optarg))
964
 
                {
965
1019
                        warning("Initializing sound-support failed!\n");
966
 
                }
967
1020
        }
968
1021
#endif
969
1022
 
977
1030
 
978
1031
        rdpdr_init();
979
1032
 
980
 
        while (run_count < 2 && continue_connect)       /* add support for Session Directory; only reconnect once */
 
1033
        while (1)
981
1034
        {
982
 
                if (run_count == 0)
 
1035
                rdesktop_reset_state();
 
1036
 
 
1037
                if (g_redirect)
983
1038
                {
984
 
                        if (!rdp_connect(server, flags, domain, password, shell, directory))
985
 
                                return 1;
 
1039
                        STRNCPY(domain, g_redirect_domain, sizeof(domain));
 
1040
                        xfree(g_username);
 
1041
                        g_username = (char *) xmalloc(strlen(g_redirect_username) + 1);
 
1042
                        STRNCPY(g_username, g_redirect_username, sizeof(g_username));
 
1043
                        STRNCPY(password, g_redirect_password, sizeof(password));
 
1044
                        STRNCPY(server, g_redirect_server, sizeof(server));
 
1045
                        flags |= RDP_LOGON_AUTO;
986
1046
                }
987
 
                else if (!rdp_reconnect
988
 
                         (server, flags, domain, password, shell, directory, g_redirect_cookie))
989
 
                        return 1;
 
1047
 
 
1048
                ui_init_connection();
 
1049
                if (!rdp_connect(server, flags, domain, password, shell, directory, g_redirect))
 
1050
                        return EX_PROTOCOL;
990
1051
 
991
1052
                /* By setting encryption to False here, we have an encrypted login 
992
1053
                   packet but unencrypted transfer of other packets */
997
1058
                DEBUG(("Connection successful.\n"));
998
1059
                memset(password, 0, sizeof(password));
999
1060
 
1000
 
                if (run_count == 0)
 
1061
                if (!g_redirect)
1001
1062
                        if (!ui_create_window())
1002
 
                                continue_connect = False;
 
1063
                                return EX_OSERR;
1003
1064
 
1004
 
                if (continue_connect)
1005
 
                        rdp_main_loop(&deactivated, &ext_disc_reason);
 
1065
                g_redirect = False;
 
1066
                rdp_main_loop(&deactivated, &ext_disc_reason);
1006
1067
 
1007
1068
                DEBUG(("Disconnecting...\n"));
1008
1069
                rdp_disconnect();
1009
1070
 
1010
 
                if ((g_redirect == True) && (run_count == 0))   /* Support for Session Directory */
1011
 
                {
1012
 
                        /* reset state of major globals */
1013
 
                        rdesktop_reset_state();
1014
 
 
1015
 
                        STRNCPY(domain, g_redirect_domain, sizeof(domain));
1016
 
                        STRNCPY(g_username, g_redirect_username, sizeof(g_username));
1017
 
                        STRNCPY(password, g_redirect_password, sizeof(password));
1018
 
                        STRNCPY(server, g_redirect_server, sizeof(server));
1019
 
                        flags |= RDP_LOGON_AUTO;
1020
 
 
1021
 
                        g_redirect = False;
1022
 
                }
1023
 
                else
1024
 
                {
1025
 
                        continue_connect = False;
1026
 
                        ui_destroy_window();
1027
 
                        break;
1028
 
                }
1029
 
 
1030
 
                run_count++;
 
1071
                if (g_redirect)
 
1072
                        continue;
 
1073
 
 
1074
                ui_seamless_end();
 
1075
                ui_destroy_window();
 
1076
                if (g_pending_resize)
 
1077
                {
 
1078
                        /* If we have a pending resize, reconnect using the new size, rather than exit */
 
1079
                        g_pending_resize = False;
 
1080
                        continue;
 
1081
                }
 
1082
                break;
1031
1083
        }
1032
1084
 
1033
1085
        cache_save_state();
1034
1086
        ui_deinit();
1035
1087
 
1036
1088
#ifdef WITH_RDPUSB
1037
 
        if (g_rdpusb)
1038
 
                rdpusb_close();
1039
 
#endif
1040
 
 
1041
 
        if (ext_disc_reason >= 2)
1042
 
                print_disconnect_reason(ext_disc_reason);
1043
 
 
1044
 
        if (deactivated)
1045
 
        {
1046
 
                /* clean disconnect */
1047
 
                return 0;
1048
 
        }
1049
 
        else
1050
 
        {
1051
 
                if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
1052
 
                    || ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
1053
 
                {
1054
 
                        /* not so clean disconnect, but nothing to worry about */
1055
 
                        return 0;
1056
 
                }
1057
 
                else
1058
 
                {
1059
 
                        /* return error */
1060
 
                        return 2;
1061
 
                }
1062
 
        }
1063
 
 
1064
 
#endif
1065
 
 
 
1089
        if (g_rdpusb)
 
1090
                rdpusb_close();
 
1091
#endif
 
1092
 
 
1093
        if (g_user_quit)
 
1094
                return EXRD_WINDOW_CLOSED;
 
1095
 
 
1096
        return handle_disconnect_reason(deactivated, ext_disc_reason);
 
1097
 
 
1098
#endif
 
1099
        if (g_redirect_username)
 
1100
                xfree(g_redirect_username);
 
1101
 
 
1102
        xfree(g_username);
1066
1103
}
1067
1104
 
1068
1105
#ifdef EGD_SOCKET
1156
1193
        if (mem == NULL)
1157
1194
        {
1158
1195
                error("xmalloc %d\n", size);
1159
 
                exit(1);
 
1196
                exit(EX_UNAVAILABLE);
1160
1197
        }
1161
1198
        return mem;
1162
1199
}
1168
1205
        if (ptr == NULL)
1169
1206
        {
1170
1207
                error("unexpected null pointer. Out of memory?\n");
1171
 
                exit(1);
 
1208
                exit(EX_UNAVAILABLE);
1172
1209
        }
1173
1210
}
1174
1211
 
1180
1217
        if (mem == NULL)
1181
1218
        {
1182
1219
                perror("strdup");
1183
 
                exit(1);
 
1220
                exit(EX_UNAVAILABLE);
1184
1221
        }
1185
1222
        return mem;
1186
1223
}
1197
1234
        if (mem == NULL)
1198
1235
        {
1199
1236
                error("xrealloc %ld\n", size);
1200
 
                exit(1);
 
1237
                exit(EX_UNAVAILABLE);
1201
1238
        }
1202
1239
        return mem;
1203
1240
}