| 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 |