~ubuntu-branches/debian/stretch/rdesktop/stretch

« back to all changes in this revision

Viewing changes to iso.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Johnston
  • Date: 2004-02-04 17:52:26 UTC
  • Revision ID: james.westby@ubuntu.com-20040204175226-87kz4bzs1nimji68
Tags: upstream-1.3.1
ImportĀ upstreamĀ versionĀ 1.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- c-basic-offset: 8 -*-
 
2
   rdesktop: A Remote Desktop Protocol client.
 
3
   Protocol services - ISO layer
 
4
   Copyright (C) Matthew Chapman 1999-2002
 
5
   
 
6
   This program is free software; you can redistribute it and/or modify
 
7
   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
 
9
   (at your option) any later version.
 
10
   
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
   
 
16
   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
*/
 
20
 
 
21
#include "rdesktop.h"
 
22
 
 
23
/* Send a self-contained ISO PDU */
 
24
static void
 
25
iso_send_msg(uint8 code)
 
26
{
 
27
        STREAM s;
 
28
 
 
29
        s = tcp_init(11);
 
30
 
 
31
        out_uint8(s, 3);        /* version */
 
32
        out_uint8(s, 0);        /* reserved */
 
33
        out_uint16_be(s, 11);   /* length */
 
34
 
 
35
        out_uint8(s, 6);        /* hdrlen */
 
36
        out_uint8(s, code);
 
37
        out_uint16(s, 0);       /* dst_ref */
 
38
        out_uint16(s, 0);       /* src_ref */
 
39
        out_uint8(s, 0);        /* class */
 
40
 
 
41
        s_mark_end(s);
 
42
        tcp_send(s);
 
43
}
 
44
 
 
45
static void
 
46
iso_send_connection_request(char *username)
 
47
{
 
48
        STREAM s;
 
49
        int length = 30 + strlen(username);
 
50
 
 
51
        s = tcp_init(length);
 
52
 
 
53
        out_uint8(s, 3);        /* version */
 
54
        out_uint8(s, 0);        /* reserved */
 
55
        out_uint16_be(s, length);       /* length */
 
56
 
 
57
        out_uint8(s, length - 5);       /* hdrlen */
 
58
        out_uint8(s, ISO_PDU_CR);
 
59
        out_uint16(s, 0);       /* dst_ref */
 
60
        out_uint16(s, 0);       /* src_ref */
 
61
        out_uint8(s, 0);        /* class */
 
62
 
 
63
        out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash="));
 
64
        out_uint8p(s, username, strlen(username));
 
65
 
 
66
        out_uint8(s, 0x0d);     /* Unknown */
 
67
        out_uint8(s, 0x0a);     /* Unknown */
 
68
 
 
69
        s_mark_end(s);
 
70
        tcp_send(s);
 
71
}
 
72
 
 
73
/* Receive a message on the ISO layer, return code */
 
74
static STREAM
 
75
iso_recv_msg(uint8 * code)
 
76
{
 
77
        STREAM s;
 
78
        uint16 length;
 
79
        uint8 version;
 
80
 
 
81
      next_packet:
 
82
        s = tcp_recv(NULL, 4);
 
83
        if (s == NULL)
 
84
                return NULL;
 
85
 
 
86
        in_uint8(s, version);
 
87
        switch (version & 3)
 
88
        {
 
89
                case 0:
 
90
                        in_uint8(s, length);
 
91
                        if (length & 0x80)
 
92
                        {
 
93
                                length &= ~0x80;
 
94
                                next_be(s, length);
 
95
                        }
 
96
                        break;
 
97
 
 
98
                case 3:
 
99
                        in_uint8s(s, 1);        /* pad */
 
100
                        in_uint16_be(s, length);
 
101
                        break;
 
102
 
 
103
                default:
 
104
                        error("TPKT v%d\n", version);
 
105
                        return NULL;
 
106
        }
 
107
 
 
108
        s = tcp_recv(s, length - 4);
 
109
        if (s == NULL)
 
110
                return NULL;
 
111
 
 
112
        if ((version & 3) == 0)
 
113
        {
 
114
                rdp5_process(s, version & 0x80);
 
115
                goto next_packet;
 
116
        }
 
117
 
 
118
        in_uint8s(s, 1);        /* hdrlen */
 
119
        in_uint8(s, *code);
 
120
 
 
121
        if (*code == ISO_PDU_DT)
 
122
        {
 
123
                in_uint8s(s, 1);        /* eot */
 
124
                return s;
 
125
        }
 
126
 
 
127
        in_uint8s(s, 5);        /* dst_ref, src_ref, class */
 
128
        return s;
 
129
}
 
130
 
 
131
/* Initialise ISO transport data packet */
 
132
STREAM
 
133
iso_init(int length)
 
134
{
 
135
        STREAM s;
 
136
 
 
137
        s = tcp_init(length + 7);
 
138
        s_push_layer(s, iso_hdr, 7);
 
139
 
 
140
        return s;
 
141
}
 
142
 
 
143
/* Send an ISO data PDU */
 
144
void
 
145
iso_send(STREAM s)
 
146
{
 
147
        uint16 length;
 
148
 
 
149
        s_pop_layer(s, iso_hdr);
 
150
        length = s->end - s->p;
 
151
 
 
152
        out_uint8(s, 3);        /* version */
 
153
        out_uint8(s, 0);        /* reserved */
 
154
        out_uint16_be(s, length);
 
155
 
 
156
        out_uint8(s, 2);        /* hdrlen */
 
157
        out_uint8(s, ISO_PDU_DT);       /* code */
 
158
        out_uint8(s, 0x80);     /* eot */
 
159
 
 
160
        tcp_send(s);
 
161
}
 
162
 
 
163
/* Receive ISO transport data packet */
 
164
STREAM
 
165
iso_recv(void)
 
166
{
 
167
        STREAM s;
 
168
        uint8 code;
 
169
 
 
170
        s = iso_recv_msg(&code);
 
171
        if (s == NULL)
 
172
                return NULL;
 
173
 
 
174
        if (code != ISO_PDU_DT)
 
175
        {
 
176
                error("expected DT, got 0x%x\n", code);
 
177
                return NULL;
 
178
        }
 
179
 
 
180
        return s;
 
181
}
 
182
 
 
183
/* Establish a connection up to the ISO layer */
 
184
BOOL
 
185
iso_connect(char *server, char *username)
 
186
{
 
187
        uint8 code;
 
188
 
 
189
        if (!tcp_connect(server))
 
190
                return False;
 
191
 
 
192
        iso_send_connection_request(username);
 
193
 
 
194
        if (iso_recv_msg(&code) == NULL)
 
195
                return False;
 
196
 
 
197
        if (code != ISO_PDU_CC)
 
198
        {
 
199
                error("expected CC, got 0x%x\n", code);
 
200
                tcp_disconnect();
 
201
                return False;
 
202
        }
 
203
 
 
204
        return True;
 
205
}
 
206
 
 
207
/* Disconnect from the ISO layer */
 
208
void
 
209
iso_disconnect(void)
 
210
{
 
211
        iso_send_msg(ISO_PDU_DR);
 
212
        tcp_disconnect();
 
213
}