~ubuntu-branches/ubuntu/vivid/gtk-vnc/vivid-proposed

« back to all changes in this revision

Viewing changes to src/vncconnection.c

  • Committer: Package Import Robot
  • Author(s): Laurent Léonard
  • Date: 2012-07-24 00:49:55 UTC
  • mfrom: (1.2.5)
  • Revision ID: package-import@ubuntu.com-20120724004955-6711f7ontxvn9yzy
Tags: 0.5.1-1
* [e2591bf] Imported Upstream version 0.5.1
* [a0f6408] Drop patch
  - Allow-Unix-domain-sockets-in-gvncviewer.patch - fixed upstream
* [c031b94] Bump Standards-Version to 3.9.3
* [61e5796] Set build directories for dh_auto_clean
* [7fde78d] Drop patch
  - Look-for-generated-enums-in-srcdir.patch
* [fada5be] Add dh_auto_test override
* [d7567f1] Update symbols
* [6189676] Enable dpkg-buildflags

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
#include <gnutls/x509.h>
45
45
#include <gdk-pixbuf/gdk-pixbuf.h>
46
46
 
47
 
#if HAVE_SASL
 
47
#ifdef HAVE_SASL
48
48
#include <sasl/sasl.h>
49
49
#endif
50
50
 
56
56
 
57
57
#include "dh.h"
58
58
 
 
59
#if GLIB_CHECK_VERSION(2, 31, 0)
 
60
#define g_mutex_new() g_new0(GMutex, 1)
 
61
#define g_mutex_free(m) g_free(m)
 
62
#endif
 
63
 
59
64
struct wait_queue
60
65
{
61
66
    gboolean waiting;
62
67
    struct coroutine *context;
63
68
};
64
69
 
 
70
typedef enum {
 
71
    VNC_CONNECTION_SERVER_MESSAGE_FRAMEBUFFER_UPDATE = 0,
 
72
    VNC_CONNECTION_SERVER_MESSAGE_SET_COLOR_MAP_ENTRIES = 1,
 
73
    VNC_CONNECTION_SERVER_MESSAGE_BELL = 2,
 
74
    VNC_CONNECTION_SERVER_MESSAGE_SERVER_CUT_TEXT = 3,
 
75
    VNC_CONNECTION_SERVER_MESSAGE_QEMU = 255,
 
76
} VncConnectionServerMessage;
 
77
 
 
78
typedef enum {
 
79
    VNC_CONNECTION_SERVER_MESSAGE_QEMU_AUDIO = 1,
 
80
} VncConnectionServerMessageQEMU;
 
81
 
 
82
typedef enum {
 
83
    VNC_CONNECTION_SERVER_MESSAGE_QEMU_AUDIO_STOP = 0,
 
84
    VNC_CONNECTION_SERVER_MESSAGE_QEMU_AUDIO_START = 1,
 
85
    VNC_CONNECTION_SERVER_MESSAGE_QEMU_AUDIO_DATA = 2,
 
86
} VncConnectionServerMessageQEMUAudio;
 
87
 
 
88
 
 
89
typedef enum {
 
90
    VNC_CONNECTION_CLIENT_MESSAGE_SET_PIXEL_FORMAT = 0,
 
91
    VNC_CONNECTION_CLIENT_MESSAGE_SET_ENCODINGS = 2,
 
92
    VNC_CONNECTION_CLIENT_MESSAGE_FRAMEBUFFER_UPDATE_REQUEST = 3,
 
93
    VNC_CONNECTION_CLIENT_MESSAGE_KEY = 4,
 
94
    VNC_CONNECTION_CLIENT_MESSAGE_POINTER = 5,
 
95
    VNC_CONNECTION_CLIENT_MESSAGE_CUT_TEXT = 6,
 
96
    VNC_CONNECTION_CLIENT_MESSAGE_QEMU = 255,
 
97
} VncConnectionClientMessage;
 
98
 
 
99
typedef enum {
 
100
    VNC_CONNECTION_CLIENT_MESSAGE_QEMU_KEY = 0,
 
101
    VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO = 1,
 
102
} VncConnectionClientMessageQEMU;
 
103
 
 
104
typedef enum {
 
105
    VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO_ENABLE = 0,
 
106
    VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO_DISABLE = 1,
 
107
    VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO_SET_FORMAT = 2,
 
108
} VncConnectionClientMessageQEMUAudio;
 
109
 
65
110
 
