~paulliu/ubuntu/quantal/freerdp/fixext

« back to all changes in this revision

Viewing changes to libfreerdp-core/nego.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2012-01-31 10:02:14 UTC
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: package-import@ubuntu.com-20120131100214-zvig71djj2sqgq22
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol Client
 
3
 * RDP Protocol Security Negotiation
 
4
 *
 
5
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
6
 *
 
7
 * Licensed under the Apache License, Version 2.0 (the "License");
 
8
 * you may not use this file except in compliance with the License.
 
9
 * You may obtain a copy of the License at
 
10
 *
 
11
 *     http://www.apache.org/licenses/LICENSE-2.0
 
12
 *
 
13
 * Unless required by applicable law or agreed to in writing, software
 
14
 * distributed under the License is distributed on an "AS IS" BASIS,
 
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
16
 * See the License for the specific language governing permissions and
 
17
 * limitations under the License.
 
18
 */
 
19
 
 
20
#include <stdio.h>
 
21
#include <string.h>
 
22
 
 
23
#include <freerdp/constants.h>
 
24
#include <freerdp/utils/memory.h>
 
25
 
 
26
#include "tpkt.h"
 
27
 
 
28
#include "nego.h"
 
29
 
 
30
static const char* const NEGO_STATE_STRINGS[] =
 
31
{
 
32
        "NEGO_STATE_INITIAL",
 
33
        "NEGO_STATE_NLA",
 
34
        "NEGO_STATE_TLS",
 
35
        "NEGO_STATE_RDP",
 
36
        "NEGO_STATE_FAIL",
 
37
        "NEGO_STATE_FINAL"
 
38
};
 
39
 
 
40
static const char PROTOCOL_SECURITY_STRINGS[3][4] =
 
41
{
 
42
        "RDP",
 
43
        "TLS",
 
44
        "NLA"
 
45
};
 
46
 
 
47
/**
 
48
 * Negotiate protocol security and connect.
 
49
 * @param nego
 
50
 * @return
 
51
 */
 
52
 
 
53
boolean nego_connect(rdpNego* nego)
 
54
{
 
55
        if (nego->state == NEGO_STATE_INITIAL)
 
56
        {
 
57
                if (nego->enabled_protocols[PROTOCOL_NLA] > 0)
 
58
                        nego->state = NEGO_STATE_NLA;
 
59
                else if (nego->enabled_protocols[PROTOCOL_TLS] > 0)
 
60
                        nego->state = NEGO_STATE_TLS;
 
61
                else if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
 
62
                        nego->state = NEGO_STATE_RDP;
 
63
                else
 
64
                        nego->state = NEGO_STATE_FAIL;
 
65
        }
 
66
 
 
67
        do
 
68
        {
 
69
                DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]);
 
70
 
 
71
                nego_send(nego);
 
72
 
 
73
                if (nego->state == NEGO_STATE_FAIL)
 
74
                {
 
75
                        DEBUG_NEGO("Protocol Security Negotiation Failure");
 
76
                        nego->state = NEGO_STATE_FINAL;
 
77
                        return false;
 
78
                }
 
79
        }
 
80
        while (nego->state != NEGO_STATE_FINAL);
 
81
 
 
82
        DEBUG_NEGO("Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]);
 
83
 
 
84
        /* update settings with negotiated protocol security */
 
85
        nego->transport->settings->requested_protocols = nego->requested_protocols;
 
86
        nego->transport->settings->selected_protocol = nego->selected_protocol;
 
87
        nego->transport->settings->negotiationFlags = nego->flags;
 
88
 
 
89
        if(nego->selected_protocol == PROTOCOL_RDP)
 
90
        {
 
91
                nego->transport->settings->encryption = true;
 
92
                nego->transport->settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
 
93
                nego->transport->settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
 
94
        }
 
95
 
 
96
        return true;
 
97
}
 
98
 
 
99
/**
 
100
 * Connect TCP layer.
 
101
 * @param nego
 
102
 * @return
 
103
 */
 
104
 
 
105
boolean nego_tcp_connect(rdpNego* nego)
 
