FreeRDP
tpkt.c
1 
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 
70 int tpkt_verify_header(wStream* s)
71 {
72  BYTE version = 0;
73 
74  if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
75  return -1;
76 
77  Stream_Peek_UINT8(s, version);
78 
79  if (version == 3)
80  return 1;
81  else
82  return 0;
83 }
84 
94 BOOL tpkt_read_header(wStream* s, UINT16* length)
95 {
96  BYTE version = 0;
97 
98  if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
99  return FALSE;
100 
101  Stream_Peek_UINT8(s, version);
102 
103  if (version == 3)
104  {
105  UINT16 len = 0;
106  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
107  return FALSE;
108 
109  Stream_Seek(s, 2);
110  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  if (len < 7)
114  {
115  WLog_ERR(TAG, "TPKT header too short, require minimum of 7 bytes, got %" PRId16, len);
116  return FALSE;
117  }
118 
119  if (!Stream_CheckAndLogRequiredLength(TAG, s, len - 4))
120  {
121  WLog_ERR(TAG, "TPKT header length %" PRIu16 ", but received less", len);
122  return FALSE;
123  }
124  *length = len;
125  }
126  else
127  {
128  /* not a TPKT header */
129  *length = 0;
130  }
131 
132  return TRUE;
133 }
134 
135 BOOL tpkt_ensure_stream_consumed_(wStream* s, size_t length, const char* fkt)
136 {
137  if (length > UINT16_MAX)
138  {
139  WLog_ERR(TAG, "[%s] length %" PRIuz " > %" PRIu16, fkt, length, UINT16_MAX);
140  return FALSE;
141  }
142 
143  size_t rem = Stream_GetRemainingLength(s);
144  if (rem > 0)
145  {
146  WLog_ERR(TAG,
147  "[%s] Received invalid TPKT header length %" PRIu16 ", %" PRIdz " bytes too long!",
148  fkt, length, rem);
149  return FALSE;
150  }
151  return TRUE;
152 }
153 
163 BOOL tpkt_write_header(wStream* s, size_t length)
164 {
165  if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 4))
166  return FALSE;
167  Stream_Write_UINT8(s, 3); /* version */
168  Stream_Write_UINT8(s, 0); /* reserved */
169 
170  WINPR_ASSERT(length <= UINT16_MAX);
171  Stream_Write_UINT16_BE(s, (UINT16)length); /* length */
172  return TRUE;
173 }