Decodes the SMB message in buf. All fields of the SMBMessage object will be reset to default values before decoding. On errors, do not assume that the fields will be reinstated back to what they are before this method is invoked. @param buf: data containing
(self, buf)
| 179 | return headers_data + self.parameters_data + struct.pack('<H', len(self.data)) + self.data |
| 180 | |
| 181 | def decode(self, buf): |
| 182 | """ |
| 183 | Decodes the SMB message in buf. |
| 184 | All fields of the SMBMessage object will be reset to default values before decoding. |
| 185 | On errors, do not assume that the fields will be reinstated back to what they are before |
| 186 | this method is invoked. |
| 187 | |
| 188 | @param buf: data containing one complete SMB message |
| 189 | @type buf: string |
| 190 | @return: a positive integer indicating the number of bytes used in buf to decode this SMB message |
| 191 | @raise ProtocolError: raised when decoding fails |
| 192 | """ |
| 193 | buf_len = len(buf) |
| 194 | if buf_len < self.HEADER_STRUCT_SIZE: |
| 195 | # We need at least 32 bytes (header) + 1 byte (parameter count) |
| 196 | raise ProtocolError('Not enough data to decode SMB header', buf) |
| 197 | |
| 198 | self.reset() |
| 199 | |
| 200 | protocol, self.command, status, self.flags, \ |
| 201 | self.flags2, pid_high, self.security, self.tid, \ |
| 202 | pid_low, self.uid, self.mid, params_count = struct.unpack(self.HEADER_STRUCT_FORMAT, buf[:self.HEADER_STRUCT_SIZE]) |
| 203 | |
| 204 | if protocol == b'\xFESMB': |
| 205 | raise SMB2ProtocolHeaderError() |
| 206 | if protocol != b'\xFFSMB': |
| 207 | raise ProtocolError('Invalid 4-byte protocol field', buf) |
| 208 | |
| 209 | self.pid = (pid_high << 16) | pid_low |
| 210 | self.status.internal_value = status |
| 211 | self.status.is_ntstatus = bool(self.flags2 & SMB_FLAGS2_NT_STATUS) |
| 212 | |
| 213 | offset = self.HEADER_STRUCT_SIZE |
| 214 | if buf_len < params_count * 2 + 2: |
| 215 | # Not enough data in buf to decode up to body length |
| 216 | raise ProtocolError('Not enough data. Parameters list decoding failed', buf) |
| 217 | |
| 218 | datalen_offset = offset + params_count*2 |
| 219 | body_len = struct.unpack('<H', buf[datalen_offset:datalen_offset+2])[0] |
| 220 | if body_len > 0 and buf_len < (datalen_offset + 2 + body_len): |
| 221 | # Not enough data in buf to decode body |
| 222 | raise ProtocolError('Not enough data. Body decoding failed', buf) |
| 223 | |
| 224 | self.parameters_data = buf[offset:datalen_offset] |
| 225 | |
| 226 | if body_len > 0: |
| 227 | self.data = buf[datalen_offset+2:datalen_offset+2+body_len] |
| 228 | |
| 229 | self.raw_data = buf |
| 230 | self._decodePayload() |
| 231 | |
| 232 | return self.HEADER_STRUCT_SIZE + params_count * 2 + 2 + body_len |
| 233 | |
| 234 | def _decodePayload(self): |
| 235 | if self.command == SMB_COM_READ_ANDX: |
nothing calls this directly
no test coverage detected