106
{
 
107
        if (nego->tcp_connected == 0)
 
108
        {
 
109
                if (transport_connect(nego->transport, nego->hostname, nego->port) == false)
 
110
                {
 
111
                        nego->tcp_connected = 0;
 
112
                        return false;
 
113
                }
 
114
                else
 
115
                {
 
116
                        nego->tcp_connected = 1;
 
117
                        return true;
 
118
                }
 
119
        }
 
120
 
 
121
        return true;
 
122
}
 
123
 
 
124
/**
 
125
 * Disconnect TCP layer.
 
126
 * @param nego
 
127
 * @return
 
128
 */
 
129
 
 
130
int nego_tcp_disconnect(rdpNego* nego)
 
131
{
 
132
        if (nego->tcp_connected)
 
133
                transport_disconnect(nego->transport);
 
134
 
 
135
        nego->tcp_connected = 0;
 
136
        return 1;
 
137
}
 
138
 
 
139
/**
 
140
 * Attempt negotiating NLA + TLS security.
 
141
 * @param nego
 
142
 */
 
143
 
 
144
void nego_attempt_nla(rdpNego* nego)
 
145
{
 
146
        nego->requested_protocols = PROTOCOL_NLA | PROTOCOL_TLS;
 
147
 
 
148
        DEBUG_NEGO("Attempting NLA security");
 
149
 
 
150
        if (!nego_tcp_connect(nego))
 
151
        {
 
152
                nego->state = NEGO_STATE_FAIL;
 
153
                return;
 
154
        }
 
155
 
 
156
        if (!nego_send_negotiation_request(nego))
 
157
        {
 
158
                nego->state = NEGO_STATE_FAIL;
 
159
                return;
 
160
        }
 
161
 
 
162
        if (!nego_recv_response(nego))
 
163
        {
 
164
                nego->state = NEGO_STATE_FAIL;
 
165
                return;
 
166
        }
 
167
 
 
168
        if (nego->state != NEGO_STATE_FINAL)
 
169
        {
 
170
                nego_tcp_disconnect(nego);
 
171
 
 
172
                if (nego->enabled_protocols[PROTOCOL_TLS] > 0)
 
173
                        nego->state = NEGO_STATE_TLS;
 
174
                else if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
 
175
                        nego->state = NEGO_STATE_RDP;
 
176
                else
 
177
                        nego->state = NEGO_STATE_FAIL;
 
178
        }
 
179
}
 
180
 
 
181
/**
 
182
 * Attempt negotiating TLS security.
 
183
 * @param nego
 
184
 */
 
185
 
 
186
void nego_attempt_tls(rdpNego* nego)
 
187
{
 
188
        nego->requested_protocols = PROTOCOL_TLS;
 
189
 
 
190
        DEBUG_NEGO("Attempting TLS security");
 
191
 
 
192
        if (!nego_tcp_connect(nego))
 
193
        {
 
194
                nego->state = NEGO_STATE_FAIL;
 
195
                return;
 
196
        }
 
197
 
 
198
        if (!nego_send_negotiation_request(nego))
 
199
        {
 
200
                nego->state = NEGO_STATE_FAIL;
 
201
                return;
 
202
        }
 
203
 
 
204
        if (!nego_recv_response(nego))
 
205
        {
 
206
                nego->state = NEGO_STATE_FAIL;
 
207
                return;
 
208
        }
 
209
 
 
210
        if (nego->state != NEGO_STATE_FINAL)
 
211
        {
 
212
                nego_tcp_disconnect(nego);
 
213
 
 
214
                if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
 
215
                        nego->state = NEGO_STATE_RDP;
 
216
                else
 
217
                        nego->state = NEGO_STATE_FAIL;
 
218
        }
 
219
}
 
220
 
 
221
/**
 
222
 * Attempt negotiating standard RDP security.
 
223
 * @param nego
 
224
 */
 
225
 
 
226
void nego_attempt_rdp(rdpNego* nego)
 
