1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Cedar Communication Module
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100
101
102 // Interop_SSTP.c
103 // SSTP (Microsoft Secure Socket Tunneling Protocol) protocol stack
104
105 #include "CedarPch.h"
106
107 static bool g_no_sstp = false;
108
109 // Get the SSTP disabling flag
GetNoSstp()110 bool GetNoSstp()
111 {
112
113 return g_no_sstp;
114 }
115
116 // Set the SSTP disabling flag
SetNoSstp(bool b)117 void SetNoSstp(bool b)
118 {
119 g_no_sstp = b;
120 }
121
122 // Process the SSTP control packet reception
SstpProcessControlPacket(SSTP_SERVER * s,SSTP_PACKET * p)123 void SstpProcessControlPacket(SSTP_SERVER *s, SSTP_PACKET *p)
124 {
125 // Validate arguments
126 if (s == NULL || p == NULL || p->IsControl == false)
127 {
128 return;
129 }
130
131 Debug("SSTP Control Packet Recv: Msg = %u, Num = %u\n", p->MessageType, LIST_NUM(p->AttibuteList));
132
133 switch (p->MessageType)
134 {
135 case SSTP_MSG_CALL_CONNECT_REQUEST: // Receive a connection request from a client
136 if (s->Aborting == false && s->Disconnecting == false)
137 {
138 if (s->Status == SSTP_SERVER_STATUS_REQUEST_PENGING)
139 {
140 SSTP_ATTRIBUTE *protocol_id = SstpFindAttribute(p, SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID);
141 if (protocol_id != NULL && protocol_id->DataSize == 2 &&
142 READ_USHORT(protocol_id->Data) == SSTP_ENCAPSULATED_PROTOCOL_PPP)
143 {
144 // Accept the connection request by the PPP protocol
145 SSTP_PACKET *ret;
146
147 // Generation of random numbers
148 Rand(s->SentNonce, SSTP_NONCE_SIZE);
149
150 ret = SstpNewControlPacketWithAnAttribute(SSTP_MSG_CALL_CONNECT_ACK,
151 SstpNewCryptoBindingRequestAttribute(CERT_HASH_PROTOCOL_SHA256, s->SentNonce));
152
153 SstpSendPacket(s, ret);
154
155 SstpFreePacket(ret);
156
157 s->Status = SSTP_SERVER_STATUS_CONNECTED_PENDING;
158
159 s->EstablishedCount++;
160 }
161 else
162 {
163 // Refuse to accept for a connection request other than the PPP protocol
164 SSTP_PACKET *ret = SstpNewControlPacketWithAnAttribute(SSTP_MSG_CALL_CONNECT_NAK,
165 SstpNewStatusInfoAttribute(SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID, ATTRIB_STATUS_VALUE_NOT_SUPPORTED));
166
167 SstpSendPacket(s, ret);
168
169 SstpFreePacket(ret);
170 }
171 }
172 }
173 break;
174
175 case SSTP_MSG_CALL_CONNECTED: // Connection from the client complete
176 if (s->Aborting == false && s->Disconnecting == false)
177 {
178 if (s->Status == SSTP_SERVER_STATUS_CONNECTED_PENDING)
179 {
180 s->Status = SSTP_SERVER_STATUS_ESTABLISHED;
181
182 Debug("SSTP Connected.\n");
183 }
184 }
185 break;
186
187 case SSTP_MSG_CALL_DISCONNECT: // Receive a disconnect request from the client
188 case SSTP_MSG_CALL_DISCONNECT_ACK:
189 s->DisconnectRecved = true;
190 SstpDisconnect(s);
191 break;
192
193 case SSTP_MSG_CALL_ABORT: // Receive a disconnect request from the client
194 s->AbortReceived = true;
195 SstpAbort(s);
196 break;
197 }
198 }
199
200 // Process the SSTP received data packet
SstpProcessDataPacket(SSTP_SERVER * s,SSTP_PACKET * p)201 void SstpProcessDataPacket(SSTP_SERVER *s, SSTP_PACKET *p)
202 {
203 // Validate arguments
204 if (s == NULL || p == NULL || p->IsControl)
205 {
206 return;
207 }
208
209 //Debug("SSTP Data Packet Recv: Size = %u\n", p->DataSize);
210
211 if (s->PPPThread == NULL)
212 {
213 // Create a thread to initialize the new PPP module
214 s->PPPThread = NewPPPSession(s->Cedar, &s->ClientIp, s->ClientPort, &s->ServerIp, s->ServerPort,
215 s->TubeSend, s->TubeRecv, SSTP_IPC_POSTFIX, SSTP_IPC_CLIENT_NAME,
216 s->ClientHostName, s->ClientCipherName, 0);
217 }
218
219 // Pass the received data to the PPP module
220 TubeSendEx(s->TubeRecv, p->Data, p->DataSize, NULL, true);
221 s->FlushRecvTube = true;
222 }
223
224 // Process the SSTP received packet
SstpProcessPacket(SSTP_SERVER * s,SSTP_PACKET * p)225 void SstpProcessPacket(SSTP_SERVER *s, SSTP_PACKET *p)
226 {
227 // Validate arguments
228 if (s == NULL || p == NULL)
229 {
230 return;
231 }
232
233 s->LastRecvTick = s->Now;
234
235 if (p->IsControl)
236 {
237 // Control packet
238 SstpProcessControlPacket(s, p);
239 }
240 else
241 {
242 // Data packet
243 SstpProcessDataPacket(s, p);
244 }
245 }
246
247 // Send a SSTP packet
SstpSendPacket(SSTP_SERVER * s,SSTP_PACKET * p)248 void SstpSendPacket(SSTP_SERVER *s, SSTP_PACKET *p)
249 {
250 BUF *b;
251 BLOCK *block;
252 // Validate arguments
253 if (s == NULL || p == NULL)
254 {
255 return;
256 }
257
258 if (p->IsControl)
259 {
260 Debug("SSTP Control Packet Send: Msg = %u, Num = %u\n", p->MessageType, LIST_NUM(p->AttibuteList));
261 }
262 else
263 {
264 //Debug("SSTP Data Packet Send: Size=%u\n", p->DataSize);
265 }
266
267 b = SstpBuildPacket(p);
268 if (b == NULL)
269 {
270 return;
271 }
272
273 block = NewBlock(b->Buf, b->Size, 0);
274 block->PriorityQoS = p->IsControl;
275 Free(b);
276
277 InsertQueue(s->SendQueue, block);
278 }
279
280 // Process the timer interrupt
SstpProcessInterrupt(SSTP_SERVER * s)281 void SstpProcessInterrupt(SSTP_SERVER *s)
282 {
283 // Validate arguments
284 if (s == NULL)
285 {
286 return;
287 }
288
289 s->Now = Tick64();
290
291 s->FlushRecvTube = false;
292
293 // Process the received packet
294 while (true)
295 {
296 BLOCK *b = GetNext(s->RecvQueue);
297 SSTP_PACKET *p;
298
299 if (b == NULL)
300 {
301 break;
302 }
303
304 p = SstpParsePacket(b->Buf, b->Size);
305 if (p == NULL)
306 {
307 // Disconnect the SSTP since a bad packet received
308 SstpAbort(s);
309 }
310 else
311 {
312 // Process the received packet
313 SstpProcessPacket(s, p);
314
315 SstpFreePacket(p);
316 }
317
318 FreeBlock(b);
319 }
320
321 if (s->FlushRecvTube)
322 {
323 TubeFlush(s->TubeRecv);
324 }
325
326 // Transmit a packet that the PPP module is trying to send via the SSTP
327 while (true)
328 {
329 TUBEDATA *d = TubeRecvAsync(s->TubeSend);
330 SSTP_PACKET *p;
331 if (d == NULL)
332 {
333 break;
334 }
335
336 p = SstpNewDataPacket(d->Data, d->DataSize);
337
338 SstpSendPacket(s, p);
339
340 SstpFreePacket(p);
341
342 FreeTubeData(d);
343 }
344
345 if (s->Status == SSTP_SERVER_STATUS_ESTABLISHED)
346 {
347 if (s->Disconnecting == false && s->Aborting == false)
348 {
349 // Periodic transmission of Echo Request
350 if (s->NextSendEchoRequestTick == 0 || s->NextSendEchoRequestTick <= s->Now)
351 {
352 UINT64 next_interval = (UINT64)(SSTP_ECHO_SEND_INTERVAL_MIN + Rand32() % (SSTP_ECHO_SEND_INTERVAL_MAX - SSTP_ECHO_SEND_INTERVAL_MIN));
353 SSTP_PACKET *p;
354
355 s->NextSendEchoRequestTick = s->Now + next_interval;
356 AddInterrupt(s->Interrupt, s->NextSendEchoRequestTick);
357
358 p = SstpNewControlPacket(SSTP_MSG_ECHO_REQUEST);
359
360 SstpSendPacket(s, p);
361
362 SstpFreePacket(p);
363 }
364 }
365 }
366
367 if ((s->LastRecvTick + (UINT64)SSTP_TIMEOUT) <= s->Now)
368 {
369 // Disconnect the SSTP because a timeout occurred
370 SstpAbort(s);
371 s->Disconnected = true;
372 }
373
374 if (IsTubeConnected(s->TubeRecv) == false || IsTubeConnected(s->TubeSend) == false)
375 {
376 // Disconnect the SSTP since the PPP module is disconnected
377 SstpDisconnect(s);
378 }
379
380 if (s->Disconnecting)
381 {
382 // Normal disconnection process
383 if (s->DisconnectSent == false)
384 {
385 // Send a Disconnect
386 SSTP_PACKET *ret = SstpNewControlPacket(s->DisconnectRecved ? SSTP_MSG_CALL_DISCONNECT_ACK : SSTP_MSG_CALL_DISCONNECT);
387
388 SstpSendPacket(s, ret);
389
390 SstpFreePacket(ret);
391
392 s->DisconnectSent = true;
393 }
394 }
395
396 if (s->Aborting)
397 {
398 // Abnormal disconnection processing
399 if (s->AbortSent == false)
400 {
401 // Send the Abort
402 SSTP_PACKET *ret = SstpNewControlPacket(SSTP_MSG_CALL_ABORT);
403
404 SstpSendPacket(s, ret);
405
406 SstpFreePacket(ret);
407
408 s->AbortSent = true;
409 }
410 }
411
412 if (s->DisconnectSent && s->DisconnectRecved)
413 {
414 // Disconnect after exchanging the Disconnect each other
415 s->Disconnected = true;
416 }
417
418 if (s->AbortSent && s->AbortReceived)
419 {
420 // Disconnect after exchanging the Abort each other
421 s->Disconnected = true;
422 }
423 }
424
425 // Create a new SSTP control packet with an Attribute
SstpNewControlPacketWithAnAttribute(USHORT message_type,SSTP_ATTRIBUTE * a)426 SSTP_PACKET *SstpNewControlPacketWithAnAttribute(USHORT message_type, SSTP_ATTRIBUTE *a)
427 {
428 SSTP_PACKET *p = SstpNewControlPacket(message_type);
429
430 if (a != NULL)
431 {
432 Add(p->AttibuteList, a);
433 }
434
435 return p;
436 }
437
438 // Create a new SSTP control packet
SstpNewControlPacket(USHORT message_type)439 SSTP_PACKET *SstpNewControlPacket(USHORT message_type)
440 {
441 SSTP_PACKET *p = ZeroMalloc(sizeof(SSTP_PACKET));
442
443 p->IsControl = true;
444 p->MessageType = message_type;
445 p->Version = SSTP_VERSION_1;
446 p->AttibuteList = NewListFast(NULL);
447
448 return p;
449 }
450
451 // Create a new SSTP data packet
SstpNewDataPacket(UCHAR * data,UINT size)452 SSTP_PACKET *SstpNewDataPacket(UCHAR *data, UINT size)
453 {
454 SSTP_PACKET *p = ZeroMalloc(sizeof(SSTP_PACKET));
455
456 p->IsControl = false;
457 p->Data = Clone(data, size);
458 p->DataSize = size;
459
460 return p;
461 }
462
463 // Get the Attibute with the specified ID from SSTP packet
SstpFindAttribute(SSTP_PACKET * p,UCHAR attribute_id)464 SSTP_ATTRIBUTE *SstpFindAttribute(SSTP_PACKET *p, UCHAR attribute_id)
465 {
466 UINT i;
467 // Validate arguments
468 if (p == NULL)
469 {
470 return NULL;
471 }
472
473 for (i = 0;i < LIST_NUM(p->AttibuteList);i++)
474 {
475 SSTP_ATTRIBUTE *a = LIST_DATA(p->AttibuteList, i);
476
477 if (a->AttributeId == attribute_id)
478 {
479 return a;
480 }
481 }
482
483 return NULL;
484 }
485
486 // Disconnect the SSTP normally
SstpDisconnect(SSTP_SERVER * s)487 void SstpDisconnect(SSTP_SERVER *s)
488 {
489 // Validate arguments
490 if (s == NULL)
491 {
492 return;
493 }
494
495 s->Disconnecting = true;
496 }
497
498 // Disconnect the SSTP abnormally
SstpAbort(SSTP_SERVER * s)499 void SstpAbort(SSTP_SERVER *s)
500 {
501 // Validate arguments
502 if (s == NULL)
503 {
504 return;
505 }
506
507 s->Aborting = true;
508 }
509
510 // Create a Crypto Binding Request Attribute
SstpNewCryptoBindingRequestAttribute(UCHAR hash_protocol_bitmask,UCHAR * nonce_32bytes)511 SSTP_ATTRIBUTE *SstpNewCryptoBindingRequestAttribute(UCHAR hash_protocol_bitmask, UCHAR *nonce_32bytes)
512 {
513 SSTP_ATTRIBUTE *a;
514 UCHAR uc;
515 BUF *b = NewBuf();
516
517 uc = 0;
518 WriteBuf(b, &uc, 1);
519 WriteBuf(b, &uc, 1);
520 WriteBuf(b, &uc, 1);
521 WriteBuf(b, &hash_protocol_bitmask, 1);
522
523 WriteBuf(b, nonce_32bytes, SSTP_NONCE_SIZE);
524
525 a = SstpNewAttribute(SSTP_ATTRIB_CRYPTO_BINDING_REQ, b->Buf, b->Size);
526
527 FreeBuf(b);
528
529 return a;
530 }
531
532 // Create a Status Info Attribute
SstpNewStatusInfoAttribute(UCHAR attrib_id,UINT status)533 SSTP_ATTRIBUTE *SstpNewStatusInfoAttribute(UCHAR attrib_id, UINT status)
534 {
535 SSTP_ATTRIBUTE *a;
536 UCHAR uc;
537 BUF *b = NewBuf();
538
539 uc = 0;
540 WriteBuf(b, &uc, 1);
541 WriteBuf(b, &uc, 1);
542 WriteBuf(b, &uc, 1);
543 WriteBuf(b, &attrib_id, 1);
544
545 WriteBufInt(b, status);
546
547 a = SstpNewAttribute(SSTP_ATTRIB_STATUS_INFO, b->Buf, b->Size);
548
549 FreeBuf(b);
550
551 return a;
552 }
553
554 // Create a New Attribute
SstpNewAttribute(UCHAR attribute_id,UCHAR * data,UINT data_size)555 SSTP_ATTRIBUTE *SstpNewAttribute(UCHAR attribute_id, UCHAR *data, UINT data_size)
556 {
557 SSTP_ATTRIBUTE *a = ZeroMalloc(sizeof(SSTP_ATTRIBUTE));
558
559 a->AttributeId = attribute_id;
560 a->Data = Clone(data, data_size);
561 a->DataSize = data_size;
562
563 return a;
564 }
565
566 // Build the Attribute
SstpBuildAttribute(SSTP_ATTRIBUTE * a)567 BUF *SstpBuildAttribute(SSTP_ATTRIBUTE *a)
568 {
569 UCHAR uc;
570 USHORT us;
571 BUF *b;
572 // Validate arguments
573 if (a == NULL)
574 {
575 return NULL;
576 }
577
578 b = NewBuf();
579
580 // Reserved
581 uc = 0;
582 WriteBuf(b, &uc, sizeof(UCHAR));
583
584 // Attribute ID
585 uc = a->AttributeId;
586 WriteBuf(b, &uc, sizeof(UCHAR));
587
588 // LengthPacket
589 a->TotalLength = a->DataSize + 4;
590 us = (USHORT)a->TotalLength;
591 us = Endian16(us);
592 WriteBuf(b, &us, sizeof(USHORT));
593
594 // Data
595 WriteBuf(b, a->Data, a->DataSize);
596
597 return b;
598 }
599
600 // Build the Attribute list
SstpBuildAttributeList(LIST * o,USHORT message_type)601 BUF *SstpBuildAttributeList(LIST *o, USHORT message_type)
602 {
603 UINT i;
604 BUF *b;
605 USHORT us;
606 // Validate arguments
607 if (o == NULL)
608 {
609 return NULL;
610 }
611
612 b = NewBuf();
613
614 us = Endian16(message_type);
615 WriteBuf(b, &us, sizeof(USHORT));
616
617 us = Endian16((USHORT)LIST_NUM(o));
618 WriteBuf(b, &us, sizeof(USHORT));
619
620 for (i = 0;i < LIST_NUM(o);i++)
621 {
622 SSTP_ATTRIBUTE *a = LIST_DATA(o, i);
623 BUF *ab = SstpBuildAttribute(a);
624
625 if (ab != NULL)
626 {
627 WriteBufBuf(b, ab);
628
629 FreeBuf(ab);
630 }
631 }
632
633 return b;
634 }
635
636 // Building the SSTP packet
SstpBuildPacket(SSTP_PACKET * p)637 BUF *SstpBuildPacket(SSTP_PACKET *p)
638 {
639 BUF *b;
640 UCHAR uc;
641 USHORT us;
642 // Validate arguments
643 if (p == NULL)
644 {
645 return NULL;
646 }
647
648 b = NewBuf();
649
650 if (p->IsControl)
651 {
652 BUF *ab;
653
654 if (p->Data != NULL)
655 {
656 Free(p->Data);
657 }
658
659 ab = SstpBuildAttributeList(p->AttibuteList, p->MessageType);
660 p->Data = ab->Buf;
661 p->DataSize = ab->Size;
662 Free(ab);
663 }
664
665 // Version
666 uc = SSTP_VERSION_1;
667 WriteBuf(b, &uc, sizeof(UCHAR));
668
669 // Flag
670 uc = p->IsControl ? 1 : 0;
671 WriteBuf(b, &uc, sizeof(UCHAR));
672
673 // Length Packet
674 us = Endian16(p->DataSize + 4);
675 WriteBuf(b, &us, sizeof(USHORT));
676
677 // Data
678 WriteBuf(b, p->Data, p->DataSize);
679
680 return b;
681 }
682
683 // Parse the SSTP packet
SstpParsePacket(UCHAR * data,UINT size)684 SSTP_PACKET *SstpParsePacket(UCHAR *data, UINT size)
685 {
686 SSTP_PACKET *p;
687 USHORT len;
688 // Validate arguments
689 if (data == NULL || size == 0)
690 {
691 return NULL;
692 }
693
694 if (size < 4)
695 {
696 return NULL;
697 }
698
699 p = ZeroMalloc(sizeof(SSTP_PACKET));
700
701 // Version
702 p->Version = *((UCHAR *)data);
703 data++;
704 size--;
705
706 if (p->Version != SSTP_VERSION_1)
707 {
708 // Invalid version
709 SstpFreePacket(p);
710 return NULL;
711 }
712
713 // Flag
714 if ((*((UCHAR *)data)) & 0x01)
715 {
716 p->IsControl = true;
717 }
718 data++;
719 size--;
720
721 // Length
722 len = READ_USHORT(data) & 0xFFF;
723 data += sizeof(USHORT);
724 size -= sizeof(USHORT);
725
726 if (len < 4)
727 {
728 // Invalid size
729 SstpFreePacket(p);
730 return NULL;
731 }
732
733 if (((UINT)(len - 4)) > size)
734 {
735 // Oversized
736 SstpFreePacket(p);
737 return NULL;
738 }
739
740 // Data
741 p->DataSize = len - 4;
742 p->Data = Clone(data, p->DataSize);
743
744 if (p->IsControl)
745 {
746 // Parse the Attribute list
747 p->AttibuteList = SstpParseAttributeList(p->Data, p->DataSize, p);
748
749 if (p->AttibuteList == NULL)
750 {
751 // Failure of parsing list
752 SstpFreePacket(p);
753 return NULL;
754 }
755 }
756
757 return p;
758 }
759
760 // Parse the Attribute list
SstpParseAttributeList(UCHAR * data,UINT size,SSTP_PACKET * p)761 LIST *SstpParseAttributeList(UCHAR *data, UINT size, SSTP_PACKET *p)
762 {
763 LIST *o;
764 USHORT us;
765 UINT num;
766 // Validate arguments
767 if (size == 0 || data == NULL || p == NULL)
768 {
769 return NULL;
770 }
771
772 if (size < 4)
773 {
774 return NULL;
775 }
776
777 // Message Type
778 us = READ_USHORT(data);
779 p->MessageType = us;
780 data += sizeof(USHORT);
781 size -= sizeof(USHORT);
782
783 // Num Attributes
784 num = READ_USHORT(data);
785 data += sizeof(USHORT);
786 size -= sizeof(USHORT);
787
788 // Attibutes List
789 o = NewListFast(NULL);
790
791 while (LIST_NUM(o) < num)
792 {
793 SSTP_ATTRIBUTE *a = SstpParseAttribute(data, size);
794
795 if (a == NULL)
796 {
797 SstpFreeAttributeList(o);
798 return NULL;
799 }
800
801 if (a->TotalLength > size)
802 {
803 SstpFreeAttribute(a);
804 SstpFreeAttributeList(o);
805 return NULL;
806 }
807
808 Add(o, a);
809
810 data += a->TotalLength;
811 size -= a->TotalLength;
812 }
813
814 return o;
815 }
816
817 // Parse the Attribute
SstpParseAttribute(UCHAR * data,UINT size)818 SSTP_ATTRIBUTE *SstpParseAttribute(UCHAR *data, UINT size)
819 {
820 SSTP_ATTRIBUTE *a;
821 // Validate arguments
822 if (data == NULL || size == 0)
823 {
824 return NULL;
825 }
826
827 a = ZeroMalloc(sizeof(SSTP_ATTRIBUTE));
828
829 if (size < 4)
830 {
831 SstpFreeAttribute(a);
832 return NULL;
833 }
834
835 data++;
836 size--;
837
838 // Attribute ID
839 a->AttributeId = *((UCHAR *)data);
840 data++;
841 size--;
842
843 // Length
844 a->TotalLength = READ_USHORT(data) & 0xFFF;
845 data += sizeof(USHORT);
846 size -= sizeof(USHORT);
847
848 if (a->TotalLength < 4)
849 {
850 // Length fraud
851 SstpFreeAttribute(a);
852 return NULL;
853 }
854
855 a->DataSize = a->TotalLength - 4;
856 if (a->DataSize > size)
857 {
858 // Length excess
859 SstpFreeAttribute(a);
860 return NULL;
861 }
862
863 a->Data = Clone(data, a->DataSize);
864
865 return a;
866 }
867
868 // Release the Attibute
SstpFreeAttribute(SSTP_ATTRIBUTE * a)869 void SstpFreeAttribute(SSTP_ATTRIBUTE *a)
870 {
871 // Validate arguments
872 if (a == NULL)
873 {
874 return;
875 }
876
877 Free(a->Data);
878
879 Free(a);
880 }
881
882 // Release the Attribute list
SstpFreeAttributeList(LIST * o)883 void SstpFreeAttributeList(LIST *o)
884 {
885 UINT i;
886 // Validate arguments
887 if (o == NULL)
888 {
889 return;
890 }
891
892 for (i = 0;i < LIST_NUM(o);i++)
893 {
894 SSTP_ATTRIBUTE *a = LIST_DATA(o, i);
895
896 SstpFreeAttribute(a);
897 }
898
899 ReleaseList(o);
900 }
901
902 // Release the SSTP packet
SstpFreePacket(SSTP_PACKET * p)903 void SstpFreePacket(SSTP_PACKET *p)
904 {
905 // Validate arguments
906 if (p == NULL)
907 {
908 return;
909 }
910
911 if (p->AttibuteList != NULL)
912 {
913 SstpFreeAttributeList(p->AttibuteList);
914 }
915
916 if (p->Data != NULL)
917 {
918 Free(p->Data);
919 }
920
921 Free(p);
922 }
923
924 // Create a SSTP server
NewSstpServer(CEDAR * cedar,IP * client_ip,UINT client_port,IP * server_ip,UINT server_port,SOCK_EVENT * se,char * client_host_name,char * crypt_name)925 SSTP_SERVER *NewSstpServer(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip,
926 UINT server_port, SOCK_EVENT *se,
927 char *client_host_name, char *crypt_name)
928 {
929 SSTP_SERVER *s = ZeroMalloc(sizeof(SSTP_SERVER));
930
931 s->LastRecvTick = Tick64();
932
933 StrCpy(s->ClientHostName, sizeof(s->ClientHostName), client_host_name);
934 StrCpy(s->ClientCipherName, sizeof(s->ClientCipherName), crypt_name);
935
936 s->Cedar = cedar;
937 AddRef(s->Cedar->ref);
938
939 NewTubePair(&s->TubeSend, &s->TubeRecv, 0);
940 SetTubeSockEvent(s->TubeSend, se);
941
942 s->Now = Tick64();
943
944 Copy(&s->ClientIp, client_ip, sizeof(IP));
945 s->ClientPort = client_port;
946 Copy(&s->ServerIp, server_ip, sizeof(IP));
947 s->ServerPort = server_port;
948
949 s->SockEvent = se;
950
951 AddRef(s->SockEvent->ref);
952
953 s->RecvQueue = NewQueueFast();
954 s->SendQueue = NewQueueFast();
955
956 s->Interrupt = NewInterruptManager();
957
958 return s;
959 }
960
961 // Release the SSTP server
FreeSstpServer(SSTP_SERVER * s)962 void FreeSstpServer(SSTP_SERVER *s)
963 {
964 // Validate arguments
965 if (s == NULL)
966 {
967 return;
968 }
969
970 TubeDisconnect(s->TubeRecv);
971 TubeDisconnect(s->TubeSend);
972
973 WaitThread(s->PPPThread, INFINITE);
974 ReleaseThread(s->PPPThread);
975
976 while (true)
977 {
978 BLOCK *b = GetNext(s->RecvQueue);
979
980 if (b == NULL)
981 {
982 break;
983 }
984
985 FreeBlock(b);
986 }
987
988 while (true)
989 {
990 BLOCK *b = GetNext(s->SendQueue);
991
992 if (b == NULL)
993 {
994 break;
995 }
996
997 FreeBlock(b);
998 }
999
1000 ReleaseQueue(s->RecvQueue);
1001 ReleaseQueue(s->SendQueue);
1002
1003 ReleaseSockEvent(s->SockEvent);
1004
1005 FreeInterruptManager(s->Interrupt);
1006
1007 ReleaseCedar(s->Cedar);
1008
1009 ReleaseTube(s->TubeSend);
1010 ReleaseTube(s->TubeRecv);
1011
1012 Free(s);
1013 }
1014
1015 // Handle the communication of SSTP protocol
ProcessSstpHttps(CEDAR * cedar,SOCK * s,SOCK_EVENT * se)1016 bool ProcessSstpHttps(CEDAR *cedar, SOCK *s, SOCK_EVENT *se)
1017 {
1018 UINT tmp_size = 65536;
1019 UCHAR *tmp_buf;
1020 FIFO *recv_fifo;
1021 FIFO *send_fifo;
1022 SSTP_SERVER *sstp;
1023 bool ret = false;
1024 // Validate arguments
1025 if (cedar == NULL || s == NULL || se == NULL)
1026 {
1027 return false;
1028 }
1029
1030 tmp_buf = Malloc(tmp_size);
1031 recv_fifo = NewFifo();
1032 send_fifo = NewFifo();
1033
1034 sstp = NewSstpServer(cedar, &s->RemoteIP, s->RemotePort, &s->LocalIP, s->LocalPort, se,
1035 s->RemoteHostname, s->CipherName);
1036
1037 while (true)
1038 {
1039 UINT r;
1040 bool is_disconnected = false;
1041 bool state_changed = false;
1042
1043 // Receive data over SSL
1044 while (true)
1045 {
1046 r = Recv(s, tmp_buf, tmp_size, true);
1047 if (r == 0)
1048 {
1049 // SSL is disconnected
1050 is_disconnected = true;
1051 break;
1052 }
1053 else if (r == SOCK_LATER)
1054 {
1055 // Data is not received any more
1056 break;
1057 }
1058 else
1059 {
1060 // Queue the received data
1061 WriteFifo(recv_fifo, tmp_buf, r);
1062 state_changed = true;
1063 }
1064 }
1065
1066 while (recv_fifo->size >= 4)
1067 {
1068 UCHAR *first4;
1069 UINT read_size = 0;
1070 bool ok = false;
1071 // Read 4 bytes from the beginning of the receive queue
1072 first4 = ((UCHAR *)recv_fifo->p) + recv_fifo->pos;
1073 if (first4[0] == SSTP_VERSION_1)
1074 {
1075 USHORT len = READ_USHORT(first4 + 2) & 0xFFF;
1076 if (len >= 4)
1077 {
1078 ok = true;
1079
1080 if (recv_fifo->size >= len)
1081 {
1082 UCHAR *data;
1083 BLOCK *b;
1084
1085 read_size = len;
1086 data = Malloc(read_size);
1087
1088 ReadFifo(recv_fifo, data, read_size);
1089
1090 b = NewBlock(data, read_size, 0);
1091
1092 InsertQueue(sstp->RecvQueue, b);
1093 }
1094 }
1095 }
1096
1097 if (read_size == 0)
1098 {
1099 break;
1100 }
1101
1102 if (ok == false)
1103 {
1104 // Disconnect the connection since a bad packet received
1105 is_disconnected = true;
1106 break;
1107 }
1108 }
1109
1110 // Process the timer interrupt
1111 SstpProcessInterrupt(sstp);
1112
1113 if (sstp->Disconnected)
1114 {
1115 is_disconnected = true;
1116 }
1117
1118 // Put the transmission data that SSTP module has generated into the transmission queue
1119 while (true)
1120 {
1121 BLOCK *b = GetNext(sstp->SendQueue);
1122
1123 if (b == NULL)
1124 {
1125 break;
1126 }
1127
1128 // When transmit a data packet, If there are packets of more than about
1129 // 2.5 MB in the transmission queue of the TCP, discard without transmission
1130 if (b->PriorityQoS || (send_fifo->size <= MAX_BUFFERING_PACKET_SIZE))
1131 {
1132 WriteFifo(send_fifo, b->Buf, b->Size);
1133 }
1134
1135 FreeBlock(b);
1136 }
1137
1138 // Data is transmitted over SSL
1139 while (send_fifo->size != 0)
1140 {
1141 r = Send(s, ((UCHAR *)send_fifo->p) + send_fifo->pos, send_fifo->size, true);
1142 if (r == 0)
1143 {
1144 // SSL is disconnected
1145 is_disconnected = true;
1146 break;
1147 }
1148 else if (r == SOCK_LATER)
1149 {
1150 // Can not send any more
1151 break;
1152 }
1153 else
1154 {
1155 // Advance the transmission queue by the amount of the transmitted
1156 ReadFifo(send_fifo, NULL, r);
1157 state_changed = true;
1158 }
1159 }
1160
1161 if (is_disconnected)
1162 {
1163 // Disconnected
1164 break;
1165 }
1166
1167 // Wait for the next state change
1168 if (state_changed == false)
1169 {
1170 UINT select_time = SELECT_TIME;
1171 UINT r = GetNextIntervalForInterrupt(sstp->Interrupt);
1172 WaitSockEvent(se, MIN(r, select_time));
1173 }
1174 }
1175
1176 if (sstp != NULL && sstp->EstablishedCount >= 1)
1177 {
1178 ret = true;
1179 }
1180
1181 FreeSstpServer(sstp);
1182
1183 ReleaseFifo(recv_fifo);
1184 ReleaseFifo(send_fifo);
1185 Free(tmp_buf);
1186
1187 YieldCpu();
1188 Disconnect(s);
1189
1190 return ret;
1191 }
1192
1193 // Accept the SSTP connection
AcceptSstp(CONNECTION * c)1194 bool AcceptSstp(CONNECTION *c)
1195 {
1196 SOCK *s;
1197 HTTP_HEADER *h;
1198 char date_str[MAX_SIZE];
1199 bool ret;
1200 bool ret2 = false;
1201 SOCK_EVENT *se;
1202 // Validate arguments
1203 if (c == NULL)
1204 {
1205 return false;
1206 }
1207
1208 s = c->FirstSock;
1209
1210 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
1211
1212 // Return a response
1213 h = NewHttpHeader("HTTP/1.1", "200", "OK");
1214 AddHttpValue(h, NewHttpValue("Content-Length", "18446744073709551615"));
1215 AddHttpValue(h, NewHttpValue("Server", "Microsoft-HTTPAPI/2.0"));
1216 AddHttpValue(h, NewHttpValue("Date", date_str));
1217
1218 ret = PostHttp(s, h, NULL, 0);
1219
1220 FreeHttpHeader(h);
1221
1222 if (ret)
1223 {
1224 SetTimeout(s, INFINITE);
1225
1226 se = NewSockEvent();
1227
1228 JoinSockToSockEvent(s, se);
1229
1230 Debug("ProcessSstpHttps Start.\n");
1231 ret2 = ProcessSstpHttps(c->Cedar, s, se);
1232 Debug("ProcessSstpHttps End.\n");
1233
1234 ReleaseSockEvent(se);
1235 }
1236
1237 Disconnect(s);
1238
1239 return ret2;
1240 }
1241
1242