66
111
typedef void vnc_connection_rich_cursor_blt_func(VncConnection *conn, guint8 *, guint8 *,
67
112
                                                 guint8 *, int, guint16, guint16);
101
146
    struct coroutine coroutine;
102
147
    guint open_id;
103
148
    GSocket *sock;
 
149
    GSocketAddress *addr;
104
150
    int fd;
105
151
    char *host;
106
152
    char *port;
127
173
    gboolean want_cred_password;
128
174
    gboolean want_cred_x509;
129
175
 
130
 
#if HAVE_SASL
 
176
#ifdef HAVE_SASL
131
177
    sasl_conn_t *saslconn;      /* SASL context */
132
178
    const char *saslDecoded;
133
179
    unsigned int saslDecodedLength;
522
568
                      signals[data->signum],
523
569
                      0);
524
570
        break;
 
571
 
 
572
    default:
 
573
        g_warn_if_reached();
525
574
    }
526
575
 
527
576
    coroutine_yieldto(data->caller, NULL);
672
721
}
673
722
 
674
723
 
675
 
#if HAVE_SASL
 
724
#ifdef HAVE_SASL
676
725
/*
677
726
 * Read at least 1 more byte of data out of the SASL decrypted
678
727
 * data buffer, into the internal read buffer
685
734
    //VNC_DEBUG("Read SASL %p size %d offset %d", priv->saslDecoded,
686
735
    //           priv->saslDecodedLength, priv->saslDecodedOffset);
687
736
    if (priv->saslDecoded == NULL) {
688
 
        char encoded[8192];
689
 
        int encodedLen = sizeof(encoded);
 
737
        char *encoded;
 
738
        int encodedLen;
690
739
        int err, ret;
691
740
 
 
741
        encodedLen = 8192;
 
742
        encoded = g_new0(char, encodedLen);
 
743
 
692
744
        ret = vnc_connection_read_wire(conn, encoded, encodedLen);
693
745
        if (ret < 0) {
 
746
            g_free(encoded);
694
747
            return ret;
695
748
        }
696
749
 
697
750
        err = sasl_decode(priv->saslconn, encoded, ret,
698
751
                          &priv->saslDecoded, &priv->saslDecodedLength);
 
752
        g_free(encoded);
699
753
        if (err != SASL_OK) {
700
754
            VNC_DEBUG("Failed to decode SASL data %s",
701
755
                      sasl_errstring(err, NULL, NULL));
740
794
 */
741
795
static int vnc_connection_read_buf(VncConnection *conn)
742
796
{
743
 
#if HAVE_SASL
 
797
#ifdef HAVE_SASL
744
798
    VncConnectionPrivate *priv = conn->priv;
745
799
 
746
800
    //VNC_DEBUG("Start read %d", priv->has_error);
859
913
}
860
914
 
861
915
 
862
 
#if HAVE_SASL
 
916
#ifdef HAVE_SASL
863
917
/*
864
918
 * Encode all buffered data, write all encrypted data out
865
919
 * to the wire
908
962
    VncConnectionPrivate *priv = conn->priv;
909
963
 
910
964
    //VNC_DEBUG("Start flush write %d", priv->has_error);
911
 
#if HAVE_SASL
 
965
#ifdef HAVE_SASL
912
966
    if (priv->saslconn)
913
967
        vnc_connection_flush_sasl(conn);
914
968
    else
1470
1524
    VncConnectionPrivate *priv = conn->priv;
1471
1525
    guint8 pad[3] = {0};
1472
1526
 
1473
 
    vnc_connection_buffered_write_u8(conn, 0);
 
1527
    vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_SET_PIXEL_FORMAT);
1474
1528
    vnc_connection_buffered_write(conn, pad, 3);
1475
1529
 
1476
1530
    vnc_connection_buffered_write_u8(conn, fmt->bits_per_pixel);
1514
1568
{
1515
1569
    VncConnectionPrivate *priv = conn->priv;
1516
1570
 
1517
 
    vnc_connection_buffered_write_u8(conn,  255);
1518
 
    vnc_connection_buffered_write_u8(conn,  1); /* VNC_CONNECTION_QEMU_AUDIO */
1519
 
    vnc_connection_buffered_write_u16(conn, 2); /* VNC_CONNECTION_QEMU_AUDIO_SET_FORMAT */
 
1571
    vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU);
 
1572
    vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO);
 
1573
    vnc_connection_buffered_write_u16(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO_SET_FORMAT);