227
{
 
228
        nego->requested_protocols = PROTOCOL_RDP;
 
229
 
 
230
        DEBUG_NEGO("Attempting RDP security");
 
231
 
 
232
        if (!nego_tcp_connect(nego))
 
233
        {
 
234
                nego->state = NEGO_STATE_FAIL;
 
235
                return;
 
236
        }
 
237
 
 
238
        if (!nego_send_negotiation_request(nego))
 
239
        {
 
240
                nego->state = NEGO_STATE_FAIL;
 
241
                return;
 
242
        }
 
243
 
 
244
        if (!nego_recv_response(nego))
 
245
        {
 
246
                nego->state = NEGO_STATE_FAIL;
 
247
                return;
 
248
        }
 
249
}
 
250
 
 
251
/**
 
252
 * Wait to receive a negotiation response
 
253
 * @param nego
 
254
 */
 
255
 
 
256
boolean nego_recv_response(rdpNego* nego)
 
257
{
 
258
        STREAM* s = transport_recv_stream_init(nego->transport, 1024);
 
259
        if (transport_read(nego->transport, s) < 0)
 
260
                return false;
 
261
        return nego_recv(nego->transport, s, nego->transport->recv_extra);
 
262
}
 
263
 
 
264
/**
 
265
 * Receive protocol security negotiation message.\n
 
266
 * @msdn{cc240501}
 
267
 * @param transport transport
 
268
 * @param s stream
 
269
 * @param extra nego pointer
 
270
 */
 
271
 
 
272
boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra)
 
273
{
 
274
        uint8 li;
 
275
        uint8 type;
 
276
        rdpNego* nego = (rdpNego*) extra;
 
277
 
 
278
        if (tpkt_read_header(s) == 0)
 
279
                return false;
 
280
 
 
281
        li = tpdu_read_connection_confirm(s);
 
282
 
 
283
        if (li > 6)
 
284
        {
 
285
                /* rdpNegData (optional) */
 
286
 
 
287
                stream_read_uint8(s, type); /* Type */
 
288
 
 
289
                switch (type)
 
290
                {
 
291
                        case TYPE_RDP_NEG_RSP:
 
292
                                nego_process_negotiation_response(nego, s);
 
293
                                break;
 
294
 
 
295
                        case TYPE_RDP_NEG_FAILURE:
 
296
                                nego_process_negotiation_failure(nego, s);
 
297
                                break;
 
298
                }
 
299
        }
 
300
        else
 
301
        {
 
302
                nego->state = NEGO_STATE_FINAL;
 
303
        }
 
304
 
 
305
        return true;
 
306
}
 
307
 
 
308
/**
 
309
 * Read protocol security negotiation request message.\n
 
310
 * @param nego
 
311
 * @param s stream
 
312
 */
 
313
 
 
314
boolean nego_read_request(rdpNego* nego, STREAM* s)
 
315
{
 
316
        uint8 li;
 
317
        uint8 c;
 
318
        uint8 type;
 
319
 
 
320
        tpkt_read_header(s);
 
321
        li = tpdu_read_connection_request(s);
 
322
        if (li != stream_get_left(s) + 6)
 
323
        {
 
324
                printf("Incorrect TPDU length indicator.\n");
 
325
                return false;
 
326
        }
 
327
 
 
328
        if (stream_get_left(s) > 8)
 
329
        {
 
330
                /* Optional routingToken or cookie, ending with CR+LF */
 
331
                while (stream_get_left(s) > 0)
 
332
                {
 
333
                        stream_read_uint8(s, c);
 
334
                        if (c != '\x0D')
 
335
                                continue;
 
336
                        stream_peek_uint8(s, c);
 
337
                        if (c != '\x0A')
 
338
                                continue;
 
339
 
 
340
                        stream_seek_uint8(s);
 
341
                        break;
 
342
                }
 
343
        }
 
344
 
 
345
        if (stream_get_left(s) >= 8)
 
346
        {
 
347
                /* rdpNegData (optional) */
 
348
 
 
349
                stream_read_uint8(s, type); /* Type */
 
350
                if (type != TYPE_RDP_NEG_REQ)
 
351
                {
 
352
                        printf("Incorrect negotiation request type %d\n", type);
 
353
                        return false;
 
354
                }
 
355
 
 
356
                nego_process_negotiation_request(nego, s);
 
357
        }
 
358
 
 
359
        return true;
 
360
}
 
