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

Side by Side Diff: net/http/ntlm_buffer_writer.cc

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 #include "net/http/ntlm_buffer_writer.h"
6
7 #include <string.h>
8
9 #include "base/logging.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12
13 #if defined(ARCH_CPU_LITTLE_ENDIAN)
14 #define IS_LITTLE_ENDIAN 1
15 #undef IS_BIG_ENDIAN
16 #elif defined(ARCH_CPU_BIG_ENDIAN)
17 #define IS_BIG_ENDIAN 1
18 #undef IS_LITTLE_ENDIAN
19 #else
20 #error "Unknown endianness"
21 #endif
22
23 namespace net {
24
25 NtlmBufferWriter::NtlmBufferWriter(size_t buffer_len)
26 : buffer_len_(buffer_len), cursor_(0) {
27 buffer_.reset(new uint8_t[buffer_len]);
28 }
29
30 NtlmBufferWriter::~NtlmBufferWriter() {}
31
32 bool NtlmBufferWriter::CanWrite(size_t len) const {
33 if (GetBufferPtr() == nullptr)
34 return false;
35
36 DCHECK(cursor_ <= GetLength());
37
38 if (len == 0)
39 return true;
40
41 return (cursor_ + len > cursor_) && (cursor_ + len <= GetLength());
42 }
43
44 bool NtlmBufferWriter::SetCursor(size_t cursor) {
45 if ((GetBufferPtr() == nullptr) || (cursor > GetLength()))
46 return false;
47
48 cursor_ = cursor;
49 return true;
50 }
51
52 bool NtlmBufferWriter::WriteUInt64(uint64_t value) {
53 return WriteUInt<uint64_t>(value);
54 }
55 bool NtlmBufferWriter::WriteUInt32(uint32_t value) {
56 return WriteUInt<uint32_t>(value);
57 }
58 bool NtlmBufferWriter::WriteUInt16(uint16_t value) {
59 return WriteUInt<uint16_t>(value);
60 }
61
62 template <typename T>
63 bool NtlmBufferWriter::WriteUInt(T value) {
64 size_t int_size = sizeof(T);
65 if (!CanWrite(int_size))
66 return false;
67
68 for (size_t i = 0; i < int_size; i++) {
69 GetBufferPtr()[cursor_++] = static_cast<uint8_t>(value & 0xff);
70 value >>= 8;
71 }
72
73 return true;
74 }
75
76 bool NtlmBufferWriter::WriteBytes(const uint8_t* buffer, size_t len) {
77 if (!CanWrite(len))
78 return false;
79
80 memcpy(reinterpret_cast<void*>(GetBufferPtr() + cursor_),
81 reinterpret_cast<const void*>(buffer), len);
82
83 cursor_ += len;
84 return true;
85 }
86
87 bool NtlmBufferWriter::WriteSecurityBuffer(uint16_t length, uint32_t offset) {
88 if (!CanWrite(NtlmMessage::SECURITY_BUFFER_LEN))
89 return false;
90
91 if (WriteUInt16(length) && WriteUInt16(length) && WriteUInt32(offset))
92 return true;
93
94 NOTREACHED();
95 return false;
96 }
97
98 bool NtlmBufferWriter::WriteEmptySecurityBuffer() {
99 return WriteSecurityBuffer(0, 0);
100 }
101
102 bool NtlmBufferWriter::WriteNarrowString(const std::string& str) {
103 if (!CanWrite(str.length()))
104 return false;
105
106 memcpy(reinterpret_cast<void*>(GetBufferPtr() + cursor_), str.c_str(),
107 str.length());
108 cursor_ += str.length();
109 return true;
110 }
111
112 bool NtlmBufferWriter::WriteString16AsUTF8(const base::string16& str) {
113 // In practice this converts it to UTF8.
114 std::string utf8 = base::SysWideToNativeMB(base::UTF16ToWide(str));
115 return WriteNarrowString(utf8);
116 }
117
118 bool NtlmBufferWriter::WriteUnicodeString(const base::string16& str) {
119 size_t num_bytes = str.length() * 2;
120 if (!CanWrite(num_bytes))
121 return false;
122
123 if (!WriteUnicodeStringIntoBuffer(str, GetBufferPtr() + cursor_, num_bytes))
124 return false;
125
126 cursor_ += num_bytes;
127 return true;
128 }
129
130 bool NtlmBufferWriter::WriteNarrowStringAsString16(const std::string& str) {
131 base::string16 unicode;
132 unicode.assign(str.begin(), str.end());
133 return WriteUnicodeString(unicode);
134 }
135
136 bool NtlmBufferWriter::WriteUnicodeStringIntoBuffer(const base::string16& str,
137 uint8_t* buffer,
138 size_t buffer_len) {
139 // TODO: static??
140 size_t num_bytes = str.length() * 2;
141 if (num_bytes > buffer_len)
142 return false;
143
144 #if IS_BIG_ENDIAN
145 uint8_t* ptr = reinterpret_cast<uint8_t*>(GetBufferPtr() + cursor_);
146
147 for (int i = 0; i < num_bytes; i += 2) {
148 ptr[i] = str[i / 2] % 0xff;
149 ptr[i + 1] = str[i / 2] >> 8;
150 }
151 #else
152 memcpy(reinterpret_cast<void*>(GetBufferPtr() + cursor_), str.c_str(),
153 num_bytes);
154
155 #endif
156 return true;
157 }
158
159 bool NtlmBufferWriter::WriteSignature() {
160 return WriteBytes(NtlmMessage::SIGNATURE, NtlmMessage::SIGNATURE_LEN);
161 }
162
163 bool NtlmBufferWriter::WriteZeros(size_t count) {
164 if (!CanWrite(count))
165 return false;
166
167 memset(GetBufferPtr() + cursor_, 0, count);
168 cursor_ += count;
169 return true;
170 }
171
172 bool NtlmBufferWriter::WriteMessageType(NtlmMessage::MessageType message_type) {
173 return WriteUInt32(message_type);
174 }
175
176 bool NtlmBufferWriter::WriteMessageHeader(
177 NtlmMessage::MessageType message_type) {
178 if (!CanWrite(NtlmMessage::SIGNATURE_LEN + sizeof(uint32_t)))
179 return false;
180
181 if (WriteSignature() && WriteMessageType(message_type))
182 return true;
183
184 NOTREACHED();
185 return false;
186 }
187
188 // static
189 size_t NtlmBufferWriter::GetStringPayloadLength(const base::string16& str,
190 bool is_unicode) {
191 if (is_unicode)
192 return str.length() * 2;
193
194 // When |WriteString16AsUTF8| is called with
195 // a |base::string16| the string is effectively converted to
196 // UTF8 by |base::SysWideToNativeMB|. Do the conversion
197 // to ensure that the character count is correct.
198 return base::SysWideToNativeMB(base::UTF16ToWide(str)).length();
199 }
200
201 // static
202 size_t NtlmBufferWriter::GetStringPayloadLength(const std::string& str,
203 bool is_unicode) {
204 // When |WriteUnicodePayload| is called with a |std::string|
205 // the string is assumed ASCII and the characters are zero-padded.
206 return is_unicode ? str.length() * 2 : str.length();
207 }
208
209 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698