Coverage Report

Created: 2024-05-20 06:11

/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
}