361
 
 
362
/**
 
363
 * Send protocol security negotiation message.
 
364
 * @param nego
 
365
 */
 
366
 
 
367
void nego_send(rdpNego* nego)
 
368
{
 
369
        if (nego->state == NEGO_STATE_NLA)
 
370
                nego_attempt_nla(nego);
 
371
        else if (nego->state == NEGO_STATE_TLS)
 
372
                nego_attempt_tls(nego);
 
373
        else if (nego->state == NEGO_STATE_RDP)
 
374
                nego_attempt_rdp(nego);
 
375
        else
 
376
                DEBUG_NEGO("invalid negotiation state for sending");
 
377
}
 
378
 
 
379
/**
 
380
 * Send RDP Negotiation Request (RDP_NEG_REQ).\n
 
381
 * @msdn{cc240500}\n
 
382
 * @msdn{cc240470}
 
383
 * @param nego
 
384
 */
 
385
 
 
386
boolean nego_send_negotiation_request(rdpNego* nego)
 
387
{
 
388
        STREAM* s;
 
389
        int length;
 
390
        uint8 *bm, *em;
 
391
 
 
392
        s = transport_send_stream_init(nego->transport, 256);
 
393
        length = TPDU_CONNECTION_REQUEST_LENGTH;
 
394
        stream_get_mark(s, bm);
 
395
        stream_seek(s, length);
 
396
 
 
397
        if (nego->routing_token != NULL)
 
398
        {
 
399
                stream_write(s, nego->routing_token->data, nego->routing_token->length);
 
400
                length += nego->routing_token->length;
 
401
        }
 
402
        else if (nego->cookie != NULL)
 
403
        {
 
404
                int cookie_length = strlen(nego->cookie);
 
405
                stream_write(s, "Cookie: mstshash=", 17);
 
406
                stream_write(s, (uint8*)nego->cookie, cookie_length);
 
407
                stream_write_uint8(s, 0x0D); /* CR */
 
408
                stream_write_uint8(s, 0x0A); /* LF */
 
409
                length += cookie_length + 19;
 
410
        }
 
411
 
 
412
        if (nego->requested_protocols > PROTOCOL_RDP)
 
413
        {
 
414
                /* RDP_NEG_DATA must be present for TLS and NLA */
 
415
                stream_write_uint8(s, TYPE_RDP_NEG_REQ);
 
416
                stream_write_uint8(s, 0); /* flags, must be set to zero */
 
417
                stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
 
418
                stream_write_uint32(s, nego->requested_protocols); /* requestedProtocols */
 
419
                length += 8;
 
420
        }
 
421
 
 
422
        stream_get_mark(s, em);
 
423
        stream_set_mark(s, bm);
 
424
        tpkt_write_header(s, length);
 
425
        tpdu_write_connection_request(s, length - 5);
 
426
        stream_set_mark(s, em);
 
427
 
 
428
        if (transport_write(nego->transport, s) < 0)
 
429
                return false;
 
430
 
 
431
        return true;
 
432
}
 
433
 
 
434
/**
 
435
 * Process Negotiation Request from Connection Request message.
 
436
 * @param nego
 
437
 * @param s
 
438
 */
 
439
 
 
440
void nego_process_negotiation_request(rdpNego* nego, STREAM* s)
 
441
{
 
442
        uint8 flags;
 
443
        uint16 length;
 
444
 
 
445
        DEBUG_NEGO("RDP_NEG_REQ");
 
446
 
 
447
        stream_read_uint8(s, flags);
 
448
        stream_read_uint16(s, length);
 
449
        stream_read_uint32(s, nego->requested_protocols);
 
450
 
 
451
        nego->state = NEGO_STATE_FINAL;
 
452
}
 
453
 
 
454
/**
 
455
 * Process Negotiation Response from Connection Confirm message.
 
456
 * @param nego
 
457
 * @param s
 
458
 */
 
