/src/FreeRDP/libfreerdp/core/tpkt.c
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * FreeRDP: A Remote Desktop Protocol Implementation |
3 | | * Transport Packets (TPKTs) |
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 <freerdp/config.h> |
21 | | |
22 | | #include "tpdu.h" |
23 | | |
24 | | #include "tpkt.h" |
25 | | |
26 | | #include <winpr/wlog.h> |
27 | | |
28 | | #define TAG FREERDP_TAG("core.tpkt") |
29 | | |
30 | | /** |
31 | | * TPKTs are defined in: |
32 | | * |
33 | | * http://tools.ietf.org/html/rfc1006/ |
34 | | * RFC 1006 - ISO Transport Service on top of the TCP |
35 | | * |
36 | | * http://www.itu.int/rec/T-REC-T.123/ |
37 | | * ITU-T T.123 (01/2007) - Network-specific data protocol stacks for multimedia conferencing |
38 | | * |
39 | | * TPKT Header |
40 | | * ____________________ byte |
41 | | * | | |
42 | | * | 3 (version) | 1 |
43 | | * |____________________| |
44 | | * | | |
45 | | * | Reserved | 2 |
46 | | * |____________________| |
47 | | * | | |
48 | | * | Length (MSB) | 3 |
49 | | * |____________________| |
50 | | * | | |
51 | | * | Length (LSB) | 4 |
52 | | * |____________________| |
53 | | * | | |
54 | | * | X.224 TPDU | 5 - ? |
55 | | * .... |
56 | | * |
57 | | * A TPKT header is of fixed length 4, and the following X.224 TPDU is at least three bytes long. |
58 | | * Therefore, the minimum TPKT length is 7, and the maximum TPKT length is 65535. Because the TPKT |
59 | | * length includes the TPKT header (4 bytes), the maximum X.224 TPDU length is 65531. |
60 | | */ |
61 | | |
62 | | /** |
63 | | * Verify if a packet has valid TPKT header. |
64 | | * |
65 | | * @param s A stream to read from |
66 | | * |
67 | | * @return \b TRUE for success, \b FALSE otherwise |
68 | | */ |
69 | | |
70 | | int tpkt_verify_header(wStream* s) |
71 | 0 | { |
72 | 0 | BYTE version = 0; |
73 | |
|
74 | 0 | if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) |
75 | 0 | return -1; |
76 | | |
77 | 0 | Stream_Peek_UINT8(s, version); |
78 | |
|
79 | 0 | if (version == 3) |
80 | 0 | return 1; |
81 | 0 | else |
82 | 0 | return 0; |
83 | 0 | } |
84 | | |
85 | | /** |
86 | | * Read a TPKT header. |
87 | | * |
88 | | * @param s A stream to read from |
89 | | * @param length A pointer to the result, must not be NULL |
90 | | * |
91 | | * @return \b TRUE for success, \b FALSE otherwise |
92 | | */ |
93 | | |
94 | | BOOL tpkt_read_header(wStream* s, UINT16* length) |
95 | 74.8k | { |
96 | 74.8k | BYTE version = 0; |
97 | | |
98 | 74.8k | if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) |
99 | 10.3k | return FALSE; |
100 | | |
101 | 64.5k | Stream_Peek_UINT8(s, version); |
102 | | |
103 | 64.5k | if (version == 3) |
104 | 6.28k | { |
105 | 6.28k | UINT16 len = 0; |
106 | 6.28k | if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) |
107 | 74 | return FALSE; |
108 | | |
109 | 6.21k | Stream_Seek(s, 2); |
110 | 6.21k | Stream_Read_UINT16_BE(s, len); |
111 | | |
112 | | /* ITU-T Rec. T.123 8 Packet header to delimit data units in an octet stream */ |
113 | 6.21k | if (len < 7) |
114 | 464 | { |
115 | 464 | WLog_ERR(TAG, "TPKT header too short, require minimum of 7 bytes, got %" PRId16, len); |
116 | 464 | return FALSE; |
117 | 464 | } |
118 | | |
119 | 5.74k | if (!Stream_CheckAndLogRequiredLength(TAG, s, len - 4)) |
120 | 1.16k | { |
121 | 1.16k | WLog_ERR(TAG, "TPKT header length %" PRIu16 ", but received less", len); |
122 | 1.16k | return FALSE; |
123 | 1.16k | } |
124 | 4.58k | *length = len; |
125 | 4.58k | } |
126 | 58.2k | else |
127 | 58.2k | { |
128 | | /* not a TPKT header */ |
129 | 58.2k | *length = 0; |
130 | 58.2k | } |
131 | | |
132 | 62.8k | return TRUE; |
133 | 64.5k | } |
134 | | |
135 | | BOOL tpkt_ensure_stream_consumed_(wStream* s, size_t length, const char* fkt) |
136 | 12.5k | { |
137 | 12.5k | if (length > UINT16_MAX) |
138 | 0 | { |
139 | 0 | WLog_ERR(TAG, "[%s] length %" PRIuz " > %" PRIu16, fkt, length, UINT16_MAX); |
140 | 0 | return FALSE; |
141 | 0 | } |
142 | | |
143 | 12.5k | size_t rem = Stream_GetRemainingLength(s); |
144 | 12.5k | if (rem > 0) |
145 | 11.0k | { |
146 | 11.0k | WLog_ERR(TAG, |
147 | 11.0k | "[%s] Received invalid TPKT header length %" PRIu16 ", %" PRIdz " bytes too long!", |
148 | 11.0k | fkt, length, rem); |
149 | 11.0k | return FALSE; |
150 | 11.0k | } |
151 | 1.52k | return TRUE; |
152 | 12.5k | } |
153 | | |
154 | | /** |
155 | | * Write a TPKT header. |
156 | | * |
157 | | * @param s A stream to write to |
158 | | * @param length The value to write |
159 | | * |
160 | | * @return \b TRUE for success, \b FALSE otherwise |
161 | | */ |
162 | | |
163 | | BOOL tpkt_write_header(wStream* s, UINT16 length) |
164 | 3.12k | { |
165 | 3.12k | if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 4)) |
166 | 0 | return FALSE; |
167 | 3.12k | Stream_Write_UINT8(s, 3); /* version */ |
168 | 3.12k | Stream_Write_UINT8(s, 0); /* reserved */ |
169 | 3.12k | Stream_Write_UINT16_BE(s, length); /* length */ |
170 | 3.12k | return TRUE; |
171 | 3.12k | } |