1520
1574
 
1521
1575
    vnc_connection_buffered_write_u8(conn,  priv->audio_format.format);
1522
1576
    vnc_connection_buffered_write_u8(conn,  priv->audio_format.nchannels);
1553
1607
 
1554
1608
    if (priv->has_audio)
1555
1609
        {
1556
 
            vnc_connection_buffered_write_u8(conn,  255); /* QEMU message */
1557
 
            vnc_connection_buffered_write_u8(conn,  1);   /* VNC_CONNECTION_QEMU_AUDIO */
1558
 
            vnc_connection_buffered_write_u16(conn, 0);   /* VNC_CONNECTION_QEMU_AUDIO_ENABLE */
 
1610
            vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU);
 
1611
            vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO);
 
1612
            vnc_connection_buffered_write_u16(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO_ENABLE);
1559
1613
            vnc_connection_buffered_flush(conn);
1560
1614
            priv->audio_enable_pending=FALSE;
1561
1615
        }
1571
1625
 
1572
1626
    if (priv->has_audio)
1573
1627
        {
1574
 
            vnc_connection_buffered_write_u8(conn,  255); /* QEMU message */
1575
 
            vnc_connection_buffered_write_u8(conn,  1);   /* VNC_CONNECTION_QEMU_AUDIO */
1576
 
            vnc_connection_buffered_write_u16(conn, 1);  /* VNC_CONNECTION_QEMU_AUDIO_ENABLE */
 
1628
            vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU);
 
1629
            vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO);
 
1630
            vnc_connection_buffered_write_u16(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU_AUDIO_DISABLE);
1577
1631
            vnc_connection_buffered_flush(conn);
1578
1632
            priv->audio_disable_pending=FALSE;
1579
1633
        }
1613
1667
 
1614
1668
    priv->has_ext_key_event = FALSE;
1615
1669
    priv->has_audio = FALSE;
1616
 
    vnc_connection_buffered_write_u8(conn, 2);
 
1670
    vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_SET_ENCODINGS);
1617
1671
    vnc_connection_buffered_write(conn, pad, 1);
1618
1672
    vnc_connection_buffered_write_u16(conn, n_encoding - skip_zrle);
1619
1673
    for (i = 0; i < n_encoding; i++) {
1642
1696
    priv->lastUpdateRequest.width = width;
1643
1697
    priv->lastUpdateRequest.height = height;
1644
1698
 
1645
 
    vnc_connection_buffered_write_u8(conn, 3);
 
1699
    vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_FRAMEBUFFER_UPDATE_REQUEST);
1646
1700
    vnc_connection_buffered_write_u8(conn, incremental ? 1 : 0);
1647
1701
    vnc_connection_buffered_write_u16(conn, x);
1648
1702
    vnc_connection_buffered_write_u16(conn, y);
1670
1724
              priv->lastUpdateRequest.height,
1671
1725
              (int)priv->lastUpdateRequest.incremental);
1672
1726
 
1673
 
    vnc_connection_write_u8(conn, 3);
 
1727
    vnc_connection_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_FRAMEBUFFER_UPDATE_REQUEST);
1674
1728
    vnc_connection_write_u8(conn, priv->lastUpdateRequest.incremental ? 1 : 0);
1675
1729
    vnc_connection_write_u16(conn, priv->lastUpdateRequest.x);
1676
1730
    vnc_connection_write_u16(conn, priv->lastUpdateRequest.y);
1690
1744
 
1691
1745
    VNC_DEBUG("Key event %d %d %d Extended: %d", key, scancode, down_flag, priv->has_ext_key_event);
1692
1746
    if (priv->has_ext_key_event) {
1693
 
        vnc_connection_buffered_write_u8(conn, 255);
1694
 
        vnc_connection_buffered_write_u8(conn, 0);
 
1747
        vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU);
 
1748
        vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_QEMU_KEY);
1695
1749
        vnc_connection_buffered_write_u16(conn, down_flag ? 1 : 0);
1696
1750
        vnc_connection_buffered_write_u32(conn, key);
1697
1751
        vnc_connection_buffered_write_u32(conn, scancode);
1698
1752
    } else {
1699
 
        vnc_connection_buffered_write_u8(conn, 4);
 
1753
        vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_KEY);
1700
1754
        vnc_connection_buffered_write_u8(conn, down_flag ? 1 : 0);
1701
1755
        vnc_connection_buffered_write(conn, pad, 2);
