Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Titanium-Web-Proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Titanium-Web-Proxy
Commits
d431a3ef
Commit
d431a3ef
authored
May 22, 2017
by
justcoding121
Committed by
justcoding121
May 22, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntlm progress
parent
b8f7b8c5
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1014 additions
and
0 deletions
+1014
-0
Titanium.Web.Proxy.UnitTests.csproj
...m.Web.Proxy.UnitTests/Titanium.Web.Proxy.UnitTests.csproj
+2
-0
WinAuthTests.cs
Tests/Titanium.Web.Proxy.UnitTests/WinAuthTests.cs
+16
-0
BufferWrapper.cs
Titanium.Web.Proxy/Network/WinAuth/Security/BufferWrapper.cs
+21
-0
Common.cs
Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
+297
-0
EndPoint.cs
Titanium.Web.Proxy/Network/WinAuth/Security/EndPoint.cs
+178
-0
LittleEndian.cs
Titanium.Web.Proxy/Network/WinAuth/Security/LittleEndian.cs
+257
-0
Message.cs
Titanium.Web.Proxy/Network/WinAuth/Security/Message.cs
+147
-0
State.cs
Titanium.Web.Proxy/Network/WinAuth/Security/State.cs
+49
-0
WinAuthHandler.cs
Titanium.Web.Proxy/Network/WinAuth/WinAuthHandler.cs
+39
-0
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+8
-0
No files found.
Tests/Titanium.Web.Proxy.UnitTests/Titanium.Web.Proxy.UnitTests.csproj
View file @
d431a3ef
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
<DefineConstants>
TRACE
</DefineConstants>
<DefineConstants>
TRACE
</DefineConstants>
<ErrorReport>
prompt
</ErrorReport>
<ErrorReport>
prompt
</ErrorReport>
<WarningLevel>
4
</WarningLevel>
<WarningLevel>
4
</WarningLevel>
<AllowUnsafeBlocks>
true
</AllowUnsafeBlocks>
</PropertyGroup>
</PropertyGroup>
<PropertyGroup>
<PropertyGroup>
<SignAssembly>
true
</SignAssembly>
<SignAssembly>
true
</SignAssembly>
...
@@ -59,6 +60,7 @@
...
@@ -59,6 +60,7 @@
<Compile
Include=
"CertificateManagerTests.cs"
/>
<Compile
Include=
"CertificateManagerTests.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"ProxyServerTests.cs"
/>
<Compile
Include=
"ProxyServerTests.cs"
/>
<Compile
Include=
"WinAuthTests.cs"
/>
</ItemGroup>
</ItemGroup>
<ItemGroup>
<ItemGroup>
<ProjectReference
Include=
"..\..\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj"
>
<ProjectReference
Include=
"..\..\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj"
>
...
...
Tests/Titanium.Web.Proxy.UnitTests/WinAuthTests.cs
0 → 100644
View file @
d431a3ef
using
Microsoft.VisualStudio.TestTools.UnitTesting
;
using
Titanium.Web.Proxy.Network.WinAuth
;
namespace
Titanium.Web.Proxy.UnitTests
{
[
TestClass
]
public
class
WinAuthTests
{
[
TestMethod
]
public
void
Test_Acquire_Client_Token
()
{
var
token
=
WinAuthHandler
.
GetInitialAuthToken
(
"mylocalserver.com"
);
Assert
.
IsTrue
(
token
.
Length
>
1
);
}
}
}
Titanium.Web.Proxy/Network/WinAuth/Security/BufferWrapper.cs
0 → 100644
View file @
d431a3ef
namespace
Titanium.Web.Proxy.Network.WinAuth.Security
{
using
System
;
internal
struct
BufferWrapper
{
internal
byte
[]
Buffer
;
internal
Common
.
SecurityBufferType
BufferType
;
internal
BufferWrapper
(
byte
[]
buffer
,
Common
.
SecurityBufferType
bufferType
)
{
if
(
buffer
==
null
||
buffer
.
Length
==
0
)
{
throw
new
ArgumentException
(
"buffer cannot be null or 0 length"
);
}
Buffer
=
buffer
;
BufferType
=
bufferType
;
}
};
}
Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
0 → 100644
View file @
d431a3ef
namespace
Titanium.Web.Proxy.Network.WinAuth.Security
{
using
System
;
using
System.Runtime.InteropServices
;
internal
class
Common
{
#
region
Private
constants
private
const
int
ISC_REQ_REPLAY_DETECT
=
0x00000004
;
private
const
int
ISC_REQ_SEQUENCE_DETECT
=
0x00000008
;
private
const
int
ISC_REQ_CONFIDENTIALITY
=
0x00000010
;
private
const
int
ISC_REQ_CONNECTION
=
0x00000800
;
#
endregion
internal
static
uint
NewContextAttributes
=
0
;
internal
static
Common
.
SecurityInteger
NewLifeTime
=
new
SecurityInteger
(
0
);
#
region
internal
constants
internal
const
int
StandardContextAttributes
=
ISC_REQ_CONFIDENTIALITY
|
ISC_REQ_REPLAY_DETECT
|
ISC_REQ_SEQUENCE_DETECT
|
ISC_REQ_CONNECTION
;
internal
const
int
SecurityNativeDataRepresentation
=
0x10
;
internal
const
int
MaximumTokenSize
=
12288
;
internal
const
int
SecurityCredentialsOutbound
=
2
;
internal
const
int
SuccessfulResult
=
0
;
internal
const
int
IntermediateResult
=
0x90312
;
#
endregion
#
region
internal
enumerations
internal
enum
SecurityBufferType
{
SECBUFFER_VERSION
=
0
,
SECBUFFER_EMPTY
=
0
,
SECBUFFER_DATA
=
1
,
SECBUFFER_TOKEN
=
2
}
[
Flags
]
internal
enum
NtlmFlags
:
int
{
// The client sets this flag to indicate that it supports Unicode strings.
NegotiateUnicode
=
0x00000001
,
// This is set to indicate that the client supports OEM strings.
NegotiateOem
=
0x00000002
,
// This requests that the server send the authentication target with the Type 2 reply.
RequestTarget
=
0x00000004
,
// Indicates that NTLM authentication is supported.
NegotiateNtlm
=
0x00000200
,
// When set, the client will send with the message the name of the domain in which the workstation has membership.
NegotiateDomainSupplied
=
0x00001000
,
// Indicates that the client is sending its workstation name with the message.
NegotiateWorkstationSupplied
=
0x00002000
,
// Indicates that communication between the client and server after authentication should carry a "dummy" signature.
NegotiateAlwaysSign
=
0x00008000
,
// Indicates that this client supports the NTLM2 signing and sealing scheme; if negotiated, this can also affect the response calculations.
NegotiateNtlm2Key
=
0x00080000
,
// Indicates that this client supports strong (128-bit) encryption.
Negotiate128
=
0x20000000
,
// Indicates that this client supports medium (56-bit) encryption.
Negotiate56
=
(
unchecked
((
int
)
0x80000000
))
}
internal
enum
NtlmAuthLevel
{
/* Use LM and NTLM, never use NTLMv2 session security. */
LM_and_NTLM
,
/* Use NTLMv2 session security if the server supports it,
* otherwise fall back to LM and NTLM. */
LM_and_NTLM_and_try_NTLMv2_Session
,
/* Use NTLMv2 session security if the server supports it,
* otherwise fall back to NTLM. Never use LM. */
NTLM_only
,
/* Use NTLMv2 only. */
NTLMv2_only
,
}
#
endregion
#
region
internal
structures
[
StructLayout
(
LayoutKind
.
Sequential
)]
internal
struct
SecurityHandle
{
internal
IntPtr
LowPart
;
internal
IntPtr
HighPart
;
internal
SecurityHandle
(
int
dummy
)
{
LowPart
=
HighPart
=
IntPtr
.
Zero
;
}
/// <summary>
/// Resets all internal pointers to default value
/// </summary>
internal
void
Reset
()
{
LowPart
=
HighPart
=
IntPtr
.
Zero
;
}
}
[
StructLayout
(
LayoutKind
.
Sequential
)]
internal
struct
SecurityInteger
{
internal
uint
LowPart
;
internal
int
HighPart
;
internal
SecurityInteger
(
int
dummy
)
{
LowPart
=
0
;
HighPart
=
0
;
}
}
[
StructLayout
(
LayoutKind
.
Sequential
)]
internal
struct
SecurityBuffer
:
IDisposable
{
internal
int
cbBuffer
;
internal
int
cbBufferType
;
internal
IntPtr
pvBuffer
;
internal
SecurityBuffer
(
int
bufferSize
)
{
cbBuffer
=
bufferSize
;
cbBufferType
=
(
int
)
SecurityBufferType
.
SECBUFFER_TOKEN
;
pvBuffer
=
Marshal
.
AllocHGlobal
(
bufferSize
);
}
internal
SecurityBuffer
(
byte
[]
secBufferBytes
)
{
cbBuffer
=
secBufferBytes
.
Length
;
cbBufferType
=
(
int
)
SecurityBufferType
.
SECBUFFER_TOKEN
;
pvBuffer
=
Marshal
.
AllocHGlobal
(
cbBuffer
);
Marshal
.
Copy
(
secBufferBytes
,
0
,
pvBuffer
,
cbBuffer
);
}
internal
SecurityBuffer
(
byte
[]
secBufferBytes
,
SecurityBufferType
bufferType
)
{
cbBuffer
=
secBufferBytes
.
Length
;
cbBufferType
=
(
int
)
bufferType
;
pvBuffer
=
Marshal
.
AllocHGlobal
(
cbBuffer
);
Marshal
.
Copy
(
secBufferBytes
,
0
,
pvBuffer
,
cbBuffer
);
}
public
void
Dispose
()
{
if
(
pvBuffer
!=
IntPtr
.
Zero
)
{
Marshal
.
FreeHGlobal
(
pvBuffer
);
pvBuffer
=
IntPtr
.
Zero
;
}
}
}
[
StructLayout
(
LayoutKind
.
Sequential
)]
internal
struct
SecurityBufferDesciption
:
IDisposable
{
internal
int
ulVersion
;
internal
int
cBuffers
;
internal
IntPtr
pBuffers
;
//Point to SecBuffer
internal
SecurityBufferDesciption
(
int
bufferSize
)
{
ulVersion
=
(
int
)
SecurityBufferType
.
SECBUFFER_VERSION
;
cBuffers
=
1
;
Common
.
SecurityBuffer
ThisSecBuffer
=
new
Common
.
SecurityBuffer
(
bufferSize
);
pBuffers
=
Marshal
.
AllocHGlobal
(
Marshal
.
SizeOf
(
ThisSecBuffer
));
Marshal
.
StructureToPtr
(
ThisSecBuffer
,
pBuffers
,
false
);
}
internal
SecurityBufferDesciption
(
byte
[]
secBufferBytes
)
{
ulVersion
=
(
int
)
SecurityBufferType
.
SECBUFFER_VERSION
;
cBuffers
=
1
;
Common
.
SecurityBuffer
ThisSecBuffer
=
new
Common
.
SecurityBuffer
(
secBufferBytes
);
pBuffers
=
Marshal
.
AllocHGlobal
(
Marshal
.
SizeOf
(
ThisSecBuffer
));
Marshal
.
StructureToPtr
(
ThisSecBuffer
,
pBuffers
,
false
);
}
internal
SecurityBufferDesciption
(
BufferWrapper
[]
secBufferBytesArray
)
{
if
(
secBufferBytesArray
==
null
||
secBufferBytesArray
.
Length
==
0
)
{
throw
new
ArgumentException
(
"secBufferBytesArray cannot be null or 0 length"
);
}
ulVersion
=
(
int
)
SecurityBufferType
.
SECBUFFER_VERSION
;
cBuffers
=
secBufferBytesArray
.
Length
;
//Allocate memory for SecBuffer Array....
pBuffers
=
Marshal
.
AllocHGlobal
(
Marshal
.
SizeOf
(
typeof
(
Buffer
))
*
cBuffers
);
for
(
int
Index
=
0
;
Index
<
secBufferBytesArray
.
Length
;
Index
++)
{
//Super hack: Now allocate memory for the individual SecBuffers
//and just copy the bit values to the SecBuffer array!!!
Common
.
SecurityBuffer
ThisSecBuffer
=
new
Common
.
SecurityBuffer
(
secBufferBytesArray
[
Index
].
Buffer
,
secBufferBytesArray
[
Index
].
BufferType
);
//We will write out bits in the following order:
//int cbBuffer;
//int BufferType;
//pvBuffer;
//Note that we won't be releasing the memory allocated by ThisSecBuffer until we
//are disposed...
int
CurrentOffset
=
Index
*
Marshal
.
SizeOf
(
typeof
(
Buffer
));
Marshal
.
WriteInt32
(
pBuffers
,
CurrentOffset
,
ThisSecBuffer
.
cbBuffer
);
Marshal
.
WriteInt32
(
pBuffers
,
CurrentOffset
+
Marshal
.
SizeOf
(
ThisSecBuffer
.
cbBuffer
),
ThisSecBuffer
.
cbBufferType
);
Marshal
.
WriteIntPtr
(
pBuffers
,
CurrentOffset
+
Marshal
.
SizeOf
(
ThisSecBuffer
.
cbBuffer
)
+
Marshal
.
SizeOf
(
ThisSecBuffer
.
cbBufferType
),
ThisSecBuffer
.
pvBuffer
);
}
}
public
void
Dispose
()
{
if
(
pBuffers
!=
IntPtr
.
Zero
)
{
if
(
cBuffers
==
1
)
{
Common
.
SecurityBuffer
ThisSecBuffer
=
(
Common
.
SecurityBuffer
)
Marshal
.
PtrToStructure
(
pBuffers
,
typeof
(
Common
.
SecurityBuffer
));
ThisSecBuffer
.
Dispose
();
}
else
{
for
(
int
Index
=
0
;
Index
<
cBuffers
;
Index
++)
{
//The bits were written out the following order:
//int cbBuffer;
//int BufferType;
//pvBuffer;
//What we need to do here is to grab a hold of the pvBuffer allocate by the individual
//SecBuffer and release it...
int
CurrentOffset
=
Index
*
Marshal
.
SizeOf
(
typeof
(
Buffer
));
IntPtr
SecBufferpvBuffer
=
Marshal
.
ReadIntPtr
(
pBuffers
,
CurrentOffset
+
Marshal
.
SizeOf
(
typeof
(
int
))
+
Marshal
.
SizeOf
(
typeof
(
int
)));
Marshal
.
FreeHGlobal
(
SecBufferpvBuffer
);
}
}
Marshal
.
FreeHGlobal
(
pBuffers
);
pBuffers
=
IntPtr
.
Zero
;
}
}
internal
byte
[]
GetBytes
()
{
byte
[]
Buffer
=
null
;
if
(
pBuffers
==
IntPtr
.
Zero
)
{
throw
new
InvalidOperationException
(
"Object has already been disposed!!!"
);
}
if
(
cBuffers
==
1
)
{
Common
.
SecurityBuffer
ThisSecBuffer
=
(
Common
.
SecurityBuffer
)
Marshal
.
PtrToStructure
(
pBuffers
,
typeof
(
Common
.
SecurityBuffer
));
if
(
ThisSecBuffer
.
cbBuffer
>
0
)
{
Buffer
=
new
byte
[
ThisSecBuffer
.
cbBuffer
];
Marshal
.
Copy
(
ThisSecBuffer
.
pvBuffer
,
Buffer
,
0
,
ThisSecBuffer
.
cbBuffer
);
}
}
else
{
int
BytesToAllocate
=
0
;
for
(
int
Index
=
0
;
Index
<
cBuffers
;
Index
++)
{
//The bits were written out the following order:
//int cbBuffer;
//int BufferType;
//pvBuffer;
//What we need to do here calculate the total number of bytes we need to copy...
int
CurrentOffset
=
Index
*
Marshal
.
SizeOf
(
typeof
(
Buffer
));
BytesToAllocate
+=
Marshal
.
ReadInt32
(
pBuffers
,
CurrentOffset
);
}
Buffer
=
new
byte
[
BytesToAllocate
];
for
(
int
Index
=
0
,
BufferIndex
=
0
;
Index
<
cBuffers
;
Index
++)
{
//The bits were written out the following order:
//int cbBuffer;
//int BufferType;
//pvBuffer;
//Now iterate over the individual buffers and put them together into a
//byte array...
int
CurrentOffset
=
Index
*
Marshal
.
SizeOf
(
typeof
(
Buffer
));
int
BytesToCopy
=
Marshal
.
ReadInt32
(
pBuffers
,
CurrentOffset
);
IntPtr
SecBufferpvBuffer
=
Marshal
.
ReadIntPtr
(
pBuffers
,
CurrentOffset
+
Marshal
.
SizeOf
(
typeof
(
int
))
+
Marshal
.
SizeOf
(
typeof
(
int
)));
Marshal
.
Copy
(
SecBufferpvBuffer
,
Buffer
,
BufferIndex
,
BytesToCopy
);
BufferIndex
+=
BytesToCopy
;
}
}
return
(
Buffer
);
}
}
#
endregion
}
}
Titanium.Web.Proxy/Network/WinAuth/Security/EndPoint.cs
0 → 100644
View file @
d431a3ef
// http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html
namespace
Titanium.Web.Proxy.Network.WinAuth.Security
{
using
System
;
using
System.Runtime.InteropServices
;
using
System.Security.Principal
;
using
static
Common
;
internal
class
EndPoint
{
internal
static
byte
[]
AcquireInitialSecurityToken
(
string
hostname
)
{
byte
[]
token
=
null
;
//null for initial call
SecurityBufferDesciption
serverToken
=
new
SecurityBufferDesciption
();
SecurityBufferDesciption
clientToken
=
new
SecurityBufferDesciption
(
MaximumTokenSize
);
try
{
int
result
;
var
state
=
new
State
();
result
=
AcquireCredentialsHandle
(
WindowsIdentity
.
GetCurrent
().
Name
,
"NTLM"
,
Common
.
SecurityCredentialsOutbound
,
IntPtr
.
Zero
,
IntPtr
.
Zero
,
0
,
IntPtr
.
Zero
,
ref
state
.
Credentials
,
ref
NewLifeTime
);
if
(
result
!=
SuccessfulResult
)
{
// Credentials acquire operation failed.
return
null
;
}
result
=
InitializeSecurityContext
(
ref
state
.
Credentials
,
IntPtr
.
Zero
,
hostname
,
StandardContextAttributes
,
0
,
SecurityNativeDataRepresentation
,
ref
serverToken
,
0
,
out
state
.
Context
,
out
clientToken
,
out
NewContextAttributes
,
out
NewLifeTime
);
if
(
result
!=
IntermediateResult
)
{
// Client challenge issue operation failed.
return
null
;
}
token
=
clientToken
.
GetBytes
();
}
finally
{
clientToken
.
Dispose
();
serverToken
.
Dispose
();
}
return
token
;
}
/// <summary>
/// Acquire the final token to send
/// </summary>
/// <param name="hostname"></param>
/// <param name="serverChallenge"></param>
/// <returns></returns>
internal
static
byte
[]
AcquireFinalSecurityToken
(
string
hostname
,
byte
[]
serverChallenge
)
{
byte
[]
token
=
null
;
//user server challenge
SecurityBufferDesciption
serverToken
=
new
SecurityBufferDesciption
(
serverChallenge
);
SecurityBufferDesciption
clientToken
=
new
SecurityBufferDesciption
(
MaximumTokenSize
);
try
{
int
result
;
var
state
=
new
State
();
result
=
AcquireCredentialsHandle
(
WindowsIdentity
.
GetCurrent
().
Name
,
"NTLM"
,
SecurityCredentialsOutbound
,
IntPtr
.
Zero
,
IntPtr
.
Zero
,
0
,
IntPtr
.
Zero
,
ref
state
.
Credentials
,
ref
NewLifeTime
);
if
(
result
!=
SuccessfulResult
)
{
// Credentials acquire operation failed.
return
null
;
}
result
=
InitializeSecurityContext
(
ref
state
.
Credentials
,
IntPtr
.
Zero
,
hostname
,
StandardContextAttributes
,
0
,
SecurityNativeDataRepresentation
,
ref
serverToken
,
0
,
out
state
.
Context
,
out
clientToken
,
out
NewContextAttributes
,
out
NewLifeTime
);
if
(
result
!=
SuccessfulResult
)
{
// Client challenge issue operation failed.
return
null
;
}
token
=
clientToken
.
GetBytes
();
}
finally
{
clientToken
.
Dispose
();
serverToken
.
Dispose
();
}
return
token
;
}
#
region
Native
calls
to
secur32
.
dll
[
DllImport
(
"secur32.dll"
,
SetLastError
=
true
)]
static
extern
int
InitializeSecurityContext
(
ref
SecurityHandle
phCredential
,
//PCredHandle
IntPtr
phContext
,
//PCtxtHandle
string
pszTargetName
,
int
fContextReq
,
int
Reserved1
,
int
TargetDataRep
,
ref
SecurityBufferDesciption
pInput
,
//PSecBufferDesc SecBufferDesc
int
Reserved2
,
out
SecurityHandle
phNewContext
,
//PCtxtHandle
out
Common
.
SecurityBufferDesciption
pOutput
,
//PSecBufferDesc SecBufferDesc
out
uint
pfContextAttr
,
//managed ulong == 64 bits!!!
out
Common
.
SecurityInteger
ptsExpiry
);
//PTimeStamp
[
DllImport
(
"secur32.dll"
,
CharSet
=
CharSet
.
Auto
,
SetLastError
=
false
)]
private
static
extern
int
AcquireCredentialsHandle
(
string
pszPrincipal
,
//SEC_CHAR*
string
pszPackage
,
//SEC_CHAR* //"Kerberos","NTLM","Negotiative"
int
fCredentialUse
,
IntPtr
PAuthenticationID
,
//_LUID AuthenticationID,//pvLogonID, //PLUID
IntPtr
pAuthData
,
//PVOID
int
pGetKeyFn
,
//SEC_GET_KEY_FN
IntPtr
pvGetKeyArgument
,
//PVOID
ref
Common
.
SecurityHandle
phCredential
,
//SecHandle //PCtxtHandle ref
ref
Common
.
SecurityInteger
ptsExpiry
);
//PTimeStamp //TimeStamp ref
#
endregion
}
}
Titanium.Web.Proxy/Network/WinAuth/Security/LittleEndian.cs
0 → 100644
View file @
d431a3ef
//
// Mono.Security.BitConverterLE.cs
// Like System.BitConverter but always little endian
//
// Author:
// Bernie Solomon
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace
Titanium.Web.Proxy.Network.WinAuth.Security
{
using
System
;
internal
sealed
class
LittleEndian
{
private
LittleEndian
()
{
}
unsafe
private
static
byte
[]
GetUShortBytes
(
byte
*
bytes
)
{
if
(
BitConverter
.
IsLittleEndian
)
{
return
new
byte
[]
{
bytes
[
0
],
bytes
[
1
]
};
}
else
{
return
new
byte
[]
{
bytes
[
1
],
bytes
[
0
]
};
}
}
unsafe
private
static
byte
[]
GetUIntBytes
(
byte
*
bytes
)
{
if
(
BitConverter
.
IsLittleEndian
)
{
return
new
byte
[]
{
bytes
[
0
],
bytes
[
1
],
bytes
[
2
],
bytes
[
3
]
};
}
else
{
return
new
byte
[]
{
bytes
[
3
],
bytes
[
2
],
bytes
[
1
],
bytes
[
0
]
};
}
}
unsafe
private
static
byte
[]
GetULongBytes
(
byte
*
bytes
)
{
if
(
BitConverter
.
IsLittleEndian
)
{
return
new
byte
[]
{
bytes
[
0
],
bytes
[
1
],
bytes
[
2
],
bytes
[
3
],
bytes
[
4
],
bytes
[
5
],
bytes
[
6
],
bytes
[
7
]
};
}
else
{
return
new
byte
[]
{
bytes
[
7
],
bytes
[
6
],
bytes
[
5
],
bytes
[
4
],
bytes
[
3
],
bytes
[
2
],
bytes
[
1
],
bytes
[
0
]
};
}
}
unsafe
internal
static
byte
[]
GetBytes
(
bool
value
)
{
return
new
byte
[]
{
value
?
(
byte
)
1
:
(
byte
)
0
};
}
unsafe
internal
static
byte
[]
GetBytes
(
char
value
)
{
return
GetUShortBytes
((
byte
*)
&
value
);
}
unsafe
internal
static
byte
[]
GetBytes
(
short
value
)
{
return
GetUShortBytes
((
byte
*)
&
value
);
}
unsafe
internal
static
byte
[]
GetBytes
(
int
value
)
{
return
GetUIntBytes
((
byte
*)
&
value
);
}
unsafe
internal
static
byte
[]
GetBytes
(
long
value
)
{
return
GetULongBytes
((
byte
*)
&
value
);
}
unsafe
internal
static
byte
[]
GetBytes
(
ushort
value
)
{
return
GetUShortBytes
((
byte
*)
&
value
);
}
unsafe
internal
static
byte
[]
GetBytes
(
uint
value
)
{
return
GetUIntBytes
((
byte
*)
&
value
);
}
unsafe
internal
static
byte
[]
GetBytes
(
ulong
value
)
{
return
GetULongBytes
((
byte
*)
&
value
);
}
unsafe
internal
static
byte
[]
GetBytes
(
float
value
)
{
return
GetUIntBytes
((
byte
*)
&
value
);
}
unsafe
internal
static
byte
[]
GetBytes
(
double
value
)
{
return
GetULongBytes
((
byte
*)
&
value
);
}
unsafe
private
static
void
UShortFromBytes
(
byte
*
dst
,
byte
[]
src
,
int
startIndex
)
{
if
(
BitConverter
.
IsLittleEndian
)
{
dst
[
0
]
=
src
[
startIndex
];
dst
[
1
]
=
src
[
startIndex
+
1
];
}
else
{
dst
[
0
]
=
src
[
startIndex
+
1
];
dst
[
1
]
=
src
[
startIndex
];
}
}
unsafe
private
static
void
UIntFromBytes
(
byte
*
dst
,
byte
[]
src
,
int
startIndex
)
{
if
(
BitConverter
.
IsLittleEndian
)
{
dst
[
0
]
=
src
[
startIndex
];
dst
[
1
]
=
src
[
startIndex
+
1
];
dst
[
2
]
=
src
[
startIndex
+
2
];
dst
[
3
]
=
src
[
startIndex
+
3
];
}
else
{
dst
[
0
]
=
src
[
startIndex
+
3
];
dst
[
1
]
=
src
[
startIndex
+
2
];
dst
[
2
]
=
src
[
startIndex
+
1
];
dst
[
3
]
=
src
[
startIndex
];
}
}
unsafe
private
static
void
ULongFromBytes
(
byte
*
dst
,
byte
[]
src
,
int
startIndex
)
{
if
(
BitConverter
.
IsLittleEndian
)
{
for
(
int
i
=
0
;
i
<
8
;
++
i
)
dst
[
i
]
=
src
[
startIndex
+
i
];
}
else
{
for
(
int
i
=
0
;
i
<
8
;
++
i
)
dst
[
i
]
=
src
[
startIndex
+
(
7
-
i
)];
}
}
unsafe
internal
static
bool
ToBoolean
(
byte
[]
value
,
int
startIndex
)
{
return
value
[
startIndex
]
!=
0
;
}
unsafe
internal
static
char
ToChar
(
byte
[]
value
,
int
startIndex
)
{
char
ret
;
UShortFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
unsafe
internal
static
short
ToInt16
(
byte
[]
value
,
int
startIndex
)
{
short
ret
;
UShortFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
unsafe
internal
static
int
ToInt32
(
byte
[]
value
,
int
startIndex
)
{
int
ret
;
UIntFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
unsafe
internal
static
long
ToInt64
(
byte
[]
value
,
int
startIndex
)
{
long
ret
;
ULongFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
unsafe
internal
static
ushort
ToUInt16
(
byte
[]
value
,
int
startIndex
)
{
ushort
ret
;
UShortFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
unsafe
internal
static
uint
ToUInt32
(
byte
[]
value
,
int
startIndex
)
{
uint
ret
;
UIntFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
unsafe
internal
static
ulong
ToUInt64
(
byte
[]
value
,
int
startIndex
)
{
ulong
ret
;
ULongFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
unsafe
internal
static
float
ToSingle
(
byte
[]
value
,
int
startIndex
)
{
float
ret
;
UIntFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
unsafe
internal
static
double
ToDouble
(
byte
[]
value
,
int
startIndex
)
{
double
ret
;
ULongFromBytes
((
byte
*)
&
ret
,
value
,
startIndex
);
return
ret
;
}
}
}
Titanium.Web.Proxy/Network/WinAuth/Security/Message.cs
0 → 100644
View file @
d431a3ef
//
// Nancy.Authentication.Ntlm.Protocol.Type3Message - Authentication
//
// Author:
// Sebastien Pouliot <sebastien@ximian.com>
//
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
//
// References
// a. NTLM Authentication Scheme for HTTP, Ronald Tschalär
// http://www.innovation.ch/java/ntlm.html
// b. The NTLM Authentication Protocol, Copyright © 2003 Eric Glass
// http://davenport.sourceforge.net/ntlm.html
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace
Titanium.Web.Proxy.Network.WinAuth.Security
{
using
System
;
using
System.Text
;
internal
class
Message
{
static
private
byte
[]
header
=
{
0x4e
,
0x54
,
0x4c
,
0x4d
,
0x53
,
0x53
,
0x50
,
0x00
};
internal
Message
(
byte
[]
message
)
{
_type
=
3
;
Decode
(
message
);
}
/// <summary>
/// Domain name
/// </summary>
internal
string
Domain
{
get
;
private
set
;
}
/// <summary>
/// Username
/// </summary>
internal
string
Username
{
get
;
private
set
;
}
private
int
_type
;
private
Common
.
NtlmFlags
_flags
;
internal
Common
.
NtlmFlags
Flags
{
get
{
return
_flags
;
}
set
{
_flags
=
value
;
}
}
// methods
private
void
Decode
(
byte
[]
message
)
{
//base.Decode (message);
if
(
message
==
null
)
throw
new
ArgumentNullException
(
"message"
);
if
(
message
.
Length
<
12
)
{
string
msg
=
"Minimum Type3 message length is 12 bytes."
;
throw
new
ArgumentOutOfRangeException
(
"message"
,
message
.
Length
,
msg
);
}
if
(!
CheckHeader
(
message
))
{
string
msg
=
"Invalid Type3 message header."
;
throw
new
ArgumentException
(
msg
,
"message"
);
}
if
(
LittleEndian
.
ToUInt16
(
message
,
56
)
!=
message
.
Length
)
{
string
msg
=
"Invalid Type3 message length."
;
throw
new
ArgumentException
(
msg
,
"message"
);
}
if
(
message
.
Length
>=
64
)
{
Flags
=
(
Common
.
NtlmFlags
)
LittleEndian
.
ToUInt32
(
message
,
60
);
}
else
{
Flags
=
(
Common
.
NtlmFlags
)
0x8201
;
}
int
dom_len
=
LittleEndian
.
ToUInt16
(
message
,
28
);
int
dom_off
=
LittleEndian
.
ToUInt16
(
message
,
32
);
this
.
Domain
=
DecodeString
(
message
,
dom_off
,
dom_len
);
int
user_len
=
LittleEndian
.
ToUInt16
(
message
,
36
);
int
user_off
=
LittleEndian
.
ToUInt16
(
message
,
40
);
this
.
Username
=
DecodeString
(
message
,
user_off
,
user_len
);
}
string
DecodeString
(
byte
[]
buffer
,
int
offset
,
int
len
)
{
if
((
Flags
&
Common
.
NtlmFlags
.
NegotiateUnicode
)
!=
0
)
{
return
Encoding
.
Unicode
.
GetString
(
buffer
,
offset
,
len
);
}
else
{
return
Encoding
.
ASCII
.
GetString
(
buffer
,
offset
,
len
);
}
}
protected
bool
CheckHeader
(
byte
[]
message
)
{
for
(
int
i
=
0
;
i
<
header
.
Length
;
i
++)
{
if
(
message
[
i
]
!=
header
[
i
])
return
false
;
}
return
(
LittleEndian
.
ToUInt32
(
message
,
8
)
==
_type
);
}
}
}
Titanium.Web.Proxy/Network/WinAuth/Security/State.cs
0 → 100644
View file @
d431a3ef
namespace
Titanium.Web.Proxy.Network.WinAuth.Security
{
using
System
;
/// <summary>
/// Status of authenticated session
/// </summary>
internal
class
State
{
internal
State
()
{
this
.
Credentials
=
new
Common
.
SecurityHandle
(
0
);
this
.
Context
=
new
Common
.
SecurityHandle
(
0
);
this
.
LastSeen
=
DateTime
.
MinValue
;
}
/// <summary>
/// Credentials used to validate NTLM hashes
/// </summary>
internal
Common
.
SecurityHandle
Credentials
;
/// <summary>
/// Context will be used to validate HTLM hashes
/// </summary>
internal
Common
.
SecurityHandle
Context
;
/// <summary>
/// Timestamp needed to calculate validity of the authenticated session
/// </summary>
internal
DateTime
LastSeen
;
internal
bool
isOlder
(
int
seconds
)
{
return
(
this
.
LastSeen
.
AddSeconds
(
seconds
)
<
DateTime
.
UtcNow
)
?
true
:
false
;
}
internal
void
ResetHandles
()
{
this
.
Credentials
.
Reset
();
this
.
Context
.
Reset
();
}
internal
void
UpdatePresence
()
{
this
.
LastSeen
=
DateTime
.
UtcNow
;
}
}
}
Titanium.Web.Proxy/Network/WinAuth/WinAuthHandler.cs
0 → 100644
View file @
d431a3ef
using
Titanium.Web.Proxy.Network.WinAuth.Security
;
using
System
;
namespace
Titanium.Web.Proxy.Network.WinAuth
{
/// <summary>
/// A handler for NTLM/Kerberos windows authentication challenge from server
/// NTLM process details below
/// https://blogs.msdn.microsoft.com/chiranth/2013/09/20/ntlm-want-to-know-how-it-works/
/// </summary>
public
static
class
WinAuthHandler
{
/// <summary>
/// Get the initial client token for server
/// using credentials of user running the proxy server process
/// </summary>
/// <param name="serverHostname"></param>
/// <returns></returns>
public
static
string
GetInitialAuthToken
(
string
serverHostname
)
{
var
tokenBytes
=
EndPoint
.
AcquireInitialSecurityToken
(
serverHostname
);
return
string
.
Concat
(
" "
,
Convert
.
ToBase64String
(
tokenBytes
));
}
/// <summary>
/// Get the final token given the server challenge token
/// </summary>
/// <param name="serverHostname"></param>
/// <param name="serverToken"></param>
/// <returns></returns>
public
static
string
GetFinalAuthToken
(
string
serverHostname
,
string
serverToken
)
{
var
tokenBytes
=
EndPoint
.
AcquireFinalSecurityToken
(
serverHostname
,
Convert
.
FromBase64String
(
serverToken
));
return
string
.
Concat
(
" "
,
Convert
.
ToBase64String
(
tokenBytes
));
}
}
}
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
d431a3ef
...
@@ -37,6 +37,7 @@
...
@@ -37,6 +37,7 @@
<DocumentationFile>
bin\Release\Titanium.Web.Proxy.XML
</DocumentationFile>
<DocumentationFile>
bin\Release\Titanium.Web.Proxy.XML
</DocumentationFile>
<DebugType>
none
</DebugType>
<DebugType>
none
</DebugType>
<DebugSymbols>
false
</DebugSymbols>
<DebugSymbols>
false
</DebugSymbols>
<AllowUnsafeBlocks>
true
</AllowUnsafeBlocks>
</PropertyGroup>
</PropertyGroup>
<PropertyGroup>
<PropertyGroup>
<SignAssembly>
true
</SignAssembly>
<SignAssembly>
true
</SignAssembly>
...
@@ -105,6 +106,13 @@
...
@@ -105,6 +106,13 @@
<Compile
Include=
"Network\Tcp\TcpConnectionFactory.cs"
/>
<Compile
Include=
"Network\Tcp\TcpConnectionFactory.cs"
/>
<Compile
Include=
"Models\HttpHeader.cs"
/>
<Compile
Include=
"Models\HttpHeader.cs"
/>
<Compile
Include=
"Http\HttpWebClient.cs"
/>
<Compile
Include=
"Http\HttpWebClient.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\BufferWrapper.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\Common.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\EndPoint.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\LittleEndian.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\Message.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\State.cs"
/>
<Compile
Include=
"Network\WinAuth\WinAuthHandler.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"ProxyAuthorizationHandler.cs"
/>
<Compile
Include=
"ProxyAuthorizationHandler.cs"
/>
<Compile
Include=
"RequestHandler.cs"
/>
<Compile
Include=
"RequestHandler.cs"
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment