Skip to content

Commit

Permalink
Fix #225. Detect protocol change on socket reuse
Browse files Browse the repository at this point in the history
  • Loading branch information
bjowes committed Mar 5, 2023
1 parent bca817f commit d9e5ba2
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/proxy/connection.context.manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export class ConnectionContextManager implements IConnectionContextManager {
context.agent = agent;
context.clientSocket = clientSocket;
context.useUpstreamProxy = useUpstreamProxy;
context.isSSL = isSSL;

this._connectionContexts[clientAddress] = context;
context.socketCloseListener = this.removeAgentOnClose.bind(
Expand Down
12 changes: 10 additions & 2 deletions src/proxy/connection.context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class ConnectionContext implements IConnectionContext {
private _socketCloseListener: any;
private _configApiConnection = false;
private _useUpstreamProxy = false;
private _isSSL = false;

get agent(): any {
return this._agent;
Expand Down Expand Up @@ -78,6 +79,13 @@ export class ConnectionContext implements IConnectionContext {
this._useUpstreamProxy = val;
}

get isSSL(): boolean {
return this._isSSL;
}
set isSSL(val: boolean) {
this._isSSL = val;
}

/**
* If the connection is new or a handshake has been completed (successful or failed),
* a new handshake can be initiated
Expand All @@ -93,8 +101,8 @@ export class ConnectionContext implements IConnectionContext {
return auth;
}

matchHostOrNew(ntlmHostUrl: URL): boolean {
return this._ntlmHost === undefined || this._ntlmHost.href === ntlmHostUrl.href;
matchHostOrNew(ntlmHostUrl: URL, isSSL: boolean): boolean {
return this._isSSL == isSSL && (this._ntlmHost === undefined || this._ntlmHost.href === ntlmHostUrl.href);
}

getState(ntlmHostUrl: URL): NtlmStateEnum {
Expand Down
3 changes: 2 additions & 1 deletion src/proxy/interfaces/i.connection.context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ export interface IConnectionContext {
socketCloseListener: any;
configApiConnection: boolean;
useUpstreamProxy: boolean;
isSSL: boolean;

canStartAuthHandshake(ntlmHostUrl: URL): boolean;
matchHostOrNew(ntlmHostUrl: URL): boolean;
matchHostOrNew(ntlmHostUrl: URL, isSSL: boolean): boolean;
getState(ntlmHostUrl: URL): NtlmStateEnum;
setState(ntlmHostUrl: URL, authState: NtlmStateEnum): void;

Expand Down
2 changes: 1 addition & 1 deletion src/proxy/ntlm.proxy.mitm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class NtlmProxyMitm implements INtlmProxyMitm {
const useSso = self._configStore.useSso(targetHost);
const useNtlm = useSso || self._configStore.exists(targetHost);
if (context) {
if (context.matchHostOrNew(targetHost) === false) {
if (context.matchHostOrNew(targetHost, ctx.isSSL) === false) {
self._debug.log(
"Existing client socket " +
context.clientAddress +
Expand Down
63 changes: 63 additions & 0 deletions test/unittest/proxy/connection.context.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import assert from 'assert';
import { NtlmStateEnum } from '../../../src/models/ntlm.state.enum';
import { ConnectionContext } from '../../../src/proxy/connection.context';

describe('ConnectionContext', () => {
describe('matchHostOrNew', () => {
it('should return true for unused NTLM ', () => {
let context = new ConnectionContext();
let ntlmHost = new URL('http://localhost:8787');
let result = context.matchHostOrNew(ntlmHost, false);
assert.equal(result, true);
});

it('should return false for used NTLM ', () => {
let context = new ConnectionContext();
let oldNtlmHost = new URL('http://localhost:8878');
context.setState(oldNtlmHost, NtlmStateEnum.Authenticated);
let ntlmHost = new URL('http://localhost:8787');
let result = context.matchHostOrNew(ntlmHost, false);
assert.equal(result, false);
});

it('should return true for used NTLM on match', () => {
let context = new ConnectionContext();
let ntlmHost = new URL('http://localhost:8787');
context.setState(ntlmHost, NtlmStateEnum.NotAuthenticated);
let result = context.matchHostOrNew(ntlmHost, false);
assert.equal(result, true);
});

it('should return false on protocol change http to https for NTLM', () => {
let context = new ConnectionContext();
let ntlmHost = new URL('localhost:8787');
context.setState(ntlmHost, NtlmStateEnum.NotAuthenticated);
let result = context.matchHostOrNew(ntlmHost, true);
assert.equal(result, false);
});

it('should return false on protocol change https to http for NTLM', () => {
let context = new ConnectionContext();
let ntlmHost = new URL('localhost:8787');
context.setState(ntlmHost, NtlmStateEnum.NotAuthenticated);
context.isSSL = true;
let result = context.matchHostOrNew(ntlmHost, false);
assert.equal(result, false);
});

it('should return false on protocol change http to https for non NTLM', () => {
let context = new ConnectionContext();
let newNtlmHost = new URL('https://localhost:8787');
let result = context.matchHostOrNew(newNtlmHost, true);
assert.equal(result, false);
});

it('should return false on protocol change https to http for non NTLM', () => {
let context = new ConnectionContext();
context.isSSL = true;
let newNtlmHost = new URL('http://localhost:8787');
let result = context.matchHostOrNew(newNtlmHost, false);
assert.equal(result, false);
});
});
});

0 comments on commit d9e5ba2

Please sign in to comment.