1702
1756
        vnc_connection_buffered_write_u32(conn, key);
1709
1763
gboolean vnc_connection_pointer_event(VncConnection *conn, guint8 button_mask,
1710
1764
                                      guint16 x, guint16 y)
1711
1765
{
1712
 
    vnc_connection_buffered_write_u8(conn, 5);
 
1766
    vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_POINTER);
1713
1767
    vnc_connection_buffered_write_u8(conn, button_mask);
1714
1768
    vnc_connection_buffered_write_u16(conn, x);
1715
1769
    vnc_connection_buffered_write_u16(conn, y);
1722
1776
{
1723
1777
    guint8 pad[3] = {0};
1724
1778
 
1725
 
    vnc_connection_buffered_write_u8(conn, 6);
 
1779
    vnc_connection_buffered_write_u8(conn, VNC_CONNECTION_CLIENT_MESSAGE_CUT_TEXT);
1726
1780
    vnc_connection_buffered_write(conn, pad, 3);
1727
1781
    vnc_connection_buffered_write_u32(conn, length);
1728
1782
    vnc_connection_buffered_write(conn, data, length);
2037
2091
                                                 guint16 width, guint16 height)
2038
2092
{
2039
2093
    VncConnectionPrivate *priv = conn->priv;
2040
 
    guint8 blit_data[4 * 64 * 64];
 
2094
    guint8 *blit_data;
2041
2095
    int i, bpp;
2042
2096
 
 
2097
    blit_data = g_new0(guint8, 4*64*64);
 
2098
 
2043
2099
    bpp = vnc_connection_pixel_size(conn);
2044
2100
 
2045
2101
    for (i = 0; i < width * height; i++)
2046
2102
        vnc_connection_read_cpixel(conn, blit_data + (i * bpp));
2047
2103
 
2048
2104
    vnc_framebuffer_blt(priv->fb, blit_data, width * bpp, x, y, width, height);
 
2105
 
 
2106
    g_free(blit_data);
2049
2107
}
2050
2108
 
2051
2109
static guint8 vnc_connection_read_zrle_pi(VncConnection *conn, int palette_size)
2623
2681
    VncConnectionPrivate *priv = conn->priv;
2624
2682
    struct signal_data sigdata;
2625
2683
 
 
2684
    VNC_DEBUG("Pointer mode %s", absPointer ? "absolute" : "relative");
 
2685
 
2626
2686
    if (priv->absPointer == absPointer)
2627
2687
        return;
2628
2688
    priv->absPointer = absPointer;
2745
2805
{
2746
2806
    VncConnectionPrivate *priv = conn->priv;
2747
2807
 
 
2808
    VNC_DEBUG("Keyboard mode extended");
2748
2809
    priv->has_ext_key_event = TRUE;
2749
2810
}
2750
2811
 
2838
2899
        vnc_connection_resend_framebuffer_update_request(conn);
2839
2900
        break;
2840
2901
    case VNC_CONNECTION_ENCODING_AUDIO:
 
2902
        VNC_DEBUG("Audio encoding support");
2841
2903
        priv->has_audio=TRUE;
2842
2904
 
2843
2905
        if (priv->audio_disable_pending)
2881
2943
{
2882
2944
    VncConnection *conn;
2883
2945
    struct coroutine *caller;
2884
 
    int action;
 
2946
    enum {
 
2947
        VNC_AUDIO_PLAYBACK_STOP = 0,
 
2948
        VNC_AUDIO_PLAYBACK_START = 1,
 
2949
        VNC_AUDIO_PLAYBACK_DATA = 2,
 
2950
    } action;
2885
2951
};
2886
2952
 
2887
2953
static gboolean do_vnc_connection_audio_action(gpointer opaque)
2892
2958
    VNC_DEBUG("Audio action main context %d", data->action);
2893
2959
 
2894
2960
    switch (data->action) {
2895
 
    case 0:
 
2961
    case VNC_AUDIO_PLAYBACK_STOP:
2896
2962
        vnc_audio_playback_stop(priv->audio);
2897
2963
        break;
2898
 
    case 1:
 
2964
    case VNC_AUDIO_PLAYBACK_START:
2899
2965
        vnc_audio_playback_start(priv->audio, &priv->audio_format);
2900
2966
        break;
2901
 
    case 2:
 
2967
    case VNC_AUDIO_PLAYBACK_DATA:
2902
2968
        vnc_audio_playback_data(priv->audio, priv->audio_sample);
2903
2969
        break;
 
2970
    default:
 
2971
        g_warn_if_reached();
2904
2972
    }
