Skip to content

Commit 9d4c146

Browse files
authored
Merge pull request #12 from jstruzik/php72-fixes
PHP 7.2 compatibility and adding example usage
2 parents e75cf49 + 9039991 commit 9d4c146

File tree

6 files changed

+94
-21
lines changed

6 files changed

+94
-21
lines changed

.travis.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ sudo: false
22

33
language: php
44
php:
5-
- 5.4
6-
- 5.5
7-
- 5.6
8-
- 7.0
5+
- 7.1
6+
- 7.2
97
- nightly
108
- hhvm
119

@@ -17,6 +15,7 @@ matrix:
1715

1816
before_install:
1917
- export ALLOW_FAILURE=1; if [ "$TRAVIS_PHP_VERSION" != "hhvm" ] && [ "$TRAVIS_PHP_VERSION" != "nightly" ]; then export ALLOW_FAILURE=0; fi
18+
- if [ "$TRAVIS_PHP_VERSION" == "7.2" ]; then yes '' | pecl install mcrypt-1.0.2; fi
2019

2120
install:
2221
- composer self-update

README.md

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ secure version of a credential for storage (rather than storing passwords in "pl
1919
## Requirements
2020

2121
- 64-bit PHP runtime (NTLM negotiation bit flags extend beyond the 32-bit integer size)
22-
- PHP `>=5.4.0`
22+
- PHP `>=7.1.0`
2323

2424

2525
## Installation
@@ -29,6 +29,71 @@ secure version of a credential for storage (rather than storing passwords in "pl
2929
3. Include the [Composer autoloader][composer-documentation-autoloading]
3030

3131

32+
## Example Usage
33+
34+
```php
35+
// Using Guzzle
36+
$client = new Client();
37+
$request = new Request('get', 'https://my-exchange-url.com');
38+
$user_name = 'user_name';
39+
$password = 'password';
40+
$target_name = 'target_name';
41+
$host_name = 'host_name';
42+
43+
$encoding_converter = new MbstringEncodingConverter();
44+
$random_byte_generator = new NativeRandomByteGenerator();
45+
$hasher_factory = HasherFactory::createWithDetectedSupportedAlgorithms();
46+
47+
$negotiate_message_encoder = new NegotiateMessageEncoder($encoding_converter);
48+
$challenge_message_decoder = new ChallengeMessageDecoder();
49+
50+
$keyed_hasher_factory = KeyedHasherFactory::createWithDetectedSupportedAlgorithms();
51+
52+
$nt1_hasher = new NtV1Hasher($hasher_factory, $encoding_converter);
53+
$nt2_hasher = new NtV2Hasher($nt1_hasher, $keyed_hasher_factory, $encoding_converter);
54+
55+
$authenticate_message_encoder = new NtlmV2AuthenticateMessageEncoder(
56+
$encoding_converter,
57+
$nt2_hasher,
58+
$random_byte_generator,
59+
$keyed_hasher_factory
60+
);
61+
62+
$negotiate_message = $negotiate_message_encoder->encode(
63+
$target_name,
64+
$host_name
65+
);
66+
67+
// Send negotiate message
68+
$request->setHeader('Authorization', sprintf('NTLM %s', base64_encode($negotiate_message)));
69+
$response = $client->send($request);
70+
71+
// Decode returned challenge message
72+
$authenticate_headers = $response->getHeaderAsArray('WWW-Authenticate');
73+
foreach ($authenticate_headers as $header_string) {
74+
$ntlm_matches = preg_match('/NTLM( (.*))?/', $header_string, $ntlm_header);
75+
76+
if (0 < $ntlm_matches && isset($ntlm_header[2])) {
77+
$raw_server_challenge = base64_decode($ntlm_header[2]);
78+
break;
79+
}
80+
}
81+
$server_challenge = $challenge_message_decoder->decode($raw_server_challenge);
82+
83+
$authenticate_message = $authenticate_message_encoder->encode(
84+
$user_name,
85+
$target_name,
86+
$host_name,
87+
new Password($password),
88+
$server_challenge
89+
);
90+
91+
// Send authenticate message
92+
$request->setHeader('Authorization', sprintf('NTLM %s', base64_encode($authenticate_message)));
93+
$client->send($request);
94+
```
95+
96+
3297
## TODO
3398

3499
- [x] LM hashing
@@ -49,8 +114,7 @@ secure version of a credential for storage (rather than storing passwords in "pl
49114
- [x] Extended session security (NTLM2 session key) support
50115
- [ ] \(Add-on) Encrypted session key exchange support
51116
- [ ] Datagram ("connectionless") support
52-
- [ ] PHP 5.3.x support
53-
- [ ] Tests... ugh.
117+
- [ ] Tests
54118

55119

56120
## License
@@ -59,7 +123,7 @@ secure version of a credential for storage (rather than storing passwords in "pl
59123

60124
--------------------------------------------------------------------------------
61125

62-
Copyright 2015 Robin Powered, Inc.
126+
Copyright 2019 Robin Powered, Inc.
63127

64128
Licensed under the Apache License, Version 2.0 (the "License");
65129
you may not use this file except in compliance with the License.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"source": "https://github.com/robinpowered/php-ntlm"
1717
},
1818
"require": {
19-
"php-64bit": ">=5.4.0"
19+
"php-64bit": ">=7.1.0"
2020
},
2121
"require-dev": {
2222
"ext-mcrypt": "*",

src/Robin/Ntlm/Crypt/Des/McryptDesEncrypter.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/**
33
* Robin NTLM
44
*
5-
* @copyright 2015 Robin Powered, Inc.
5+
* @copyright 2019 Robin Powered, Inc.
66
* @link https://robinpowered.com/
77
*/
88

@@ -13,6 +13,10 @@
1313
use Robin\Ntlm\Crypt\Exception\CryptographicFailureException;
1414

1515
/**
16+
* @deprecated Mcrypt has been deprecated from the core PHP library. Use
17+
* {@see OpenSslDesEncrypter} as an alternative.
18+
* @link https://php.net/manual/en/migration72.other-changes.php#migration72.other-changes.mcrypt
19+
*
1620
* An engine used to encrypt data using the DES standard algorithm and
1721
* implemented using the PHP "mcrypt" extension.
1822
*

src/Robin/Ntlm/Crypt/Hasher/AbstractHasher.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
/**
33
* Robin NTLM
44
*
5-
* @copyright 2015 Robin Powered, Inc.
5+
* @copyright 2019 Robin Powered, Inc.
66
* @link https://robinpowered.com/
77
*/
88

9+
declare(strict_types=1);
10+
911
namespace Robin\Ntlm\Crypt\Hasher;
1012

13+
use HashContext;
1114
use InvalidArgumentException;
1215

1316
/**
@@ -28,6 +31,7 @@ abstract class AbstractHasher implements HasherInterface
2831
*
2932
* @type string
3033
*/
34+
3135
const HASH_CONTEXT_RESOURCE_TYPE = 'Hash Context';
3236

3337

@@ -39,7 +43,7 @@ abstract class AbstractHasher implements HasherInterface
3943
* The incremental hashing context.
4044
*
4145
* @link http://php.net/manual/en/hash.resources.php
42-
* @type resource
46+
* @type resource|HashContext
4347
*/
4448
private $context;
4549

@@ -51,7 +55,7 @@ abstract class AbstractHasher implements HasherInterface
5155
/**
5256
* Constructor
5357
*
54-
* @param resource $context The incremental hashing context.
58+
* @param resource|HashContext $context The incremental hashing context.
5559
*/
5660
protected function __construct($context)
5761
{
@@ -61,7 +65,7 @@ protected function __construct($context)
6165
/**
6266
* {@inheritDoc}
6367
*/
64-
public function update($data)
68+
public function update(string $data): HasherInterface
6569
{
6670
hash_update($this->context, $data);
6771

@@ -71,7 +75,7 @@ public function update($data)
7175
/**
7276
* {@inheritDoc}
7377
*/
74-
public function digest()
78+
public function digest(): string
7579
{
7680
// Copy the context so we can keep using the hasher
7781
$context_copy = hash_copy($this->context);
@@ -90,14 +94,14 @@ public function digest()
9094
*
9195
* @link http://php.net/manual/en/hash.resources.php
9296
* @param mixed $context The context to validate.
93-
* @return resource The incremental hashing context.
97+
* @return resource|HashContext The incremental hashing context.
9498
* @throws InvalidArgumentException If the hash context isn't valid.
9599
*/
96100
protected function validateHashContext($context)
97101
{
98-
if (false === $context
102+
if (!($context instanceof HashContext) && (false === $context
99103
|| !is_resource($context)
100-
|| (is_resource($context) && static::HASH_CONTEXT_RESOURCE_TYPE !== get_resource_type($context))) {
104+
|| (is_resource($context) && static::HASH_CONTEXT_RESOURCE_TYPE !== get_resource_type($context)))) {
101105
throw new InvalidArgumentException(
102106
'Unable to initialize hashing context. Your system might not support the supplied algorithm.'
103107
);

src/Robin/Ntlm/Crypt/Hasher/HasherInterface.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
/**
33
* Robin NTLM
44
*
5-
* @copyright 2015 Robin Powered, Inc.
5+
* @copyright 2019 Robin Powered, Inc.
66
* @link https://robinpowered.com/
77
*/
88

9+
declare(strict_types=1);
10+
911
namespace Robin\Ntlm\Crypt\Hasher;
1012

1113
/**
@@ -23,12 +25,12 @@ interface HasherInterface
2325
* @param string $data The data to add.
2426
* @return $this
2527
*/
26-
public function update($data);
28+
public function update(string $data): HasherInterface;
2729

2830
/**
2931
* Calculates the digest of the message.
3032
*
3133
* @return string The message digest as a binary string.
3234
*/
33-
public function digest();
35+
public function digest(): string;
3436
}

0 commit comments

Comments
 (0)