| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import "package:convert/convert.dart"; |
| 5 import "package:crypto/crypto.dart"; | 6 import "package:crypto/crypto.dart"; |
| 6 import "package:expect/expect.dart"; | 7 import "package:expect/expect.dart"; |
| 7 import "package:path/path.dart"; | 8 import "package:path/path.dart"; |
| 8 import "dart:async"; | 9 import "dart:async"; |
| 9 import "dart:io"; | 10 import "dart:io"; |
| 10 import 'dart:convert'; | 11 import 'dart:convert'; |
| 11 | 12 |
| 12 String localFile(path) => Platform.script.resolve(path).toFilePath(); | 13 String localFile(path) => Platform.script.resolve(path).toFilePath(); |
| 13 | 14 |
| 14 SecurityContext serverContext = new SecurityContext() | 15 SecurityContext serverContext = new SecurityContext() |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 this.password = password; | 109 this.password = password; |
| 109 authScheme = "Basic"; | 110 authScheme = "Basic"; |
| 110 } | 111 } |
| 111 | 112 |
| 112 void useDigestAuthentication(String username, String password) { | 113 void useDigestAuthentication(String username, String password) { |
| 113 this.username = username; | 114 this.username = username; |
| 114 this.password = password; | 115 this.password = password; |
| 115 authScheme = "Digest"; | 116 authScheme = "Digest"; |
| 116 | 117 |
| 117 // Calculate ha1. | 118 // Calculate ha1. |
| 118 var hasher = new MD5(); | 119 var digest = md5.convert("${username}:${realm}:${password}".codeUnits); |
| 119 hasher.add("${username}:${realm}:${password}".codeUnits); | 120 ha1 = hex.encode(digest.bytes); |
| 120 ha1 = CryptoUtils.bytesToHex(hasher.close()); | |
| 121 } | 121 } |
| 122 | 122 |
| 123 basicAuthenticationRequired(request) { | 123 basicAuthenticationRequired(request) { |
| 124 request.fold(null, (x, y) {}).then((_) { | 124 request.fold(null, (x, y) {}).then((_) { |
| 125 var response = request.response; | 125 var response = request.response; |
| 126 response.headers.set(HttpHeaders.PROXY_AUTHENTICATE, | 126 response.headers.set(HttpHeaders.PROXY_AUTHENTICATE, |
| 127 "Basic, realm=$realm"); | 127 "Basic, realm=$realm"); |
| 128 response.statusCode = HttpStatus.PROXY_AUTHENTICATION_REQUIRED; | 128 response.statusCode = HttpStatus.PROXY_AUTHENTICATION_REQUIRED; |
| 129 response.close(); | 129 response.close(); |
| 130 }); | 130 }); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 return; | 166 return; |
| 167 } else { | 167 } else { |
| 168 Expect.equals( | 168 Expect.equals( |
| 169 1, request.headers[HttpHeaders.PROXY_AUTHORIZATION].length); | 169 1, request.headers[HttpHeaders.PROXY_AUTHORIZATION].length); |
| 170 String authorization = | 170 String authorization = |
| 171 request.headers[HttpHeaders.PROXY_AUTHORIZATION][0]; | 171 request.headers[HttpHeaders.PROXY_AUTHORIZATION][0]; |
| 172 if (authScheme == "Basic") { | 172 if (authScheme == "Basic") { |
| 173 List<String> tokens = authorization.split(" "); | 173 List<String> tokens = authorization.split(" "); |
| 174 Expect.equals("Basic", tokens[0]); | 174 Expect.equals("Basic", tokens[0]); |
| 175 String auth = | 175 String auth = |
| 176 CryptoUtils.bytesToBase64(UTF8.encode("$username:$password")); | 176 BASE64.encode(UTF8.encode("$username:$password")); |
| 177 if (auth != tokens[1]) { | 177 if (auth != tokens[1]) { |
| 178 basicAuthenticationRequired(request); | 178 basicAuthenticationRequired(request); |
| 179 return; | 179 return; |
| 180 } | 180 } |
| 181 } else { | 181 } else { |
| 182 HeaderValue header = | 182 HeaderValue header = |
| 183 HeaderValue.parse( | 183 HeaderValue.parse( |
| 184 authorization, parameterSeparator: ","); | 184 authorization, parameterSeparator: ","); |
| 185 Expect.equals("Digest", header.value); | 185 Expect.equals("Digest", header.value); |
| 186 var uri = header.parameters["uri"]; | 186 var uri = header.parameters["uri"]; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 199 Expect.isNotNull(cnonce); | 199 Expect.isNotNull(cnonce); |
| 200 Expect.isNotNull(nc); | 200 Expect.isNotNull(nc); |
| 201 Expect.isFalse(ncs.contains(nc)); | 201 Expect.isFalse(ncs.contains(nc)); |
| 202 ncs.add(nc); | 202 ncs.add(nc); |
| 203 } else { | 203 } else { |
| 204 Expect.isNull(cnonce); | 204 Expect.isNull(cnonce); |
| 205 Expect.isNull(nc); | 205 Expect.isNull(nc); |
| 206 } | 206 } |
| 207 Expect.isNotNull(header.parameters["response"]); | 207 Expect.isNotNull(header.parameters["response"]); |
| 208 | 208 |
| 209 var hasher = new MD5(); | 209 var digest = md5.convert("${request.method}:${uri}".codeUnits); |
| 210 hasher.add("${request.method}:${uri}".codeUnits); | 210 var ha2 = hex.encode(digest.bytes); |
| 211 var ha2 = CryptoUtils.bytesToHex(hasher.close()); | |
| 212 | 211 |
| 213 var x; | 212 var x; |
| 214 hasher = new MD5(); | |
| 215 if (qop == null || qop == "" || qop == "none") { | 213 if (qop == null || qop == "" || qop == "none") { |
| 216 hasher.add("$ha1:${nonce}:$ha2".codeUnits); | 214 digest = md5.convert("$ha1:${nonce}:$ha2".codeUnits); |
| 217 } else { | 215 } else { |
| 218 hasher.add( | 216 digest = md5.convert( |
| 219 "$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits); | 217 "$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits); |
| 220 } | 218 } |
| 221 Expect.equals(CryptoUtils.bytesToHex(hasher.close()), | 219 Expect.equals(hex.encode(digest.bytes), |
| 222 header.parameters["response"]); | 220 header.parameters["response"]); |
| 223 | 221 |
| 224 // Add a bogus Proxy-Authentication-Info for testing. | 222 // Add a bogus Proxy-Authentication-Info for testing. |
| 225 var info = 'rspauth="77180d1ab3d6c9de084766977790f482", ' | 223 var info = 'rspauth="77180d1ab3d6c9de084766977790f482", ' |
| 226 'cnonce="8f971178", ' | 224 'cnonce="8f971178", ' |
| 227 'nc=000002c74, ' | 225 'nc=000002c74, ' |
| 228 'qop=auth'; | 226 'qop=auth'; |
| 229 request.response.headers.set("Proxy-Authentication-Info", info); | 227 request.response.headers.set("Proxy-Authentication-Info", info); |
| 230 } | 228 } |
| 231 } | 229 } |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 // The two invocations use the same global variable for state - | 625 // The two invocations use the same global variable for state - |
| 628 // run one after the other. | 626 // run one after the other. |
| 629 testProxyAuthenticate(false) | 627 testProxyAuthenticate(false) |
| 630 .then((_) => testProxyAuthenticate(true)); | 628 .then((_) => testProxyAuthenticate(true)); |
| 631 | 629 |
| 632 // This test is not normally run. It can be used for locally testing | 630 // This test is not normally run. It can be used for locally testing |
| 633 // with a real proxy server (e.g. Apache). | 631 // with a real proxy server (e.g. Apache). |
| 634 // testRealProxy(); | 632 // testRealProxy(); |
| 635 // testRealProxyAuth(); | 633 // testRealProxyAuth(); |
| 636 } | 634 } |
| OLD | NEW |