2905
2973
 
2906
2974
    coroutine_yieldto(data->caller, NULL);
2956
3024
    }
2957
3025
 
2958
3026
    switch (msg) {
2959
 
    case 0: { /* FramebufferUpdate */
 
3027
    case VNC_CONNECTION_SERVER_MESSAGE_FRAMEBUFFER_UPDATE: {
2960
3028
        guint8 pad[1];
2961
3029
        guint16 n_rects;
2962
3030
        int i;
2977
3045
                break;
2978
3046
        }
2979
3047
    }        break;
2980
 
    case 1: { /* SetColorMapEntries */
 
3048
    case VNC_CONNECTION_SERVER_MESSAGE_SET_COLOR_MAP_ENTRIES: {
2981
3049
        guint16 first_color;
2982
3050
        guint16 n_colors;
2983
3051
        guint8 pad[1];
3007
3075
        vnc_framebuffer_set_color_map(priv->fb, map);
3008
3076
        vnc_color_map_free(map);
3009
3077
    }        break;
3010
 
    case 2: /* Bell */
 
3078
    case VNC_CONNECTION_SERVER_MESSAGE_BELL:
3011
3079
        vnc_connection_bell(conn);
3012
3080
        break;
3013
 
    case 3: { /* ServerCutText */
 
3081
    case VNC_CONNECTION_SERVER_MESSAGE_SERVER_CUT_TEXT: {
3014
3082
        guint8 pad[3];
3015
3083
        guint32 n_text;
3016
3084
        char *data;
3036
3104
        vnc_connection_server_cut_text(conn, data, n_text);
3037
3105
        g_free(data);
3038
3106
    }        break;
3039
 
    case 255: { /* QEMU Messages */
 
3107
    case VNC_CONNECTION_SERVER_MESSAGE_QEMU: {
3040
3108
        guint8  n_type;
3041
3109
 
3042
3110
        n_type = vnc_connection_read_u8(conn);
3045
3113
            break;
3046
3114
 
3047
3115
        switch (n_type) {
3048
 
        case 1: { /* QEMU audio */
 
3116
        case VNC_CONNECTION_SERVER_MESSAGE_QEMU_AUDIO: {
3049
3117
            guint16 n_subtype;
3050
3118
            guint32 n_length;
3051
3119
 
3052
3120
            n_subtype = vnc_connection_read_u16(conn);
3053
3121
            switch (n_subtype) {
3054
 
            case 2:
 
3122
            case VNC_CONNECTION_SERVER_MESSAGE_QEMU_AUDIO_DATA:
3055
3123
                n_length = vnc_connection_read_u32(conn);
3056
3124
                if (n_length > (1024*1024)) {
3057
3125
                    VNC_DEBUG("Received audio message that is too large %u", n_length);
3073
3141
                            priv->audio_sample->capacity,
3074
3142
                            priv->audio_sample->length,
3075
3143
                            n_length);
3076
 
                    vnc_connection_audio_action(conn, 2);
 
3144
                    vnc_connection_audio_action(conn, VNC_AUDIO_PLAYBACK_DATA);
3077
3145
                    vnc_audio_sample_free(priv->audio_sample);
3078
3146
                    priv->audio_sample = NULL;
3079
3147
                }
3089
3157
                                    n_length);
3090
3158
                priv->audio_sample->length += n_length;
3091
3159
                break;
3092
 
            case 1:
 
3160
            case VNC_CONNECTION_SERVER_MESSAGE_QEMU_AUDIO_START:
3093
3161
                if (priv->audio)
3094
 
                    vnc_connection_audio_action(conn, 1);
 
3162
                    vnc_connection_audio_action(conn, VNC_AUDIO_PLAYBACK_START);
3095
3163
                else
3096
3164
                    priv->has_error = TRUE;
3097
3165
                break;
3098
 
            case 0:
 
3166
            case VNC_CONNECTION_SERVER_MESSAGE_QEMU_AUDIO_STOP:
3099
3167
                if (priv->audio) {
3100
3168
                    if (priv->audio_sample) {
3101
3169
                        g_source_remove(priv->audio_timer);
3102
 
                        vnc_connection_audio_action(conn, 2);
 
3170
                        vnc_connection_audio_action(conn, VNC_AUDIO_PLAYBACK_DATA);
3103
3171
                        vnc_audio_sample_free(priv->audio_sample);
3104
3172
                        priv->audio_sample = NULL;
3105
3173
                    }
3106
 
                    vnc_connection_audio_action(conn, 0);
 
3174
                    vnc_connection_audio_action(conn, VNC_AUDIO_PLAYBACK_STOP);
3107
3175
                } else {
3108
3176
                    priv->has_error = TRUE;
3109
3177
                }
3489
3557
}
3490
3558
 
3491
3559
 
3492
 
#if HAVE_SASL
 
3560
#ifdef HAVE_SASL
3493
3561
/*
3494
3562
 * NB, keep in sync with similar method in qemud/remote.c
3495
3563
 */
3564
3632
            interact[ninteract].len = strlen(priv->cred_password);
3565
3633
            //VNC_DEBUG("Gather Password %s", priv->cred_password);
3566
3634
            break;
 
3635
 
 
3636
        default:
 
3637
            g_warn_if_reached();
3567
3638
        }
3568
3639
    }
3569
3640
 
3607
3678
 */
3608
3679
 
3609
3680
#define SASL_MAX_MECHLIST_LEN 300
3610
 
#define SASL_MAX_MECHNAME_LEN 100
3611
3681
#define SASL_MAX_DATA_LEN (1024 * 1024)
3612
3682
 
3613
3683
/* Perform the SASL authentication process
4181
4251
        return TRUE;
4182
4252
    case VNC_CONNECTION_AUTH_VNC:
4183
4253
        return vnc_connection_perform_auth_vnc(conn);
4184
 
#if HAVE_SASL
 
4254
#ifdef HAVE_SASL
4185
4255
    case VNC_CONNECTION_AUTH_SASL:
4186
4256
        return vnc_connection_perform_auth_sasl(conn);
4187
4257
#endif
4247
4317
    if (!vnc_connection_gather_credentials(conn))
4248
4318
        return FALSE;
4249
4319
 
4250
 
#if !DEBUG
 
4320
#ifndef DEBUG
4251
4321
    if (priv->auth_subtype == VNC_CONNECTION_AUTH_VENCRYPT_PLAIN) {
4252
4322
        VNC_DEBUG("Cowardly refusing to transmit plain text password");
4253
4323
        return FALSE;
4292
4362
        VNC_DEBUG("Handing off to VNC auth");
4293
4363
        return vnc_connection_perform_auth_vnc(conn);
4294
4364
 
4295
 
#if HAVE_SASL
 
4365
#ifdef HAVE_SASL
4296
4366
        /* SASL layered over TLS */
4297
4367
    case VNC_CONNECTION_AUTH_VENCRYPT_TLSSASL:
4298
4368
    case VNC_CONNECTION_AUTH_VENCRYPT_X509SASL:
4383
4453
    case VNC_CONNECTION_AUTH_VENCRYPT:
4384
4454
        return vnc_connection_perform_auth_vencrypt(conn);
4385
4455
 
4386
 
#if HAVE_SASL
 
4456
#ifdef HAVE_SASL
4387
4457
    case VNC_CONNECTION_AUTH_SASL:
4388
4458
        return vnc_connection_perform_auth_sasl(conn);
4389
4459
#endif
4657
4727
        gnutls_bye(priv->tls_session, GNUTLS_SHUT_RDWR);
4658
4728
        priv->tls_session = NULL;
4659
4729
    }
4660
 
#if HAVE_SASL
 
4730
#ifdef HAVE_SASL
4661
4731
    if (priv->saslconn) {
4662
4732
        sasl_dispose (&priv->saslconn);
4663
4733
        priv->saslconn = NULL;
4669
4739
        g_object_unref(priv->sock);
4670
4740
        priv->sock = NULL;
4671
4741
    }
 
4742
    if (priv->addr) {
 
4743
        g_object_unref(priv->addr);
 
4744
        priv->addr = NULL;
 
4745
    }
4672
4746
    if (priv->fd != -1)
4673
4747
        priv->fd = -1;
4674
4748
 
4780
4854
        return TRUE;
4781
4855
    if (priv->host)
4782
4856
        return TRUE;
 
4857
    if (priv->addr)
 
4858
        return TRUE;
4783
4859
    return FALSE;
4784
4860
}
4785
4861
 
4946
5022
    return sock;
4947
5023
}
4948
5024
 
 
5025
static gboolean vnc_connection_open_addr_internal(VncConnection *conn)
 
5026
{
 
5027
    VncConnectionPrivate *priv = conn->priv;
 
5028
    GError *conn_error = NULL;
 
5029
    GSocket *sock = NULL;
 
5030
 
 
5031
    VNC_DEBUG("Connecting with addr %p", priv->addr);
 
5032
 
 
5033
    sock = vnc_connection_connect_socket(priv->addr, &conn_error);
 
5034
    g_clear_error(&conn_error);
 
5035
    if (sock) {
 
5036
        priv->sock = sock;
 
5037
        return TRUE;
 
5038
    }
 
5039
    return FALSE;
 
5040
}
 
5041
 
 
5042
 
4949
5043
static gboolean vnc_connection_open_host_internal(VncConnection *conn)
4950
5044
{
4951
5045
    VncConnectionPrivate *priv = conn->priv;
5012
5106
    if (priv->fd != -1) {
5013
5107
        if (!vnc_connection_open_fd_internal(conn))
5014
5108
            goto cleanup;
 
5109
    } else if (priv->addr != NULL) {
 
5110
        if (!vnc_connection_open_addr_internal(conn))
 
5111
            goto cleanup;
5015
5112
    } else {
5016
5113
        if (!vnc_connection_open_host_internal(conn))
5017
5114
            goto cleanup;
5062
5159
 
5063
5160
gboolean vnc_connection_open_fd(VncConnection *conn, int fd)
5064
5161
{
 
5162
    return vnc_connection_open_fd_with_hostname(conn, fd, NULL);
 
5163
}
 
5164
 
 
5165
 
 
5166
gboolean vnc_connection_open_fd_with_hostname(VncConnection *conn, int fd, const char *hostname)
 
5167
{
5065
5168
    VncConnectionPrivate *priv = conn->priv;
5066
5169
 
5067
5170
    VNC_DEBUG("Open fd=%d", fd);
5070
5173
        return FALSE;
5071
5174
 
5072
5175
    priv->fd = fd;
5073
 
    priv->host = NULL;
5074
 
    priv->port = NULL;
 
5176
    priv->addr = NULL;
 
5177
    priv->host = g_strdup(hostname ? hostname : "localhost");
 
5178
    priv->port = g_strdup("");
5075
5179
 
5076
5180
    g_object_ref(G_OBJECT(conn)); /* Unref'd when co-routine exits */
5077
5181
    priv->open_id = g_idle_add(do_vnc_connection_open, conn);
5079
5183
    return TRUE;
5080
5184
}
5081
5185
 
 
5186
 
5082
5187
gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const char *port)
5083
5188
{
5084
5189
    VncConnectionPrivate *priv = conn->priv;
5089
5194
        return FALSE;
5090
5195
 
5091
5196
    priv->fd = -1;
 
5197
    priv->addr = NULL;
5092
5198
    priv->host = g_strdup(host);
5093
5199
    priv->port = g_strdup(port);
5094
5200
 
5098
5204
    return TRUE;
5099
5205
}
5100
5206
 
 
5207
gboolean vnc_connection_open_addr(VncConnection *conn, GSocketAddress *addr, const char *hostname)
 
5208
{
 
5209
    VncConnectionPrivate *priv = conn->priv;
 
5210
 
 
5211
    VNC_DEBUG("Open addr=%p", addr);
 
5212
 
 
5213
    if (vnc_connection_is_open(conn))
 
5214
        return FALSE;
 
5215
 
 
5216
    priv->fd = -1;
 
5217
    priv->addr = g_object_ref(addr);
 
5218
 
 
5219
    priv->host = g_strdup(hostname ? hostname : "localhost");
 
5220
    if (G_IS_INET_SOCKET_ADDRESS(addr)) {
 
5221
        guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(addr));
 
5222
        priv->port = g_strdup_printf("%d", (int)port);
 
5223
    } else {
 
5224
        priv->port = g_strdup("");
 
5225
    }
 
5226
 
 
5227
    g_object_ref(G_OBJECT(conn)); /* Unref'd when co-routine exits */
 
5228
    priv->open_id = g_idle_add(do_vnc_connection_open, conn);
 
5229
 
 
5230
    return TRUE;
 
5231
}
 
5232
 
5101
5233
 
5102
5234
gboolean vnc_connection_set_auth_type(VncConnection *conn, unsigned int type)
5103
5235
{