Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: net/http/ntlm_buffer_reader.h

Issue 2879353002: Add a buffer reader/writer for NTLM. (Closed)
Patch Set: Add a buffer reader/writer for NTLM. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef NET_BASE_NTLM_BUFFER_READER_H_
6 #define NET_BASE_NTLM_BUFFER_READER_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <string>
12
13 #include "base/strings/string_piece.h"
14 #include "net/base/net_export.h"
15 #include "net/http/ntlm_message.h"
16
17 namespace net {
18
19 // Supports various bounds checked low level buffer
20 // operations required by an NTLM implementation.
21 //
22 // The class supports sequential read of a provided
23 // buffer. All reads perform bounds checking to ensure
24 // enough space is remaining in the buffer.
25 //
26 //
27 // Read* methods read from the buffer at the current cursor
28 // position and perform any necessary type conversion and
29 // provide the data in out params. After a successful read
30 // the cursor position is advanced past the read field.
31 //
32 // Failed reads leave the internal cursor at the same
33 // position as before the call.
34 //
35 //
36 // Read*Payload methods first read a security buffer see
37 // |ReadSecurityBuffer| then read the requested payload
38 // from the offset and length stated in the security buffer.
39 //
40 // If the length and offset in the security buffer would
41 // cause a read outside the message buffer the payload will
42 // not be read and the function will return false.
43 //
44 // The cursor will remain as it was before the call as if
45 // the security buffer had not been read.
46 //
47 //
48 // Skip* methods skip the cursor over that same number
49 // of bytes that the equivalent Read method would without
50 // reading or returning the values.
51 //
52 //
53 // Match* methods are used to validate fields in the
54 // buffer that should have expected values, such as
55 // signatures or message identifiers.
Ryan Sleevi 2017/05/30 19:02:22 I can't tell - are these aligned to the maximal us
zentaro 2017/06/05 17:28:44 Done.
56 //
57 //
58 // Based on [MS-NLMP]: NT LAN Manager (NTLM) Authentication
59 // Protocol specification version 28.0 [1]
60 //
61 // [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
62 class NET_EXPORT NtlmBufferReader {
63 public:
64 NtlmBufferReader(const base::StringPiece buffer);
Ryan Sleevi 2017/05/30 19:02:22 style: you can drop the const since you're passing
Ryan Sleevi 2017/05/30 19:02:22 style: "explicit" - https://google.github.io/style
zentaro 2017/06/05 17:28:44 Done. I previously was passing by const-ref then s
zentaro 2017/06/05 17:28:44 Done.
65 NtlmBufferReader(const uint8_t* ptr, size_t len);
Ryan Sleevi 2017/05/30 19:02:22 Since you accept a base::StringPiece, is this over
zentaro 2017/06/05 17:28:44 I could I guess try and convert all the callers to
66 ~NtlmBufferReader();
67
68 size_t GetLength() const { return buffer_.length(); }
69 size_t GetCursor() const { return cursor_; }
70 bool IsEndOfBuffer() const { return cursor_ >= GetLength(); }
71
72 const uint8_t* GetBufferPtr() const {
73 return reinterpret_cast<const uint8_t*>(buffer_.data());
74 }
75
76 // Returns a pointer to the underlying buffer at the current cursor
77 // position.
78 const uint8_t* GetBufferAtCursor() const { return GetBufferPtr() + cursor_; }
Ryan Sleevi 2017/05/30 19:02:22 Both this and the function on line 72 seem like th
zentaro 2017/06/05 17:28:44 I managed to refactor out all the public uses of t
79
80 // Returns true if there are |len| more bytes between the
81 // current cursor position and the end of the buffer.
82 bool CanRead(size_t len) const;
83
84 // Returns true if there are |len| more bytes between |offset|
85 // and the end of the buffer. The cursor position is not used
86 // or modified.
87 bool CanReadFrom(size_t offset, size_t len) const;
88
89 bool ReadUInt16(uint16_t* value);
Ryan Sleevi 2017/05/30 19:02:22 Document a bit more - for example, what's the endi
zentaro 2017/06/05 17:28:44 Done.
90 bool ReadUInt32(uint32_t* value);
91 bool ReadUInt64(uint64_t* value);
92
93 bool ReadBytes(uint8_t* buffer, size_t len);
94
95 // A security buffer is an 8 byte structure that defines the
96 // offset and length of a payload (string, struct or byte array)
97 // that appears after the fixed part of the message.
98 //
99 // The structure is (little endian fields):
100 // uint16 - |length| Length of payload
101 // uint16 - Allocation (this is always ignored and not returned)
102 // uint32 - |offset| Offset from start of message
103 bool ReadSecurityBuffer(uint16_t* length, uint32_t* offset);
104
105 bool ReadAsciiString(std::string* value, size_t len);
106 bool ReadUnicodeString(base::string16* value, size_t len);
Ryan Sleevi 2017/05/30 19:02:22 I suspect you're borrowing from the NTLM language,
107
108 // There are 3 message types Negotiate (sent by client),
109 // Challenge (sent by server), and Authenticate (sent by client).
110 //
111 // This reads the message type from the header and will return
112 // false if the value is invalid.
113 bool ReadMessageType(NtlmMessage::MessageType* message_type);
114
115 bool ReadAsciiPayload(std::string* value);
116 bool ReadUnicodePayload(base::string16* value);
117 bool ReadBytesPayload(uint8_t* buffer, size_t buffer_len);
Ryan Sleevi 2017/05/30 19:02:22 How are the *Payload functions different from the
zentaro 2017/06/05 17:28:44 Added some additional docs to clarify. But the 'pa
118
119 bool SkipSecurityBuffer();
120
121 // Skips over the security buffer without returning the values
Ryan Sleevi 2017/05/30 19:02:22 grammar: "returning the values, " (add a comma)
zentaro 2017/06/05 17:28:44 Done.
122 // but fails if the values would cause a read outside the buffer
123 // if the payload was actually read.
124 bool SkipSecurityBufferWithValidation();
125
126 // Skips over |count| bytes in the buffer. Returns false if there
127 // is not |count| bytes left in the buffer.
128 bool SkipBytes(size_t count);
129
130 // Reads and returns true if the next 8 bytes matches the signature in
131 // an NTLM message "NTLMSSP\0"
132 bool MatchSignature();
133
134 // Reads the message type from the cursor and returns true
135 // if it is |message_type|.
136 bool MatchMessageType(NtlmMessage::MessageType message_type);
137
138 // Performs |MatchSignature| then |MatchMessageType|.
139 bool MatchMessageHeader(NtlmMessage::MessageType message_type);
140
141 // Reads and returns true if there are |count| bytes of zeros.
142 bool MatchZeros(size_t count);
143
144 // Reads and returns true if the next 8 bytes contain an empty
145 // ie. all zero security buffer.
146 bool MatchEmptySecurityBuffer();
147
148 private:
149 // Reads |sizeof(T)| bytes of an integer type from a little-endian
150 // buffer.
151 template <typename T>
152 bool ReadUInt(T* value);
153
154 // Sets the cursor position. This is used when reading payloads to
155 // move the cursor to the start of the payload indicated by the
156 // security buffer.
157 bool SetCursor(size_t cursor);
158
159 uint8_t GetByteAtCursor() const {
160 DCHECK(!IsEndOfBuffer());
161 return *(GetBufferAtCursor());
162 }
163
164 const base::StringPiece buffer_;
165 size_t cursor_;
166
167 DISALLOW_COPY_AND_ASSIGN(NtlmBufferReader);
168 };
169
170 } // namespace net
171
172 #endif // NET_BASE_NTLM_BUFFER_READER_H_
OLDNEW
« no previous file with comments | « net/BUILD.gn ('k') | net/http/ntlm_buffer_reader.cc » ('j') | net/http/ntlm_buffer_reader.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698