459
 
 
460
void nego_process_negotiation_response(rdpNego* nego, STREAM* s)
 
461
{
 
462
        uint16 length;
 
463
 
 
464
        DEBUG_NEGO("RDP_NEG_RSP");
 
465
 
 
466
        stream_read_uint8(s, nego->flags);
 
467
        stream_read_uint16(s, length);
 
468
        stream_read_uint32(s, nego->selected_protocol);
 
469
 
 
470
        nego->state = NEGO_STATE_FINAL;
 
471
}
 
472
 
 
473
/**
 
474
 * Process Negotiation Failure from Connection Confirm message.
 
475
 * @param nego
 
476
 * @param s
 
477
 */
 
478
 
 
479
void nego_process_negotiation_failure(rdpNego* nego, STREAM* s)
 
480
{
 
481
        uint8 flags;
 
482
        uint16 length;
 
483
        uint32 failureCode;
 
484
 
 
485
        DEBUG_NEGO("RDP_NEG_FAILURE");
 
486
 
 
487
        stream_read_uint8(s, flags);
 
488
        stream_read_uint16(s, length);
 
489
        stream_read_uint32(s, failureCode);
 
490
 
 
491
        switch (failureCode)
 
492
        {
 
493
                case SSL_REQUIRED_BY_SERVER:
 
494
                        DEBUG_NEGO("Error: SSL_REQUIRED_BY_SERVER");
 
495
                        break;
 
496
                case SSL_NOT_ALLOWED_BY_SERVER:
 
497
                        DEBUG_NEGO("Error: SSL_NOT_ALLOWED_BY_SERVER");
 
498
                        break;
 
499
                case SSL_CERT_NOT_ON_SERVER:
 
500
                        DEBUG_NEGO("Error: SSL_CERT_NOT_ON_SERVER");
 
501
                        break;
 
502
                case INCONSISTENT_FLAGS:
 
503
                        DEBUG_NEGO("Error: INCONSISTENT_FLAGS");
 
504
                        break;
 
505
                case HYBRID_REQUIRED_BY_SERVER:
 
506
                        DEBUG_NEGO("Error: HYBRID_REQUIRED_BY_SERVER");
 
507
                        break;
 
508
                default:
 
509
                        DEBUG_NEGO("Error: Unknown protocol security error %d", failureCode);
 
510
                        break;
 
511
        }
 
512
 
 
513
        nego->state = NEGO_STATE_FAIL;
 
514
}
 
515
 
 
516
/**
 
517
 * Send RDP Negotiation Response (RDP_NEG_RSP).\n
 
518
 * @param nego
 
519
 */
 
520
 
 
521
boolean nego_send_negotiation_response(rdpNego* nego)
 
522
{
 
523
        STREAM* s;
 
524
        int length;
 
525
        uint8 *bm, *em;
 
526
 
 
527
        s = transport_send_stream_init(nego->transport, 256);
 
528
        length = TPDU_CONNECTION_CONFIRM_LENGTH;
 
529
        stream_get_mark(s, bm);
 
530
        stream_seek(s, length);
 
531
 
 
532
        if (nego->selected_protocol > PROTOCOL_RDP)
 
533
        {
 
534
                /* RDP_NEG_DATA must be present for TLS and NLA */
 
535
                stream_write_uint8(s, TYPE_RDP_NEG_RSP);
 
536
                stream_write_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
 
537
                stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
 
538
                stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */
 
539
                length += 8;
 
540
        }
 
541
 
 
542
        stream_get_mark(s, em);
 
543
        stream_set_mark(s, bm);
 
544
        tpkt_write_header(s, length);
 
545
        tpdu_write_connection_confirm(s, length - 5);
 
546
        stream_set_mark(s, em);
 
547
 
 
548
        if (transport_write(nego->transport, s) < 0)
 
549
                return false;
 
550
 
 
551
        /* update settings with negotiated protocol security */
 
552
        nego->transport->settings->requested_protocols = nego->requested_protocols;
 
553
        nego->transport->settings->selected_protocol = nego->selected_protocol;
 
554
 
 
555
        return true;
 
556
}
 
