OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_auth_gssapi_posix.h" | 5 #include "net/http/http_auth_gssapi_posix.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/threading/thread_restrictions.h" | 16 #include "base/threading/thread_restrictions.h" |
17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
18 #include "net/base/net_util.h" | 18 #include "net/base/net_util.h" |
19 #include "net/http/http_auth_challenge_tokenizer.h" | 19 #include "net/http/http_auth_challenge_tokenizer.h" |
20 | 20 |
21 // These are defined for the GSSAPI library: | 21 // These are defined for the GSSAPI library: |
22 // Paraphrasing the comments from gssapi.h: | 22 // Paraphrasing the comments from gssapi.h: |
23 // "The implementation must reserve static storage for a | 23 // "The implementation must reserve static storage for a |
24 // gss_OID_desc object for each constant. That constant | 24 // gss_OID_desc object for each constant. That constant |
25 // should be initialized to point to that gss_OID_desc." | 25 // should be initialized to point to that gss_OID_desc." |
26 // These are encoded using ASN.1 BER encoding. | 26 // These are encoded using ASN.1 BER encoding. |
27 namespace { | 27 namespace { |
28 | 28 |
29 static gss_OID_desc GSS_C_NT_USER_NAME_VAL = { | 29 static gss_OID_desc GSS_C_NT_USER_NAME_VAL = { |
30 10, | 30 10, const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01")}; |
31 const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01") | |
32 }; | |
33 static gss_OID_desc GSS_C_NT_MACHINE_UID_NAME_VAL = { | 31 static gss_OID_desc GSS_C_NT_MACHINE_UID_NAME_VAL = { |
34 10, | 32 10, const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02")}; |
35 const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02") | |
36 }; | |
37 static gss_OID_desc GSS_C_NT_STRING_UID_NAME_VAL = { | 33 static gss_OID_desc GSS_C_NT_STRING_UID_NAME_VAL = { |
38 10, | 34 10, const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")}; |
39 const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03") | |
40 }; | |
41 static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_X_VAL = { | 35 static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_X_VAL = { |
42 6, | 36 6, const_cast<char*>("\x2b\x06\x01\x05\x06\x02")}; |
43 const_cast<char*>("\x2b\x06\x01\x05\x06\x02") | |
44 }; | |
45 static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_VAL = { | 37 static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_VAL = { |
46 10, | 38 10, const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")}; |
47 const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04") | |
48 }; | |
49 static gss_OID_desc GSS_C_NT_ANONYMOUS_VAL = { | 39 static gss_OID_desc GSS_C_NT_ANONYMOUS_VAL = { |
50 6, | 40 6, const_cast<char*>("\x2b\x06\01\x05\x06\x03")}; |
51 const_cast<char*>("\x2b\x06\01\x05\x06\x03") | |
52 }; | |
53 static gss_OID_desc GSS_C_NT_EXPORT_NAME_VAL = { | 41 static gss_OID_desc GSS_C_NT_EXPORT_NAME_VAL = { |
54 6, | 42 6, const_cast<char*>("\x2b\x06\x01\x05\x06\x04")}; |
55 const_cast<char*>("\x2b\x06\x01\x05\x06\x04") | |
56 }; | |
57 | 43 |
58 } // namespace | 44 } // namespace |
59 | 45 |
60 // Heimdal >= 1.4 will define the following as preprocessor macros. | 46 // Heimdal >= 1.4 will define the following as preprocessor macros. |
61 // To avoid conflicting declarations, we have to undefine these. | 47 // To avoid conflicting declarations, we have to undefine these. |
62 #undef GSS_C_NT_USER_NAME | 48 #undef GSS_C_NT_USER_NAME |
63 #undef GSS_C_NT_MACHINE_UID_NAME | 49 #undef GSS_C_NT_MACHINE_UID_NAME |
64 #undef GSS_C_NT_STRING_UID_NAME | 50 #undef GSS_C_NT_STRING_UID_NAME |
65 #undef GSS_C_NT_HOSTBASED_SERVICE_X | 51 #undef GSS_C_NT_HOSTBASED_SERVICE_X |
66 #undef GSS_C_NT_HOSTBASED_SERVICE | 52 #undef GSS_C_NT_HOSTBASED_SERVICE |
67 #undef GSS_C_NT_ANONYMOUS | 53 #undef GSS_C_NT_ANONYMOUS |
68 #undef GSS_C_NT_EXPORT_NAME | 54 #undef GSS_C_NT_EXPORT_NAME |
69 | 55 |
70 gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_VAL; | 56 gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_VAL; |
71 gss_OID GSS_C_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_VAL; | 57 gss_OID GSS_C_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_VAL; |
72 gss_OID GSS_C_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_VAL; | 58 gss_OID GSS_C_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_VAL; |
73 gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &GSS_C_NT_HOSTBASED_SERVICE_X_VAL; | 59 gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &GSS_C_NT_HOSTBASED_SERVICE_X_VAL; |
74 gss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_VAL; | 60 gss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_VAL; |
75 gss_OID GSS_C_NT_ANONYMOUS = &GSS_C_NT_ANONYMOUS_VAL; | 61 gss_OID GSS_C_NT_ANONYMOUS = &GSS_C_NT_ANONYMOUS_VAL; |
76 gss_OID GSS_C_NT_EXPORT_NAME = &GSS_C_NT_EXPORT_NAME_VAL; | 62 gss_OID GSS_C_NT_EXPORT_NAME = &GSS_C_NT_EXPORT_NAME_VAL; |
77 | 63 |
78 namespace net { | 64 namespace net { |
79 | 65 |
80 // Exported mechanism for GSSAPI. We always use SPNEGO: | 66 // Exported mechanism for GSSAPI. We always use SPNEGO: |
81 | 67 |
82 // iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2) | 68 // iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2) |
83 gss_OID_desc CHROME_GSS_SPNEGO_MECH_OID_DESC_VAL = { | 69 gss_OID_desc CHROME_GSS_SPNEGO_MECH_OID_DESC_VAL = { |
84 6, | 70 6, const_cast<char*>("\x2b\x06\x01\x05\x05\x02")}; |
85 const_cast<char*>("\x2b\x06\x01\x05\x05\x02") | |
86 }; | |
87 | 71 |
88 gss_OID CHROME_GSS_SPNEGO_MECH_OID_DESC = | 72 gss_OID CHROME_GSS_SPNEGO_MECH_OID_DESC = &CHROME_GSS_SPNEGO_MECH_OID_DESC_VAL; |
89 &CHROME_GSS_SPNEGO_MECH_OID_DESC_VAL; | |
90 | 73 |
91 // Debugging helpers. | 74 // Debugging helpers. |
92 namespace { | 75 namespace { |
93 | 76 |
94 std::string DisplayStatus(OM_uint32 major_status, | 77 std::string DisplayStatus(OM_uint32 major_status, OM_uint32 minor_status) { |
95 OM_uint32 minor_status) { | |
96 if (major_status == GSS_S_COMPLETE) | 78 if (major_status == GSS_S_COMPLETE) |
97 return "OK"; | 79 return "OK"; |
98 return base::StringPrintf("0x%08X 0x%08X", major_status, minor_status); | 80 return base::StringPrintf("0x%08X 0x%08X", major_status, minor_status); |
99 } | 81 } |
100 | 82 |
101 std::string DisplayCode(GSSAPILibrary* gssapi_lib, | 83 std::string DisplayCode(GSSAPILibrary* gssapi_lib, |
102 OM_uint32 status, | 84 OM_uint32 status, |
103 OM_uint32 status_code_type) { | 85 OM_uint32 status_code_type) { |
104 const int kMaxDisplayIterations = 8; | 86 const int kMaxDisplayIterations = 8; |
105 const size_t kMaxMsgLength = 4096; | 87 const size_t kMaxMsgLength = 4096; |
106 // msg_ctx needs to be outside the loop because it is invoked multiple times. | 88 // msg_ctx needs to be outside the loop because it is invoked multiple times. |
107 OM_uint32 msg_ctx = 0; | 89 OM_uint32 msg_ctx = 0; |
108 std::string rv = base::StringPrintf("(0x%08X)", status); | 90 std::string rv = base::StringPrintf("(0x%08X)", status); |
109 | 91 |
110 // This loop should continue iterating until msg_ctx is 0 after the first | 92 // This loop should continue iterating until msg_ctx is 0 after the first |
111 // iteration. To be cautious and prevent an infinite loop, it stops after | 93 // iteration. To be cautious and prevent an infinite loop, it stops after |
112 // a finite number of iterations as well. As an added sanity check, no | 94 // a finite number of iterations as well. As an added sanity check, no |
113 // individual message may exceed |kMaxMsgLength|, and the final result | 95 // individual message may exceed |kMaxMsgLength|, and the final result |
114 // will not exceed |kMaxMsgLength|*2-1. | 96 // will not exceed |kMaxMsgLength|*2-1. |
115 for (int i = 0; i < kMaxDisplayIterations && rv.size() < kMaxMsgLength; | 97 for (int i = 0; i < kMaxDisplayIterations && rv.size() < kMaxMsgLength; ++i) { |
116 ++i) { | |
117 OM_uint32 min_stat; | 98 OM_uint32 min_stat; |
118 gss_buffer_desc_struct msg = GSS_C_EMPTY_BUFFER; | 99 gss_buffer_desc_struct msg = GSS_C_EMPTY_BUFFER; |
119 OM_uint32 maj_stat = | 100 OM_uint32 maj_stat = gssapi_lib->display_status( |
120 gssapi_lib->display_status(&min_stat, status, status_code_type, | 101 &min_stat, status, status_code_type, GSS_C_NULL_OID, &msg_ctx, &msg); |
121 GSS_C_NULL_OID, &msg_ctx, &msg); | |
122 if (maj_stat == GSS_S_COMPLETE) { | 102 if (maj_stat == GSS_S_COMPLETE) { |
123 int msg_len = (msg.length > kMaxMsgLength) ? | 103 int msg_len = (msg.length > kMaxMsgLength) |
124 static_cast<int>(kMaxMsgLength) : | 104 ? static_cast<int>(kMaxMsgLength) |
125 static_cast<int>(msg.length); | 105 : static_cast<int>(msg.length); |
126 if (msg_len > 0 && msg.value != NULL) { | 106 if (msg_len > 0 && msg.value != NULL) { |
127 rv += base::StringPrintf(" %.*s", msg_len, | 107 rv += |
128 static_cast<char*>(msg.value)); | 108 base::StringPrintf(" %.*s", msg_len, static_cast<char*>(msg.value)); |
129 } | 109 } |
130 } | 110 } |
131 gssapi_lib->release_buffer(&min_stat, &msg); | 111 gssapi_lib->release_buffer(&min_stat, &msg); |
132 if (!msg_ctx) | 112 if (!msg_ctx) |
133 break; | 113 break; |
134 } | 114 } |
135 return rv; | 115 return rv; |
136 } | 116 } |
137 | 117 |
138 std::string DisplayExtendedStatus(GSSAPILibrary* gssapi_lib, | 118 std::string DisplayExtendedStatus(GSSAPILibrary* gssapi_lib, |
139 OM_uint32 major_status, | 119 OM_uint32 major_status, |
140 OM_uint32 minor_status) { | 120 OM_uint32 minor_status) { |
141 if (major_status == GSS_S_COMPLETE) | 121 if (major_status == GSS_S_COMPLETE) |
142 return "OK"; | 122 return "OK"; |
143 std::string major = DisplayCode(gssapi_lib, major_status, GSS_C_GSS_CODE); | 123 std::string major = DisplayCode(gssapi_lib, major_status, GSS_C_GSS_CODE); |
144 std::string minor = DisplayCode(gssapi_lib, minor_status, GSS_C_MECH_CODE); | 124 std::string minor = DisplayCode(gssapi_lib, minor_status, GSS_C_MECH_CODE); |
145 return base::StringPrintf("Major: %s | Minor: %s", major.c_str(), | 125 return base::StringPrintf( |
146 minor.c_str()); | 126 "Major: %s | Minor: %s", major.c_str(), minor.c_str()); |
147 } | 127 } |
148 | 128 |
149 // ScopedName releases a gss_name_t when it goes out of scope. | 129 // ScopedName releases a gss_name_t when it goes out of scope. |
150 class ScopedName { | 130 class ScopedName { |
151 public: | 131 public: |
152 ScopedName(gss_name_t name, | 132 ScopedName(gss_name_t name, GSSAPILibrary* gssapi_lib) |
153 GSSAPILibrary* gssapi_lib) | 133 : name_(name), gssapi_lib_(gssapi_lib) { |
154 : name_(name), | |
155 gssapi_lib_(gssapi_lib) { | |
156 DCHECK(gssapi_lib_); | 134 DCHECK(gssapi_lib_); |
157 } | 135 } |
158 | 136 |
159 ~ScopedName() { | 137 ~ScopedName() { |
160 if (name_ != GSS_C_NO_NAME) { | 138 if (name_ != GSS_C_NO_NAME) { |
161 OM_uint32 minor_status = 0; | 139 OM_uint32 minor_status = 0; |
162 OM_uint32 major_status = | 140 OM_uint32 major_status = gssapi_lib_->release_name(&minor_status, &name_); |
163 gssapi_lib_->release_name(&minor_status, &name_); | |
164 if (major_status != GSS_S_COMPLETE) { | 141 if (major_status != GSS_S_COMPLETE) { |
165 LOG(WARNING) << "Problem releasing name. " | 142 LOG(WARNING) << "Problem releasing name. " |
166 << DisplayStatus(major_status, minor_status); | 143 << DisplayStatus(major_status, minor_status); |
167 } | 144 } |
168 name_ = GSS_C_NO_NAME; | 145 name_ = GSS_C_NO_NAME; |
169 } | 146 } |
170 } | 147 } |
171 | 148 |
172 private: | 149 private: |
173 gss_name_t name_; | 150 gss_name_t name_; |
174 GSSAPILibrary* gssapi_lib_; | 151 GSSAPILibrary* gssapi_lib_; |
175 | 152 |
176 DISALLOW_COPY_AND_ASSIGN(ScopedName); | 153 DISALLOW_COPY_AND_ASSIGN(ScopedName); |
177 }; | 154 }; |
178 | 155 |
179 // ScopedBuffer releases a gss_buffer_t when it goes out of scope. | 156 // ScopedBuffer releases a gss_buffer_t when it goes out of scope. |
180 class ScopedBuffer { | 157 class ScopedBuffer { |
181 public: | 158 public: |
182 ScopedBuffer(gss_buffer_t buffer, | 159 ScopedBuffer(gss_buffer_t buffer, GSSAPILibrary* gssapi_lib) |
183 GSSAPILibrary* gssapi_lib) | 160 : buffer_(buffer), gssapi_lib_(gssapi_lib) { |
184 : buffer_(buffer), | |
185 gssapi_lib_(gssapi_lib) { | |
186 DCHECK(gssapi_lib_); | 161 DCHECK(gssapi_lib_); |
187 } | 162 } |
188 | 163 |
189 ~ScopedBuffer() { | 164 ~ScopedBuffer() { |
190 if (buffer_ != GSS_C_NO_BUFFER) { | 165 if (buffer_ != GSS_C_NO_BUFFER) { |
191 OM_uint32 minor_status = 0; | 166 OM_uint32 minor_status = 0; |
192 OM_uint32 major_status = | 167 OM_uint32 major_status = |
193 gssapi_lib_->release_buffer(&minor_status, buffer_); | 168 gssapi_lib_->release_buffer(&minor_status, buffer_); |
194 if (major_status != GSS_S_COMPLETE) { | 169 if (major_status != GSS_S_COMPLETE) { |
195 LOG(WARNING) << "Problem releasing buffer. " | 170 LOG(WARNING) << "Problem releasing buffer. " |
(...skipping 14 matching lines...) Expand all Loading... |
210 | 185 |
211 std::string AppendIfPredefinedValue(gss_OID oid, | 186 std::string AppendIfPredefinedValue(gss_OID oid, |
212 gss_OID predefined_oid, | 187 gss_OID predefined_oid, |
213 const char* predefined_oid_name) { | 188 const char* predefined_oid_name) { |
214 DCHECK(oid); | 189 DCHECK(oid); |
215 DCHECK(predefined_oid); | 190 DCHECK(predefined_oid); |
216 DCHECK(predefined_oid_name); | 191 DCHECK(predefined_oid_name); |
217 std::string output; | 192 std::string output; |
218 if (oid->length != predefined_oid->length) | 193 if (oid->length != predefined_oid->length) |
219 return output; | 194 return output; |
220 if (0 != memcmp(oid->elements, | 195 if (0 != |
221 predefined_oid->elements, | 196 memcmp(oid->elements, predefined_oid->elements, predefined_oid->length)) |
222 predefined_oid->length)) | |
223 return output; | 197 return output; |
224 | 198 |
225 output += " ("; | 199 output += " ("; |
226 output += predefined_oid_name; | 200 output += predefined_oid_name; |
227 output += ")"; | 201 output += ")"; |
228 return output; | 202 return output; |
229 } | 203 } |
230 | 204 |
231 } // namespace | 205 } // namespace |
232 | 206 |
233 std::string DescribeOid(GSSAPILibrary* gssapi_lib, const gss_OID oid) { | 207 std::string DescribeOid(GSSAPILibrary* gssapi_lib, const gss_OID oid) { |
234 if (!oid) | 208 if (!oid) |
235 return "<NULL>"; | 209 return "<NULL>"; |
236 std::string output; | 210 std::string output; |
237 const size_t kMaxCharsToPrint = 1024; | 211 const size_t kMaxCharsToPrint = 1024; |
238 OM_uint32 byte_length = oid->length; | 212 OM_uint32 byte_length = oid->length; |
239 size_t char_length = byte_length / sizeof(char); | 213 size_t char_length = byte_length / sizeof(char); |
240 if (char_length > kMaxCharsToPrint) { | 214 if (char_length > kMaxCharsToPrint) { |
241 // This might be a plain ASCII string. | 215 // This might be a plain ASCII string. |
242 // Check if the first |kMaxCharsToPrint| characters | 216 // Check if the first |kMaxCharsToPrint| characters |
243 // contain only printable characters and are NULL terminated. | 217 // contain only printable characters and are NULL terminated. |
244 const char* str = reinterpret_cast<const char*>(oid); | 218 const char* str = reinterpret_cast<const char*>(oid); |
245 size_t str_length = 0; | 219 size_t str_length = 0; |
246 for ( ; str_length < kMaxCharsToPrint; ++str_length) { | 220 for (; str_length < kMaxCharsToPrint; ++str_length) { |
247 if (!str[str_length] || !isprint(str[str_length])) | 221 if (!str[str_length] || !isprint(str[str_length])) |
248 break; | 222 break; |
249 } | 223 } |
250 if (!str[str_length]) { | 224 if (!str[str_length]) { |
251 output += base::StringPrintf("\"%s\"", str); | 225 output += base::StringPrintf("\"%s\"", str); |
252 return output; | 226 return output; |
253 } | 227 } |
254 } | 228 } |
255 output = base::StringPrintf("(%u) \"", byte_length); | 229 output = base::StringPrintf("(%u) \"", byte_length); |
256 if (!oid->elements) { | 230 if (!oid->elements) { |
257 output += "<NULL>"; | 231 output += "<NULL>"; |
258 return output; | 232 return output; |
259 } | 233 } |
260 const unsigned char* elements = | 234 const unsigned char* elements = |
261 reinterpret_cast<const unsigned char*>(oid->elements); | 235 reinterpret_cast<const unsigned char*>(oid->elements); |
262 // Don't print more than |kMaxCharsToPrint| characters. | 236 // Don't print more than |kMaxCharsToPrint| characters. |
263 size_t i = 0; | 237 size_t i = 0; |
264 for ( ; (i < byte_length) && (i < kMaxCharsToPrint); ++i) { | 238 for (; (i < byte_length) && (i < kMaxCharsToPrint); ++i) { |
265 output += base::StringPrintf("\\x%02X", elements[i]); | 239 output += base::StringPrintf("\\x%02X", elements[i]); |
266 } | 240 } |
267 if (i >= kMaxCharsToPrint) | 241 if (i >= kMaxCharsToPrint) |
268 output += "..."; | 242 output += "..."; |
269 output += "\""; | 243 output += "\""; |
270 | 244 |
271 // Check if the OID is one of the predefined values. | 245 // Check if the OID is one of the predefined values. |
272 output += AppendIfPredefinedValue(oid, | 246 output += |
273 GSS_C_NT_USER_NAME, | 247 AppendIfPredefinedValue(oid, GSS_C_NT_USER_NAME, "GSS_C_NT_USER_NAME"); |
274 "GSS_C_NT_USER_NAME"); | 248 output += AppendIfPredefinedValue( |
275 output += AppendIfPredefinedValue(oid, | 249 oid, GSS_C_NT_MACHINE_UID_NAME, "GSS_C_NT_MACHINE_UID_NAME"); |
276 GSS_C_NT_MACHINE_UID_NAME, | 250 output += AppendIfPredefinedValue( |
277 "GSS_C_NT_MACHINE_UID_NAME"); | 251 oid, GSS_C_NT_STRING_UID_NAME, "GSS_C_NT_STRING_UID_NAME"); |
278 output += AppendIfPredefinedValue(oid, | 252 output += AppendIfPredefinedValue( |
279 GSS_C_NT_STRING_UID_NAME, | 253 oid, GSS_C_NT_HOSTBASED_SERVICE_X, "GSS_C_NT_HOSTBASED_SERVICE_X"); |
280 "GSS_C_NT_STRING_UID_NAME"); | 254 output += AppendIfPredefinedValue( |
281 output += AppendIfPredefinedValue(oid, | 255 oid, GSS_C_NT_HOSTBASED_SERVICE, "GSS_C_NT_HOSTBASED_SERVICE"); |
282 GSS_C_NT_HOSTBASED_SERVICE_X, | 256 output += |
283 "GSS_C_NT_HOSTBASED_SERVICE_X"); | 257 AppendIfPredefinedValue(oid, GSS_C_NT_ANONYMOUS, "GSS_C_NT_ANONYMOUS"); |
284 output += AppendIfPredefinedValue(oid, | 258 output += AppendIfPredefinedValue( |
285 GSS_C_NT_HOSTBASED_SERVICE, | 259 oid, GSS_C_NT_EXPORT_NAME, "GSS_C_NT_EXPORT_NAME"); |
286 "GSS_C_NT_HOSTBASED_SERVICE"); | |
287 output += AppendIfPredefinedValue(oid, | |
288 GSS_C_NT_ANONYMOUS, | |
289 "GSS_C_NT_ANONYMOUS"); | |
290 output += AppendIfPredefinedValue(oid, | |
291 GSS_C_NT_EXPORT_NAME, | |
292 "GSS_C_NT_EXPORT_NAME"); | |
293 | 260 |
294 return output; | 261 return output; |
295 } | 262 } |
296 | 263 |
297 std::string DescribeName(GSSAPILibrary* gssapi_lib, const gss_name_t name) { | 264 std::string DescribeName(GSSAPILibrary* gssapi_lib, const gss_name_t name) { |
298 OM_uint32 major_status = 0; | 265 OM_uint32 major_status = 0; |
299 OM_uint32 minor_status = 0; | 266 OM_uint32 minor_status = 0; |
300 gss_buffer_desc_struct output_name_buffer = GSS_C_EMPTY_BUFFER; | 267 gss_buffer_desc_struct output_name_buffer = GSS_C_EMPTY_BUFFER; |
301 gss_OID_desc output_name_type_desc = GSS_C_EMPTY_BUFFER; | 268 gss_OID_desc output_name_type_desc = GSS_C_EMPTY_BUFFER; |
302 gss_OID output_name_type = &output_name_type_desc; | 269 gss_OID output_name_type = &output_name_type_desc; |
303 major_status = gssapi_lib->display_name(&minor_status, | 270 major_status = gssapi_lib->display_name( |
304 name, | 271 &minor_status, name, &output_name_buffer, &output_name_type); |
305 &output_name_buffer, | |
306 &output_name_type); | |
307 ScopedBuffer scoped_output_name(&output_name_buffer, gssapi_lib); | 272 ScopedBuffer scoped_output_name(&output_name_buffer, gssapi_lib); |
308 if (major_status != GSS_S_COMPLETE) { | 273 if (major_status != GSS_S_COMPLETE) { |
309 std::string error = | 274 std::string error = base::StringPrintf( |
310 base::StringPrintf("Unable to describe name 0x%p, %s", | 275 "Unable to describe name 0x%p, %s", |
311 name, | 276 name, |
312 DisplayExtendedStatus(gssapi_lib, | 277 DisplayExtendedStatus(gssapi_lib, major_status, minor_status).c_str()); |
313 major_status, | |
314 minor_status).c_str()); | |
315 return error; | 278 return error; |
316 } | 279 } |
317 int len = output_name_buffer.length; | 280 int len = output_name_buffer.length; |
318 std::string description = base::StringPrintf( | 281 std::string description = base::StringPrintf( |
319 "%*s (Type %s)", | 282 "%*s (Type %s)", |
320 len, | 283 len, |
321 reinterpret_cast<const char*>(output_name_buffer.value), | 284 reinterpret_cast<const char*>(output_name_buffer.value), |
322 DescribeOid(gssapi_lib, output_name_type).c_str()); | 285 DescribeOid(gssapi_lib, output_name_type).c_str()); |
323 return description; | 286 return description; |
324 } | 287 } |
(...skipping 16 matching lines...) Expand all Loading... |
341 &src_name, | 304 &src_name, |
342 &targ_name, | 305 &targ_name, |
343 &lifetime_rec, | 306 &lifetime_rec, |
344 &mech_type, | 307 &mech_type, |
345 &ctx_flags, | 308 &ctx_flags, |
346 &locally_initiated, | 309 &locally_initiated, |
347 &open); | 310 &open); |
348 ScopedName(src_name, gssapi_lib); | 311 ScopedName(src_name, gssapi_lib); |
349 ScopedName(targ_name, gssapi_lib); | 312 ScopedName(targ_name, gssapi_lib); |
350 if (major_status != GSS_S_COMPLETE) { | 313 if (major_status != GSS_S_COMPLETE) { |
351 std::string error = | 314 std::string error = base::StringPrintf( |
352 base::StringPrintf("Unable to describe context 0x%p, %s", | 315 "Unable to describe context 0x%p, %s", |
353 context_handle, | 316 context_handle, |
354 DisplayExtendedStatus(gssapi_lib, | 317 DisplayExtendedStatus(gssapi_lib, major_status, minor_status).c_str()); |
355 major_status, | |
356 minor_status).c_str()); | |
357 return error; | 318 return error; |
358 } | 319 } |
359 std::string source(DescribeName(gssapi_lib, src_name)); | 320 std::string source(DescribeName(gssapi_lib, src_name)); |
360 std::string target(DescribeName(gssapi_lib, targ_name)); | 321 std::string target(DescribeName(gssapi_lib, targ_name)); |
361 std::string description = base::StringPrintf("Context 0x%p: " | 322 std::string description = base::StringPrintf( |
362 "Source \"%s\", " | 323 "Context 0x%p: " |
363 "Target \"%s\", " | 324 "Source \"%s\", " |
364 "lifetime %d, " | 325 "Target \"%s\", " |
365 "mechanism %s, " | 326 "lifetime %d, " |
366 "flags 0x%08X, " | 327 "mechanism %s, " |
367 "local %d, " | 328 "flags 0x%08X, " |
368 "open %d", | 329 "local %d, " |
369 context_handle, | 330 "open %d", |
370 source.c_str(), | 331 context_handle, |
371 target.c_str(), | 332 source.c_str(), |
372 lifetime_rec, | 333 target.c_str(), |
373 DescribeOid(gssapi_lib, | 334 lifetime_rec, |
374 mech_type).c_str(), | 335 DescribeOid(gssapi_lib, mech_type).c_str(), |
375 ctx_flags, | 336 ctx_flags, |
376 locally_initiated, | 337 locally_initiated, |
377 open); | 338 open); |
378 return description; | 339 return description; |
379 } | 340 } |
380 | 341 |
381 } // namespace | 342 } // namespace |
382 | 343 |
383 GSSAPISharedLibrary::GSSAPISharedLibrary(const std::string& gssapi_library_name) | 344 GSSAPISharedLibrary::GSSAPISharedLibrary(const std::string& gssapi_library_name) |
384 : initialized_(false), | 345 : initialized_(false), |
385 gssapi_library_name_(gssapi_library_name), | 346 gssapi_library_name_(gssapi_library_name), |
386 gssapi_library_(NULL), | 347 gssapi_library_(NULL), |
387 import_name_(NULL), | 348 import_name_(NULL), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 const char* user_specified_library[1]; | 386 const char* user_specified_library[1]; |
426 if (!gssapi_library_name_.empty()) { | 387 if (!gssapi_library_name_.empty()) { |
427 user_specified_library[0] = gssapi_library_name_.c_str(); | 388 user_specified_library[0] = gssapi_library_name_.c_str(); |
428 library_names = user_specified_library; | 389 library_names = user_specified_library; |
429 num_lib_names = 1; | 390 num_lib_names = 1; |
430 } else { | 391 } else { |
431 static const char* const kDefaultLibraryNames[] = { | 392 static const char* const kDefaultLibraryNames[] = { |
432 #if defined(OS_MACOSX) | 393 #if defined(OS_MACOSX) |
433 "libgssapi_krb5.dylib" // MIT Kerberos | 394 "libgssapi_krb5.dylib" // MIT Kerberos |
434 #elif defined(OS_OPENBSD) | 395 #elif defined(OS_OPENBSD) |
435 "libgssapi.so" // Heimdal - OpenBSD | 396 "libgssapi.so" // Heimdal - OpenBSD |
436 #else | 397 #else |
437 "libgssapi_krb5.so.2", // MIT Kerberos - FC, Suse10, Debian | 398 "libgssapi_krb5.so.2", // MIT Kerberos - FC, Suse10, Debian |
438 "libgssapi.so.4", // Heimdal - Suse10, MDK | 399 "libgssapi.so.4", // Heimdal - Suse10, MDK |
439 "libgssapi.so.2", // Heimdal - Gentoo | 400 "libgssapi.so.2", // Heimdal - Gentoo |
440 "libgssapi.so.1" // Heimdal - Suse9, CITI - FC, MDK, Suse10 | 401 "libgssapi.so.1" // Heimdal - Suse9, CITI - FC, MDK, Suse10 |
441 #endif | 402 #endif |
442 }; | 403 }; |
443 library_names = kDefaultLibraryNames; | 404 library_names = kDefaultLibraryNames; |
444 num_lib_names = arraysize(kDefaultLibraryNames); | 405 num_lib_names = arraysize(kDefaultLibraryNames); |
445 } | 406 } |
(...skipping 11 matching lines...) Expand all Loading... |
457 if (BindMethods(lib)) | 418 if (BindMethods(lib)) |
458 return lib; | 419 return lib; |
459 base::UnloadNativeLibrary(lib); | 420 base::UnloadNativeLibrary(lib); |
460 } | 421 } |
461 } | 422 } |
462 LOG(WARNING) << "Unable to find a compatible GSSAPI library"; | 423 LOG(WARNING) << "Unable to find a compatible GSSAPI library"; |
463 return NULL; | 424 return NULL; |
464 } | 425 } |
465 | 426 |
466 #if defined(DLOPEN_KERBEROS) | 427 #if defined(DLOPEN_KERBEROS) |
467 #define BIND(lib, x) \ | 428 #define BIND(lib, x) \ |
468 DCHECK(lib); \ | 429 DCHECK(lib); \ |
469 gss_##x##_type x = reinterpret_cast<gss_##x##_type>( \ | 430 gss_##x##_type x = reinterpret_cast<gss_##x##_type>( \ |
470 base::GetFunctionPointerFromNativeLibrary(lib, "gss_" #x)); \ | 431 base::GetFunctionPointerFromNativeLibrary(lib, "gss_" #x)); \ |
471 if (x == NULL) { \ | 432 if (x == NULL) { \ |
472 LOG(WARNING) << "Unable to bind function \"" << "gss_" #x << "\""; \ | 433 LOG(WARNING) << "Unable to bind function \"" \ |
473 return false; \ | 434 << "gss_" #x << "\""; \ |
| 435 return false; \ |
474 } | 436 } |
475 #else | 437 #else |
476 #define BIND(lib, x) gss_##x##_type x = gss_##x | 438 #define BIND(lib, x) gss_##x##_type x = gss_##x |
477 #endif | 439 #endif |
478 | 440 |
479 bool GSSAPISharedLibrary::BindMethods(base::NativeLibrary lib) { | 441 bool GSSAPISharedLibrary::BindMethods(base::NativeLibrary lib) { |
480 BIND(lib, import_name); | 442 BIND(lib, import_name); |
481 BIND(lib, release_name); | 443 BIND(lib, release_name); |
482 BIND(lib, release_buffer); | 444 BIND(lib, release_buffer); |
483 BIND(lib, display_name); | 445 BIND(lib, display_name); |
(...skipping 11 matching lines...) Expand all Loading... |
495 init_sec_context_ = init_sec_context; | 457 init_sec_context_ = init_sec_context; |
496 wrap_size_limit_ = wrap_size_limit; | 458 wrap_size_limit_ = wrap_size_limit; |
497 delete_sec_context_ = delete_sec_context; | 459 delete_sec_context_ = delete_sec_context; |
498 inquire_context_ = inquire_context; | 460 inquire_context_ = inquire_context; |
499 | 461 |
500 return true; | 462 return true; |
501 } | 463 } |
502 | 464 |
503 #undef BIND | 465 #undef BIND |
504 | 466 |
505 OM_uint32 GSSAPISharedLibrary::import_name( | 467 OM_uint32 GSSAPISharedLibrary::import_name(OM_uint32* minor_status, |
506 OM_uint32* minor_status, | 468 const gss_buffer_t input_name_buffer, |
507 const gss_buffer_t input_name_buffer, | 469 const gss_OID input_name_type, |
508 const gss_OID input_name_type, | 470 gss_name_t* output_name) { |
509 gss_name_t* output_name) { | |
510 DCHECK(initialized_); | 471 DCHECK(initialized_); |
511 return import_name_(minor_status, input_name_buffer, input_name_type, | 472 return import_name_( |
512 output_name); | 473 minor_status, input_name_buffer, input_name_type, output_name); |
513 } | 474 } |
514 | 475 |
515 OM_uint32 GSSAPISharedLibrary::release_name( | 476 OM_uint32 GSSAPISharedLibrary::release_name(OM_uint32* minor_status, |
516 OM_uint32* minor_status, | 477 gss_name_t* input_name) { |
517 gss_name_t* input_name) { | |
518 DCHECK(initialized_); | 478 DCHECK(initialized_); |
519 return release_name_(minor_status, input_name); | 479 return release_name_(minor_status, input_name); |
520 } | 480 } |
521 | 481 |
522 OM_uint32 GSSAPISharedLibrary::release_buffer( | 482 OM_uint32 GSSAPISharedLibrary::release_buffer(OM_uint32* minor_status, |
523 OM_uint32* minor_status, | 483 gss_buffer_t buffer) { |
524 gss_buffer_t buffer) { | |
525 DCHECK(initialized_); | 484 DCHECK(initialized_); |
526 return release_buffer_(minor_status, buffer); | 485 return release_buffer_(minor_status, buffer); |
527 } | 486 } |
528 | 487 |
529 OM_uint32 GSSAPISharedLibrary::display_name( | 488 OM_uint32 GSSAPISharedLibrary::display_name(OM_uint32* minor_status, |
530 OM_uint32* minor_status, | 489 const gss_name_t input_name, |
531 const gss_name_t input_name, | 490 gss_buffer_t output_name_buffer, |
532 gss_buffer_t output_name_buffer, | 491 gss_OID* output_name_type) { |
533 gss_OID* output_name_type) { | |
534 DCHECK(initialized_); | 492 DCHECK(initialized_); |
535 return display_name_(minor_status, | 493 return display_name_( |
536 input_name, | 494 minor_status, input_name, output_name_buffer, output_name_type); |
537 output_name_buffer, | |
538 output_name_type); | |
539 } | 495 } |
540 | 496 |
541 OM_uint32 GSSAPISharedLibrary::display_status( | 497 OM_uint32 GSSAPISharedLibrary::display_status(OM_uint32* minor_status, |
542 OM_uint32* minor_status, | 498 OM_uint32 status_value, |
543 OM_uint32 status_value, | 499 int status_type, |
544 int status_type, | 500 const gss_OID mech_type, |
545 const gss_OID mech_type, | 501 OM_uint32* message_context, |
546 OM_uint32* message_context, | 502 gss_buffer_t status_string) { |
547 gss_buffer_t status_string) { | |
548 DCHECK(initialized_); | 503 DCHECK(initialized_); |
549 return display_status_(minor_status, status_value, status_type, mech_type, | 504 return display_status_(minor_status, |
550 message_context, status_string); | 505 status_value, |
| 506 status_type, |
| 507 mech_type, |
| 508 message_context, |
| 509 status_string); |
551 } | 510 } |
552 | 511 |
553 OM_uint32 GSSAPISharedLibrary::init_sec_context( | 512 OM_uint32 GSSAPISharedLibrary::init_sec_context( |
554 OM_uint32* minor_status, | 513 OM_uint32* minor_status, |
555 const gss_cred_id_t initiator_cred_handle, | 514 const gss_cred_id_t initiator_cred_handle, |
556 gss_ctx_id_t* context_handle, | 515 gss_ctx_id_t* context_handle, |
557 const gss_name_t target_name, | 516 const gss_name_t target_name, |
558 const gss_OID mech_type, | 517 const gss_OID mech_type, |
559 OM_uint32 req_flags, | 518 OM_uint32 req_flags, |
560 OM_uint32 time_req, | 519 OM_uint32 time_req, |
(...skipping 28 matching lines...) Expand all Loading... |
589 OM_uint32* max_input_size) { | 548 OM_uint32* max_input_size) { |
590 DCHECK(initialized_); | 549 DCHECK(initialized_); |
591 return wrap_size_limit_(minor_status, | 550 return wrap_size_limit_(minor_status, |
592 context_handle, | 551 context_handle, |
593 conf_req_flag, | 552 conf_req_flag, |
594 qop_req, | 553 qop_req, |
595 req_output_size, | 554 req_output_size, |
596 max_input_size); | 555 max_input_size); |
597 } | 556 } |
598 | 557 |
599 OM_uint32 GSSAPISharedLibrary::delete_sec_context( | 558 OM_uint32 GSSAPISharedLibrary::delete_sec_context(OM_uint32* minor_status, |
600 OM_uint32* minor_status, | 559 gss_ctx_id_t* context_handle, |
601 gss_ctx_id_t* context_handle, | 560 gss_buffer_t output_token) { |
602 gss_buffer_t output_token) { | |
603 // This is called from the owner class' destructor, even if | 561 // This is called from the owner class' destructor, even if |
604 // Init() is not called, so we can't assume |initialized_| | 562 // Init() is not called, so we can't assume |initialized_| |
605 // is set. | 563 // is set. |
606 if (!initialized_) | 564 if (!initialized_) |
607 return 0; | 565 return 0; |
608 return delete_sec_context_(minor_status, | 566 return delete_sec_context_(minor_status, context_handle, output_token); |
609 context_handle, | |
610 output_token); | |
611 } | 567 } |
612 | 568 |
613 OM_uint32 GSSAPISharedLibrary::inquire_context( | 569 OM_uint32 GSSAPISharedLibrary::inquire_context( |
614 OM_uint32* minor_status, | 570 OM_uint32* minor_status, |
615 const gss_ctx_id_t context_handle, | 571 const gss_ctx_id_t context_handle, |
616 gss_name_t* src_name, | 572 gss_name_t* src_name, |
617 gss_name_t* targ_name, | 573 gss_name_t* targ_name, |
618 OM_uint32* lifetime_rec, | 574 OM_uint32* lifetime_rec, |
619 gss_OID* mech_type, | 575 gss_OID* mech_type, |
620 OM_uint32* ctx_flags, | 576 OM_uint32* ctx_flags, |
621 int* locally_initiated, | 577 int* locally_initiated, |
622 int* open) { | 578 int* open) { |
623 DCHECK(initialized_); | 579 DCHECK(initialized_); |
624 return inquire_context_(minor_status, | 580 return inquire_context_(minor_status, |
625 context_handle, | 581 context_handle, |
626 src_name, | 582 src_name, |
627 targ_name, | 583 targ_name, |
628 lifetime_rec, | 584 lifetime_rec, |
629 mech_type, | 585 mech_type, |
630 ctx_flags, | 586 ctx_flags, |
631 locally_initiated, | 587 locally_initiated, |
632 open); | 588 open); |
633 } | 589 } |
634 | 590 |
635 ScopedSecurityContext::ScopedSecurityContext(GSSAPILibrary* gssapi_lib) | 591 ScopedSecurityContext::ScopedSecurityContext(GSSAPILibrary* gssapi_lib) |
636 : security_context_(GSS_C_NO_CONTEXT), | 592 : security_context_(GSS_C_NO_CONTEXT), gssapi_lib_(gssapi_lib) { |
637 gssapi_lib_(gssapi_lib) { | |
638 DCHECK(gssapi_lib_); | 593 DCHECK(gssapi_lib_); |
639 } | 594 } |
640 | 595 |
641 ScopedSecurityContext::~ScopedSecurityContext() { | 596 ScopedSecurityContext::~ScopedSecurityContext() { |
642 if (security_context_ != GSS_C_NO_CONTEXT) { | 597 if (security_context_ != GSS_C_NO_CONTEXT) { |
643 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; | 598 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; |
644 OM_uint32 minor_status = 0; | 599 OM_uint32 minor_status = 0; |
645 OM_uint32 major_status = gssapi_lib_->delete_sec_context( | 600 OM_uint32 major_status = gssapi_lib_->delete_sec_context( |
646 &minor_status, &security_context_, &output_token); | 601 &minor_status, &security_context_, &output_token); |
647 if (major_status != GSS_S_COMPLETE) { | 602 if (major_status != GSS_S_COMPLETE) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; | 670 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; |
716 } | 671 } |
717 | 672 |
718 int HttpAuthGSSAPI::GenerateAuthToken(const AuthCredentials* credentials, | 673 int HttpAuthGSSAPI::GenerateAuthToken(const AuthCredentials* credentials, |
719 const std::string& spn, | 674 const std::string& spn, |
720 std::string* auth_token) { | 675 std::string* auth_token) { |
721 DCHECK(auth_token); | 676 DCHECK(auth_token); |
722 | 677 |
723 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; | 678 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; |
724 input_token.length = decoded_server_auth_token_.length(); | 679 input_token.length = decoded_server_auth_token_.length(); |
725 input_token.value = (input_token.length > 0) ? | 680 input_token.value = (input_token.length > 0) |
726 const_cast<char*>(decoded_server_auth_token_.data()) : | 681 ? const_cast<char*>(decoded_server_auth_token_.data()) |
727 NULL; | 682 : NULL; |
728 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; | 683 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; |
729 ScopedBuffer scoped_output_token(&output_token, library_); | 684 ScopedBuffer scoped_output_token(&output_token, library_); |
730 int rv = GetNextSecurityToken(spn, &input_token, &output_token); | 685 int rv = GetNextSecurityToken(spn, &input_token, &output_token); |
731 if (rv != OK) | 686 if (rv != OK) |
732 return rv; | 687 return rv; |
733 | 688 |
734 // Base64 encode data in output buffer and prepend the scheme. | 689 // Base64 encode data in output buffer and prepend the scheme. |
735 std::string encode_input(static_cast<char*>(output_token.value), | 690 std::string encode_input(static_cast<char*>(output_token.value), |
736 output_token.length); | 691 output_token.length); |
737 std::string encode_output; | 692 std::string encode_output; |
738 base::Base64Encode(encode_input, &encode_output); | 693 base::Base64Encode(encode_input, &encode_output); |
739 *auth_token = scheme_ + " " + encode_output; | 694 *auth_token = scheme_ + " " + encode_output; |
740 return OK; | 695 return OK; |
741 } | 696 } |
742 | 697 |
743 | |
744 namespace { | 698 namespace { |
745 | 699 |
746 // GSSAPI status codes consist of a calling error (essentially, a programmer | 700 // GSSAPI status codes consist of a calling error (essentially, a programmer |
747 // bug), a routine error (defined by the RFC), and supplementary information, | 701 // bug), a routine error (defined by the RFC), and supplementary information, |
748 // all bitwise-or'ed together in different regions of the 32 bit return value. | 702 // all bitwise-or'ed together in different regions of the 32 bit return value. |
749 // This means a simple switch on the return codes is not sufficient. | 703 // This means a simple switch on the return codes is not sufficient. |
750 | 704 |
751 int MapImportNameStatusToError(OM_uint32 major_status) { | 705 int MapImportNameStatusToError(OM_uint32 major_status) { |
752 VLOG(1) << "import_name returned 0x" << std::hex << major_status; | 706 VLOG(1) << "import_name returned 0x" << std::hex << major_status; |
753 if (major_status == GSS_S_COMPLETE) | 707 if (major_status == GSS_S_COMPLETE) |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 } | 778 } |
825 OM_uint32 supplemental_status = GSS_SUPPLEMENTARY_INFO(major_status); | 779 OM_uint32 supplemental_status = GSS_SUPPLEMENTARY_INFO(major_status); |
826 // Replays could indicate an attack. | 780 // Replays could indicate an attack. |
827 if (supplemental_status & (GSS_S_DUPLICATE_TOKEN | GSS_S_OLD_TOKEN | | 781 if (supplemental_status & (GSS_S_DUPLICATE_TOKEN | GSS_S_OLD_TOKEN | |
828 GSS_S_UNSEQ_TOKEN | GSS_S_GAP_TOKEN)) | 782 GSS_S_UNSEQ_TOKEN | GSS_S_GAP_TOKEN)) |
829 return ERR_INVALID_RESPONSE; | 783 return ERR_INVALID_RESPONSE; |
830 | 784 |
831 // At this point, every documented status has been checked. | 785 // At this point, every documented status has been checked. |
832 return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; | 786 return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; |
833 } | 787 } |
834 | |
835 } | 788 } |
836 | 789 |
837 int HttpAuthGSSAPI::GetNextSecurityToken(const std::string& spn, | 790 int HttpAuthGSSAPI::GetNextSecurityToken(const std::string& spn, |
838 gss_buffer_t in_token, | 791 gss_buffer_t in_token, |
839 gss_buffer_t out_token) { | 792 gss_buffer_t out_token) { |
840 // Create a name for the principal | 793 // Create a name for the principal |
841 // TODO(cbentzel): Just do this on the first pass? | 794 // TODO(cbentzel): Just do this on the first pass? |
842 std::string spn_principal = spn; | 795 std::string spn_principal = spn; |
843 gss_buffer_desc spn_buffer = GSS_C_EMPTY_BUFFER; | 796 gss_buffer_desc spn_buffer = GSS_C_EMPTY_BUFFER; |
844 spn_buffer.value = const_cast<char*>(spn_principal.c_str()); | 797 spn_buffer.value = const_cast<char*>(spn_principal.c_str()); |
845 spn_buffer.length = spn_principal.size() + 1; | 798 spn_buffer.length = spn_principal.size() + 1; |
846 OM_uint32 minor_status = 0; | 799 OM_uint32 minor_status = 0; |
847 gss_name_t principal_name = GSS_C_NO_NAME; | 800 gss_name_t principal_name = GSS_C_NO_NAME; |
848 OM_uint32 major_status = library_->import_name( | 801 OM_uint32 major_status = library_->import_name( |
849 &minor_status, | 802 &minor_status, &spn_buffer, GSS_C_NT_HOSTBASED_SERVICE, &principal_name); |
850 &spn_buffer, | |
851 GSS_C_NT_HOSTBASED_SERVICE, | |
852 &principal_name); | |
853 int rv = MapImportNameStatusToError(major_status); | 803 int rv = MapImportNameStatusToError(major_status); |
854 if (rv != OK) { | 804 if (rv != OK) { |
855 LOG(ERROR) << "Problem importing name from " | 805 LOG(ERROR) << "Problem importing name from " |
856 << "spn \"" << spn_principal << "\"\n" | 806 << "spn \"" << spn_principal << "\"\n" |
857 << DisplayExtendedStatus(library_, major_status, minor_status); | 807 << DisplayExtendedStatus(library_, major_status, minor_status); |
858 return rv; | 808 return rv; |
859 } | 809 } |
860 ScopedName scoped_name(principal_name, library_); | 810 ScopedName scoped_name(principal_name, library_); |
861 | 811 |
862 // Continue creating a security context. | 812 // Continue creating a security context. |
863 OM_uint32 req_flags = 0; | 813 OM_uint32 req_flags = 0; |
864 if (can_delegate_) | 814 if (can_delegate_) |
865 req_flags |= GSS_C_DELEG_FLAG; | 815 req_flags |= GSS_C_DELEG_FLAG; |
866 major_status = library_->init_sec_context( | 816 major_status = library_->init_sec_context(&minor_status, |
867 &minor_status, | 817 GSS_C_NO_CREDENTIAL, |
868 GSS_C_NO_CREDENTIAL, | 818 scoped_sec_context_.receive(), |
869 scoped_sec_context_.receive(), | 819 principal_name, |
870 principal_name, | 820 gss_oid_, |
871 gss_oid_, | 821 req_flags, |
872 req_flags, | 822 GSS_C_INDEFINITE, |
873 GSS_C_INDEFINITE, | 823 GSS_C_NO_CHANNEL_BINDINGS, |
874 GSS_C_NO_CHANNEL_BINDINGS, | 824 in_token, |
875 in_token, | 825 NULL, // actual_mech_type |
876 NULL, // actual_mech_type | 826 out_token, |
877 out_token, | 827 NULL, // ret flags |
878 NULL, // ret flags | 828 NULL); |
879 NULL); | |
880 rv = MapInitSecContextStatusToError(major_status); | 829 rv = MapInitSecContextStatusToError(major_status); |
881 if (rv != OK) { | 830 if (rv != OK) { |
882 LOG(ERROR) << "Problem initializing context. \n" | 831 LOG(ERROR) << "Problem initializing context. \n" |
883 << DisplayExtendedStatus(library_, major_status, minor_status) | 832 << DisplayExtendedStatus(library_, major_status, minor_status) |
884 << '\n' | 833 << '\n' << DescribeContext(library_, scoped_sec_context_.get()); |
885 << DescribeContext(library_, scoped_sec_context_.get()); | |
886 } | 834 } |
887 return rv; | 835 return rv; |
888 } | 836 } |
889 | 837 |
890 } // namespace net | 838 } // namespace net |
OLD | NEW |