diff --git a/lib/ntlm.dart b/lib/ntlm.dart index e261880..fafbb92 100644 --- a/lib/ntlm.dart +++ b/lib/ntlm.dart @@ -22,6 +22,6 @@ /// ``` library ntlm; -export 'package:ntlm/src/http.dart'; export 'package:ntlm/src/hash.dart'; +export 'package:ntlm/src/http.dart'; export 'package:ntlm/src/messages/messages.dart'; diff --git a/lib/src/des/des.dart b/lib/src/des/des.dart index 8b112c3..b620471 100644 --- a/lib/src/des/des.dart +++ b/lib/src/des/des.dart @@ -1,10 +1,11 @@ import 'dart:typed_data'; + +import 'package:fixnum/fixnum.dart'; +import 'package:ntlm/src/des/des_constants.dart'; import 'package:pointycastle/api.dart'; import 'package:pointycastle/src/impl/base_block_cipher.dart'; -import 'package:pointycastle/src/ufixnum.dart'; import 'package:pointycastle/src/registry/registry.dart'; -import 'package:fixnum/fixnum.dart'; -import 'package:ntlm/src/des/des_constants.dart'; +import 'package:pointycastle/src/ufixnum.dart'; class DESEngine extends BaseBlockCipher { static final FactoryConfig FACTORY_CONFIG = diff --git a/lib/src/http.dart b/lib/src/http.dart index b3b0560..142e31d 100644 --- a/lib/src/http.dart +++ b/lib/src/http.dart @@ -13,16 +13,19 @@ class NTLMClient extends BaseClient { String workstation; /// The username of the user trying to authenticate - String username; + final String username; /// The password of the user trying to authenticate - String? password; + final String? _password; + + /// The password is set + bool get isPassSet => (_password ?? '') != ''; /// The lan manager hash of the user's password - String? lmPassword; + final String? _lmPassword; /// The NT hash of the user's password - String? ntPassword; + final String? _ntPassword; /// The prefix for 'www-authenticate'/'authorization' headers (usually /// either [kHeaderPrefixNTLM] or [kHeaderPrefixNegotiate]) @@ -33,7 +36,7 @@ class NTLMClient extends BaseClient { /// Creates a new NTLM client /// - /// The [username] is required as is either the [password]... + /// The [username] is required as is either the [_password]... /// /// ```dart /// NTLMClient client = new NTLMClient( @@ -42,7 +45,7 @@ class NTLMClient extends BaseClient { /// ); /// ``` /// - /// ...or the [lmPassword] and the [ntPassword] in base 64 form. + /// ...or the [_lmPassword] and the [_ntPassword] in base 64 form. /// /// ```dart /// String lmPassword = lmHash("password"); @@ -60,14 +63,17 @@ class NTLMClient extends BaseClient { NTLMClient({ this.domain = '', this.workstation = '', - required this.username, - this.password, - this.lmPassword, - this.ntPassword, + required String username, + String? password, + String? lmPassword, + String? ntPassword, Client? inner, this.headerPrefix = kHeaderPrefixNTLM, - }) { - if (password == null && (lmPassword == null || ntPassword == null)) { + }) : username = username, + _password = password, + _ntPassword = ntPassword, + _lmPassword = lmPassword { + if (_password == null && (_lmPassword == null || _ntPassword == null)) { throw ArgumentError( 'You must provide a password or the LM and NT hash of a password.', ); @@ -137,9 +143,9 @@ class NTLMClient extends BaseClient { domain: domain, workstation: workstation, username: username, - password: password, - lmPassword: lmPassword, - ntPassword: ntPassword, + password: _password, + lmPassword: _lmPassword, + ntPassword: _ntPassword, headerPrefix: headerPrefix, ); diff --git a/lib/src/messages/common/utils.dart b/lib/src/messages/common/utils.dart index 6e3eb42..d55554c 100644 --- a/lib/src/messages/common/utils.dart +++ b/lib/src/messages/common/utils.dart @@ -1,13 +1,14 @@ import 'dart:convert'; import 'dart:math' as math; import 'dart:typed_data'; + +import 'package:ntlm/src/des/des.dart'; +import 'package:ntlm/src/messages/type2.dart'; import 'package:pointycastle/api.dart'; +import 'package:pointycastle/block/modes/ecb.dart'; import 'package:pointycastle/digests/md4.dart'; import 'package:pointycastle/digests/md5.dart'; -import 'package:pointycastle/block/modes/ecb.dart'; import 'package:pointycastle/macs/hmac.dart'; -import 'package:ntlm/src/des/des.dart'; -import 'package:ntlm/src/messages/type2.dart'; void write(ByteData buf, Uint8List data, int offset, int length) { for (var i = 0; i < length; i++) { @@ -68,7 +69,7 @@ Uint8List encodeUtf16le(String s) => Uint8List.fromList( ); Uint8List createLMHashedPasswordV1(String password) { - var oemPassword = ascii.encode(password.toUpperCase()); + var oemPassword = password.toUpperCase().codeUnits; var length = math.min(oemPassword.length, 14); var keyBytes = List.filled(14, 0); _arrayCopy(oemPassword, 0, keyBytes, 0, length); @@ -165,7 +166,9 @@ Uint8List calculateNTLMResponseV2( // (11644473600000 = milliseconds between 1970 and 1601) var timestamp = (DateTime.now().millisecondsSinceEpoch + 11644473600000) * 10000; - buf.setUint64(24, timestamp); + // buf.setUint64(24, timestamp); + buf.setUint32(24, timestamp >> 32); + buf.setUint32(24 + 4, timestamp & 0xFFFFFFFF); // Client Nonce write(buf, clientNonce, 32, clientNonce.length); diff --git a/test/ntlm_test.dart b/test/ntlm_test.dart index 1c8d396..05dcaa5 100644 --- a/test/ntlm_test.dart +++ b/test/ntlm_test.dart @@ -1,9 +1,10 @@ import 'dart:convert'; import 'dart:io' show Platform; -import 'package:test/test.dart'; + import 'package:http/http.dart' as http; import 'package:http_parser/http_parser.dart' as http_parser; import 'package:ntlm/ntlm.dart'; +import 'package:test/test.dart'; /// The environment variable `NTLM_TEST_URL` should be set to the URL of a /// server that accepts GET, HEAD, POST, PATCH, PUT and DELETE requests to /,