557
 
 
558
/**
 
559
 * Initialize NEGO state machine.
 
560
 * @param nego
 
561
 */
 
562
 
 
563
void nego_init(rdpNego* nego)
 
564
{
 
565
        nego->state = NEGO_STATE_INITIAL;
 
566
        nego->requested_protocols = PROTOCOL_RDP;
 
567
        nego->transport->recv_callback = nego_recv;
 
568
        nego->transport->recv_extra = (void*) nego;
 
569
        nego->flags = 0;
 
570
}
 
571
 
 
572
/**
 
573
 * Create a new NEGO state machine instance.
 
574
 * @param transport
 
575
 * @return
 
576
 */
 
577
 
 
578
rdpNego* nego_new(struct rdp_transport * transport)
 
579
{
 
580
        rdpNego* nego = (rdpNego*) xzalloc(sizeof(rdpNego));
 
581
 
 
582
        if (nego != NULL)
 
583
        {
 
584
                nego->transport = transport;
 
585
                nego_init(nego);
 
586
        }
 
587
 
 
588
        return nego;
 
589
}
 
590
 
 
591
/**
 
592
 * Free NEGO state machine.
 
593
 * @param nego
 
594
 */
 
595
 
 
596
void nego_free(rdpNego* nego)
 
597
{
 
598
        xfree(nego);
 
599
}
 
600
 
 
601
/**
 
602
 * Set target hostname and port.
 
603
 * @param nego
 
604
 * @param hostname
 
605
 * @param port
 
606
 */
 
607
 
 
608
void nego_set_target(rdpNego* nego, char* hostname, int port)
 
609
{
 
610
        nego->hostname = hostname;
 
611
        nego->port = port;
 
612
}
 
613
 
 
614
/**
 
615
 * Enable RDP security protocol.
 
616
 * @param nego pointer to the negotiation structure
 
617
 * @param enable_rdp whether to enable normal RDP protocol (true for enabled, false for disabled)
 
618
 */
 
619
 
 
620
void nego_enable_rdp(rdpNego* nego, boolean enable_rdp)
 
621
{
 
622
        DEBUG_NEGO("Enabling RDP security: %s", enable_rdp ? "true" : "false");
 
623
        nego->enabled_protocols[PROTOCOL_RDP] = enable_rdp;
 
624
}
 
625
 
 
626
/**
 
627
 * Enable TLS security protocol.
 
628
 * @param nego pointer to the negotiation structure
 
629
 * @param enable_tls whether to enable TLS + RDP protocol (true for enabled, false for disabled)
 
630
 */
 
631
void nego_enable_tls(rdpNego* nego, boolean enable_tls)
 
632
{
 
633
        DEBUG_NEGO("Enabling TLS security: %s", enable_tls ? "true" : "false");
 
634
        nego->enabled_protocols[PROTOCOL_TLS] = enable_tls;
 
635
}
 
636
 
 
637
 
 
638
/**
 
639
 * Enable NLA security protocol.
 
640
 * @param nego pointer to the negotiation structure
 
641
 * @param enable_nla whether to enable network level authentication protocol (true for enabled, false for disabled)
 
642
 */
 
643
 
 
644
void nego_enable_nla(rdpNego* nego, boolean enable_nla)
 
645
{
 
646
        DEBUG_NEGO("Enabling NLA security: %s", enable_nla ? "true" : "false");
 
647
        nego->enabled_protocols[PROTOCOL_NLA] = enable_nla;
 
648
}
 
649
 
 
650
/**
 
651
 * Set routing token.
 
652
 * @param nego
 
653
 * @param routing_token
 
654
 */
 
655
 
 
656
void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token)
 
657
{
 
658
        nego->routing_token = routing_token;
 
659
}
 
660
 
 
661
/**
 
662
 * Set cookie.
 
663
 * @param nego
 
664
 * @param cookie
 
665
 */
 
666
 
 
667
void nego_set_cookie(rdpNego* nego, char* cookie)
 
668
{
 
669
        nego->cookie = cookie;
 
670
}