└── HTTP_Proxy
├── HTTP_Proxy.vcproj
├── asm
├── chkstk.asm
└── llmul.asm
├── connection.cpp
├── connection.h
├── doublylinkedlist.cpp
├── doublylinkedlist.h
├── file_operations.cpp
├── file_operations.h
├── globals.h
├── http.cpp
├── http.h
├── lite_advapi32.cpp
├── lite_advapi32.h
├── lite_crypt32.cpp
├── lite_crypt32.h
├── lite_dlls.cpp
├── lite_dlls.h
├── lite_normaliz.cpp
├── lite_normaliz.h
├── lite_ntdll.cpp
├── lite_ntdll.h
├── lite_rpcrt4.cpp
├── lite_rpcrt4.h
├── lite_shell32.cpp
├── lite_shell32.h
├── lite_ws2_32.cpp
├── lite_ws2_32.h
├── main.cpp
├── ssl.cpp
├── ssl.h
├── utilities.cpp
└── utilities.h
/HTTP_Proxy/HTTP_Proxy.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
15 |
16 |
17 |
20 |
21 |
22 |
29 |
32 |
35 |
38 |
41 |
44 |
47 |
59 |
62 |
65 |
68 |
78 |
81 |
84 |
87 |
90 |
93 |
96 |
99 |
100 |
108 |
111 |
114 |
117 |
120 |
123 |
126 |
144 |
147 |
150 |
153 |
166 |
169 |
172 |
175 |
178 |
181 |
184 |
187 |
188 |
189 |
190 |
191 |
192 |
197 |
200 |
201 |
204 |
205 |
208 |
209 |
212 |
213 |
216 |
217 |
220 |
221 |
224 |
225 |
228 |
229 |
232 |
233 |
236 |
237 |
240 |
241 |
244 |
245 |
248 |
249 |
252 |
253 |
256 |
257 |
260 |
263 |
264 |
267 |
268 |
269 |
270 |
275 |
278 |
279 |
282 |
283 |
286 |
287 |
290 |
291 |
294 |
295 |
298 |
299 |
302 |
303 |
306 |
307 |
310 |
311 |
314 |
315 |
318 |
319 |
322 |
323 |
326 |
327 |
330 |
331 |
334 |
335 |
336 |
341 |
342 |
343 |
344 |
345 |
346 |
--------------------------------------------------------------------------------
/HTTP_Proxy/asm/chkstk.asm:
--------------------------------------------------------------------------------
1 | page ,132
2 | title chkstk - C stack checking routine
3 | ;***
4 | ;chkstk.asm - C stack checking routine
5 | ;
6 | ; Copyright (c) Microsoft Corporation. All rights reserved.
7 | ;
8 | ;Purpose:
9 | ; Provides support for automatic stack checking in C procedures
10 | ; when stack checking is enabled.
11 | ;
12 | ;*******************************************************************************
13 |
14 | ;.xlist
15 | ;include cruntime.inc
16 | ;.list
17 |
18 | ; size of a page of memory
19 |
20 | _PAGESIZE_ equ 1000h
21 |
22 |
23 | ; CODESEG
24 | .386
25 | .MODEL Flat
26 | .CODE
27 |
28 | page
29 | ;***
30 | ;_chkstk - check stack upon procedure entry
31 | ;
32 | ;Purpose:
33 | ; Provide stack checking on procedure entry. Method is to simply probe
34 | ; each page of memory required for the stack in descending order. This
35 | ; causes the necessary pages of memory to be allocated via the guard
36 | ; page scheme, if possible. In the event of failure, the OS raises the
37 | ; _XCPT_UNABLE_TO_GROW_STACK exception.
38 | ;
39 | ; NOTE: Currently, the (EAX < _PAGESIZE_) code path falls through
40 | ; to the "lastpage" label of the (EAX >= _PAGESIZE_) code path. This
41 | ; is small; a minor speed optimization would be to special case
42 | ; this up top. This would avoid the painful save/restore of
43 | ; ecx and would shorten the code path by 4-6 instructions.
44 | ;
45 | ;Entry:
46 | ; EAX = size of local frame
47 | ;
48 | ;Exit:
49 | ; ESP = new stackframe, if successful
50 | ;
51 | ;Uses:
52 | ; EAX
53 | ;
54 | ;Exceptions:
55 | ; _XCPT_GUARD_PAGE_VIOLATION - May be raised on a page probe. NEVER TRAP
56 | ; THIS!!!! It is used by the OS to grow the
57 | ; stack on demand.
58 | ; _XCPT_UNABLE_TO_GROW_STACK - The stack cannot be grown. More precisely,
59 | ; the attempt by the OS memory manager to
60 | ; allocate another guard page in response
61 | ; to a _XCPT_GUARD_PAGE_VIOLATION has
62 | ; failed.
63 | ;
64 | ;*******************************************************************************
65 |
66 | public _alloca_probe
67 |
68 | __chkstk proc
69 |
70 | _alloca_probe = __chkstk
71 |
72 | push ecx
73 |
74 | ; Calculate new TOS.
75 |
76 | lea ecx, [esp] + 8 - 4 ; TOS before entering function + size for ret value
77 | sub ecx, eax ; new TOS
78 |
79 | ; Handle allocation size that results in wraparound.
80 | ; Wraparound will result in StackOverflow exception.
81 |
82 | sbb eax, eax ; 0 if CF==0, ~0 if CF==1
83 | not eax ; ~0 if TOS did not wrapped around, 0 otherwise
84 | and ecx, eax ; set to 0 if wraparound
85 |
86 | mov eax, esp ; current TOS
87 | and eax, not ( _PAGESIZE_ - 1) ; Round down to current page boundary
88 |
89 | cs10:
90 | cmp ecx, eax ; Is new TOS
91 | jb short cs20 ; in probed page?
92 | mov eax, ecx ; yes.
93 | pop ecx
94 | xchg esp, eax ; update esp
95 | mov eax, dword ptr [eax] ; get return address
96 | mov dword ptr [esp], eax ; and put it at new TOS
97 | ret
98 |
99 | ; Find next lower page and probe
100 | cs20:
101 | sub eax, _PAGESIZE_ ; decrease by PAGESIZE
102 | test dword ptr [eax],eax ; probe page.
103 | jmp short cs10
104 |
105 | __chkstk endp
106 |
107 | end
108 |
--------------------------------------------------------------------------------
/HTTP_Proxy/asm/llmul.asm:
--------------------------------------------------------------------------------
1 | title llmul - long multiply routine
2 | ;***
3 | ;llmul.asm - long multiply routine
4 | ;
5 | ; Copyright (c) Microsoft Corporation. All rights reserved.
6 | ;
7 | ;Purpose:
8 | ; Defines long multiply routine
9 | ; Both signed and unsigned routines are the same, since multiply's
10 | ; work out the same in 2's complement
11 | ; creates the following routine:
12 | ; __allmul
13 | ;
14 | ;*******************************************************************************
15 |
16 |
17 | ;.xlist
18 | ;include cruntime.inc
19 | ;include mm.inc
20 | ;.list
21 |
22 | ;***
23 | ;llmul - long multiply routine
24 | ;
25 | ;Purpose:
26 | ; Does a long multiply (same for signed/unsigned)
27 | ; Parameters are not changed.
28 | ;
29 | ;Entry:
30 | ; Parameters are passed on the stack:
31 | ; 1st pushed: multiplier (QWORD)
32 | ; 2nd pushed: multiplicand (QWORD)
33 | ;
34 | ;Exit:
35 | ; EDX:EAX - product of multiplier and multiplicand
36 | ; NOTE: parameters are removed from the stack
37 | ;
38 | ;Uses:
39 | ; ECX
40 | ;
41 | ;Exceptions:
42 | ;
43 | ;*******************************************************************************
44 |
45 | ; CODESEG
46 | .386
47 | .MODEL Flat
48 | .CODE
49 |
50 | __allmul PROC NEAR
51 |
52 | LOWORD equ [0]
53 | HIWORD equ [4]
54 | A EQU [esp + 4] ; stack address of a
55 | B EQU [esp + 12] ; stack address of b
56 |
57 | ;
58 | ; AHI, BHI : upper 32 bits of A and B
59 | ; ALO, BLO : lower 32 bits of A and B
60 | ;
61 | ; ALO * BLO
62 | ; ALO * BHI
63 | ; + BLO * AHI
64 | ; ---------------------
65 | ;
66 |
67 | mov eax,HIWORD(A)
68 | mov ecx,HIWORD(B)
69 | or ecx,eax ;test for both hiwords zero.
70 | mov ecx,LOWORD(B)
71 | jnz short hard ;both are zero, just mult ALO and BLO
72 |
73 | mov eax,LOWORD(A)
74 | mul ecx
75 |
76 | ret 16 ; callee restores the stack
77 |
78 | hard:
79 | push ebx
80 |
81 | ; must redefine A and B since esp has been altered
82 |
83 | A2 EQU [esp + 8] ; stack address of a
84 | B2 EQU [esp + 16] ; stack address of b
85 |
86 | mul ecx ;eax has AHI, ecx has BLO, so AHI * BLO
87 | mov ebx,eax ;save result
88 |
89 | mov eax,LOWORD(A2)
90 | mul dword ptr HIWORD(B2) ;ALO * BHI
91 | add ebx,eax ;ebx = ((ALO * BHI) + (AHI * BLO))
92 |
93 | mov eax,LOWORD(A2) ;ecx = BLO
94 | mul ecx ;so edx:eax = ALO*BLO
95 | add edx,ebx ;now edx has all the LO*HI stuff
96 |
97 | pop ebx
98 |
99 | ret 16 ; callee restores the stack
100 |
101 | __allmul ENDP
102 |
103 | end
104 |
--------------------------------------------------------------------------------
/HTTP_Proxy/connection.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _CONNECTION_H
20 | #define _CONNECTION_H
21 |
22 | #include "globals.h"
23 | #include "ssl.h"
24 | #include "doublylinkedlist.h"
25 |
26 | #include
27 |
28 | #define BUFFER_SIZE 16384 // Maximum size of an SSL record.
29 |
30 | #define DEFAULT_PORT 80
31 | #define DEFAULT_PORT_SECURE 443
32 |
33 | #define REQUEST_TYPE_UNKNOWN 0
34 | #define REQUEST_TYPE_GET 1
35 | #define REQUEST_TYPE_POST 2
36 | #define REQUEST_TYPE_CONNECT 3
37 | #define REQUEST_TYPE_UNSUPPORTED 4
38 |
39 | #define STEP_GET_REQUEST 0
40 | #define STEP_GOT_REQUEST 1
41 | #define STEP_RELAY_DATA 2
42 | #define STEP_CONNECT_TO_SERVER 3
43 | #define STEP_DENY_CONNECTION 4
44 | #define STEP_PROXY_AUTH 5
45 |
46 | #define CONNECTION_UNKNOWN 0
47 | #define CONNECTION_KEEP_ALIVE 1
48 | #define CONNECTION_CLOSE 2
49 |
50 | #define CONTEXT_TYPE_CLIENT 0 // The connection that was made to the proxy.
51 | #define CONTEXT_TYPE_SERVER 1 // The connection that was made from the proxy.
52 |
53 | #define PROTOCOL_UNKNOWN 0
54 | #define PROTOCOL_HTTP 1
55 | #define PROTOCOL_HTTPS 2
56 | #define PROTOCOL_RELATIVE 3
57 |
58 | #define TIME_OUT_FALSE 0
59 | #define TIME_OUT_TRUE 1
60 | #define TIME_OUT_RETRY 2
61 |
62 | #define PROXY_TYPE_UNKNOWN 0
63 | #define PROXY_TYPE_HTTP 1
64 | #define PROXY_TYPE_HTTPS 2
65 | #define PROXY_TYPE_HTTP_AND_HTTPS ( PROXY_TYPE_HTTP | PROXY_TYPE_HTTPS ) // 3
66 | #define PROXY_TYPE_IS_HTTPS 4
67 |
68 | // For listen and accept functions
69 | #define LA_STATUS_FAILED -1
70 | #define LA_STATUS_UNKNOWN 0
71 | #define LA_STATUS_OK 1
72 | #define LA_STATUS_DUPLICATE 2
73 |
74 | #define AUTH_TYPE_NONE 0
75 | #define AUTH_TYPE_BASIC 1
76 | #define AUTH_TYPE_DIGEST 2
77 | #define AUTH_TYPE_UNHANDLED 3
78 |
79 | enum IO_OPERATION
80 | {
81 | IO_Accept,
82 | IO_Connect,
83 | IO_ClientHandshakeReply,
84 | IO_ClientHandshakeResponse,
85 | IO_ServerHandshakeReply,
86 | IO_ServerHandshakeResponse,
87 | IO_Shutdown,
88 | IO_Close,
89 | IO_Write,
90 | IO_GetRequest,
91 | IO_ProcessWrite,
92 | IO_Timeout
93 | };
94 |
95 | struct HEADER_INFO
96 | {
97 | unsigned long long content_sent;
98 | unsigned long long content_length;
99 | unsigned char chunked_ending[ 5 ];
100 | unsigned char chunked_ending_size;
101 | bool chunked_transfer;
102 | };
103 |
104 | struct URL_INFO
105 | {
106 | char *host;
107 | char *resource;
108 | unsigned char protocol;
109 | unsigned short port;
110 | };
111 |
112 | struct REQUEST_INFO
113 | {
114 | CRITICAL_SECTION context_cs;
115 |
116 | URL_INFO url_info;
117 |
118 | unsigned char connection_steps;
119 |
120 | unsigned char shared_count;
121 |
122 | unsigned char request_type;
123 | };
124 |
125 | struct SOCKET_CONTEXT;
126 |
127 | struct SOCKET_CONTEXT
128 | {
129 | WSAOVERLAPPED overlapped_read;
130 | WSAOVERLAPPED overlapped_write;
131 |
132 | HEADER_INFO header_info;
133 |
134 | DoublyLinkedList context_node; // Self reference to the g_context_list.
135 |
136 | WSABUF wsabuf_read;
137 | WSABUF wsabuf_write;
138 | WSABUF temp_wsabuf_write;
139 |
140 | REQUEST_INFO *shared_request_info;
141 |
142 | SOCKET_CONTEXT *relay_context;
143 |
144 | CHAR *buffer_read;
145 | CHAR *buffer_write;
146 |
147 | SSL *ssl;
148 |
149 | addrinfoW *address_info;
150 |
151 | SOCKET socket;
152 |
153 | IO_OPERATION current_operation_read;
154 |
155 | IO_OPERATION current_operation_write;
156 | IO_OPERATION next_operation_write;
157 |
158 | volatile LONG pending_operations;
159 |
160 | volatile LONG timeout;
161 |
162 | unsigned char context_type; // 0 = Client (outgoing connections), 1 = Server (incoming connections)
163 |
164 | unsigned char proxy_type;
165 |
166 | unsigned char timed_out;
167 |
168 | bool create_new_connection;
169 | bool post_completed;
170 |
171 | bool do_read;
172 | bool do_write;
173 | bool is_reading;
174 | bool is_writing;
175 | bool finish_writing;
176 | };
177 |
178 | SECURITY_STATUS SSL_WSAAccept( SOCKET_CONTEXT *context, bool &sent );
179 | SECURITY_STATUS SSL_WSAAccept_Reply( SOCKET_CONTEXT *context, bool &sent );
180 | SECURITY_STATUS SSL_WSAAccept_Response( SOCKET_CONTEXT *context, bool &sent );
181 |
182 | SECURITY_STATUS SSL_WSAConnect( SOCKET_CONTEXT *context, char *host, bool &sent );
183 | SECURITY_STATUS SSL_WSAConnect_Response( SOCKET_CONTEXT *context, bool &sent );
184 | SECURITY_STATUS SSL_WSAConnect_Reply( SOCKET_CONTEXT *context, bool &sent );
185 |
186 | SECURITY_STATUS SSL_WSASend( SOCKET_CONTEXT *context, WSABUF *send_buf, bool &sent );
187 | SECURITY_STATUS SSL_WSARecv( SOCKET_CONTEXT *context, bool &sent );
188 |
189 | SECURITY_STATUS SSL_WSARecv_Decrypt( SSL *ssl, LPWSABUF lpBuffers, DWORD &lpNumberOfBytesDecrypted );
190 |
191 | SECURITY_STATUS SSL_WSAShutdown( SOCKET_CONTEXT *context, bool &sent );
192 |
193 | DWORD WINAPI IOCPServer( LPVOID pArgs );
194 | DWORD WINAPI IOCPConnection( LPVOID WorkThreadContext );
195 |
196 | SOCKET_CONTEXT *CreateSocketContext();
197 | SOCKET_CONTEXT *UpdateCompletionPort( SOCKET socket, bool is_listen_socket );
198 | bool CreateConnection( SOCKET_CONTEXT *context, char *host, unsigned short port );
199 | bool LoadConnectEx();
200 | char CreateListenSocket( wchar_t *host, unsigned short port, bool &use_ipv6, unsigned char proxy_type );
201 | char CreateAcceptSocket( bool use_ipv6, unsigned char proxy_type );
202 | void CleanupConnection( SOCKET_CONTEXT *context );
203 |
204 | bool TrySend( SOCKET_CONTEXT *context );
205 | bool TryReceive( SOCKET_CONTEXT *context );
206 |
207 | void BeginClose( SOCKET_CONTEXT *context, IO_OPERATION io_operation );
208 |
209 | SOCKET CreateSocket( bool IPv6 = false );
210 |
211 | void EnableTimer( bool timer_state );
212 |
213 | extern HANDLE g_hIOCP;
214 |
215 | extern bool g_shutdown_server;
216 | extern bool g_restart_server;
217 |
218 | extern WSAEVENT g_hCleanupEvent[ 1 ];
219 |
220 | extern CRITICAL_SECTION context_list_cs; // Guard access to the global context list.
221 |
222 | extern DoublyLinkedList *g_context_list;
223 |
224 | #endif
225 |
--------------------------------------------------------------------------------
/HTTP_Proxy/doublylinkedlist.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "doublylinkedlist.h"
20 |
21 | #define STRICT
22 | #define WIN32_LEAN_AND_MEAN
23 | #include
24 |
25 | DoublyLinkedList *DLL_CreateNode( void *data )
26 | {
27 | DoublyLinkedList *dll = ( DoublyLinkedList * )GlobalAlloc( GPTR, sizeof( DoublyLinkedList ) );
28 | if ( dll != NULL )
29 | {
30 | dll->next = NULL;
31 | dll->prev = NULL;
32 | dll->data = data;
33 | }
34 |
35 | return dll;
36 | }
37 |
38 | void DLL_RemoveNode( DoublyLinkedList **head, DoublyLinkedList *node )
39 | {
40 | if ( *head != NULL && node != NULL )
41 | {
42 | if ( node == *head ) // Node is the head.
43 | {
44 | if ( node->next != NULL ) // See if we can make a new head.
45 | {
46 | if ( node->next != node->prev ) // Make sure the new tail's previous value isn't itself.
47 | {
48 | node->next->prev = node->prev; // Set the new tail.
49 | }
50 | else
51 | {
52 | node->next->prev = NULL;
53 | }
54 |
55 | *head = node->next;
56 | }
57 | else // No head exists now.
58 | {
59 | *head = NULL;
60 | }
61 | }
62 | else if ( node->next == NULL ) // Node is a tail.
63 | {
64 | if ( node->prev != NULL ) // This should always be the case so long as node != head.
65 | {
66 | if ( node->prev != *head ) // Make sure the node's previous value is not the head.
67 | {
68 | if ( ( *head )->prev == node ) // Make sure the head list actually contains the node we're removing.
69 | {
70 | ( *head )->prev = node->prev; // Set the new tail.
71 | }
72 |
73 | node->prev->next = NULL;
74 | }
75 | else // All that exists now is the head.
76 | {
77 | ( *head )->next = NULL;
78 | ( *head )->prev = NULL;
79 | }
80 | }
81 | }
82 | else if ( node->next != NULL && node->prev != NULL ) // Node is between two other nodes.
83 | {
84 | node->prev->next = node->next;
85 | node->next->prev = node->prev;
86 | }
87 |
88 | node->next = NULL;
89 | node->prev = NULL;
90 | }
91 | }
92 |
93 | void DLL_AddNode( DoublyLinkedList **head, DoublyLinkedList *node, int position )
94 | {
95 | if ( node == NULL )
96 | {
97 | return;
98 | }
99 |
100 | if ( *head == NULL )
101 | {
102 | *head = node;
103 | return;
104 | }
105 |
106 | if ( position < 0 ) // Insert node as the new tail.
107 | {
108 | node->next = NULL;
109 |
110 | if ( ( *head )->prev != NULL ) // Head has a tail.
111 | {
112 | node->prev = ( *head )->prev;
113 | ( *head )->prev->next = node;
114 | }
115 | else // Head has no tail.
116 | {
117 | node->prev = *head;
118 | ( *head )->next = node;
119 | }
120 |
121 | ( *head )->prev = node;
122 | }
123 | else if ( position == 0 ) // Insert node as the new head.
124 | {
125 | node->next = *head;
126 | node->prev = ( *head )->prev;
127 | ( *head )->prev = node;
128 |
129 | *head = node; // Set the new head.
130 | }
131 | else
132 | {
133 | int count = 0;
134 | DoublyLinkedList *last_node = *head;
135 | DoublyLinkedList *current_node = ( *head )->next;
136 | while ( current_node != NULL )
137 | {
138 | if ( ++count == position )
139 | {
140 | node->next = current_node;
141 | node->prev = last_node;
142 | last_node->next = node;
143 | return;
144 | }
145 |
146 | last_node = current_node;
147 | current_node = current_node->next;
148 | }
149 |
150 | // The position is at the end of the list. Add node as the new tail.
151 | if ( current_node == NULL && ++count == position )
152 | {
153 | node->next = current_node;
154 | node->prev = last_node;
155 | last_node->next = node;
156 |
157 | ( *head )->prev = node;
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/HTTP_Proxy/doublylinkedlist.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _DOUBLYLINKEDLIST_H
20 | #define _DOUBLYLINKEDLIST_H
21 |
22 | struct DoublyLinkedList
23 | {
24 | DoublyLinkedList *prev;
25 | DoublyLinkedList *next;
26 | void *data;
27 | };
28 |
29 |
30 | DoublyLinkedList *DLL_CreateNode( void *data );
31 |
32 | void DLL_RemoveNode( DoublyLinkedList **head, DoublyLinkedList *node );
33 | void DLL_AddNode( DoublyLinkedList **head, DoublyLinkedList *node, int position );
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/HTTP_Proxy/file_operations.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "globals.h"
20 |
21 | #include "file_operations.h"
22 | #include "utilities.h"
23 |
24 | #include "connection.h"
25 |
26 | char read_config( wchar_t *filename )
27 | {
28 | char status = 0;
29 |
30 | HANDLE hFile_cfg = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
31 | if ( hFile_cfg != INVALID_HANDLE_VALUE )
32 | {
33 | DWORD read = 0, pos = 0;
34 | DWORD fz = GetFileSize( hFile_cfg, NULL );
35 |
36 | // Our config file is going to be small. If it's something else, we're not going to read it.
37 | if ( fz >= 33 && fz < 10240 )
38 | {
39 | char *cfg_buf = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * fz + 1 );
40 |
41 | ReadFile( hFile_cfg, cfg_buf, sizeof( char ) * fz, &read, NULL );
42 |
43 | cfg_buf[ fz ] = 0; // Guarantee a NULL terminated buffer.
44 |
45 | // Read the config. It must be in the order specified below.
46 | if ( read == fz && _memcmp( cfg_buf, MAGIC_ID_SETTINGS, 4 ) == 0 )
47 | {
48 | char *next = cfg_buf + 4;
49 |
50 | _memcpy_s( &cfg_proxy_type, sizeof( unsigned char ), next, sizeof( unsigned char ) );
51 | next += sizeof( unsigned char );
52 |
53 | _memcpy_s( &cfg_port, sizeof( unsigned short ), next, sizeof( unsigned short ) );
54 | next += sizeof( unsigned short );
55 |
56 | _memcpy_s( &cfg_require_authentication, sizeof( bool ), next, sizeof( bool ) );
57 | next += sizeof( bool );
58 |
59 | _memcpy_s( &cfg_auth_type, sizeof( unsigned char ), next, sizeof( unsigned char ) );
60 | next += sizeof( unsigned char );
61 |
62 | _memcpy_s( &cfg_forward_authentication, sizeof( bool ), next, sizeof( bool ) );
63 | next += sizeof( bool );
64 |
65 | _memcpy_s( &cfg_forward_connections, sizeof( bool ), next, sizeof( bool ) );
66 | next += sizeof( bool );
67 |
68 | _memcpy_s( &cfg_forward_port, sizeof( unsigned short ), next, sizeof( unsigned short ) );
69 | next += sizeof( unsigned short );
70 |
71 | _memcpy_s( &cfg_port_s, sizeof( unsigned short ), next, sizeof( unsigned short ) );
72 | next += sizeof( unsigned short );
73 |
74 | _memcpy_s( &cfg_require_authentication_s, sizeof( bool ), next, sizeof( bool ) );
75 | next += sizeof( bool );
76 |
77 | _memcpy_s( &cfg_auth_type_s, sizeof( unsigned char ), next, sizeof( unsigned char ) );
78 | next += sizeof( unsigned char );
79 |
80 | _memcpy_s( &cfg_forward_authentication_s, sizeof( bool ), next, sizeof( bool ) );
81 | next += sizeof( bool );
82 |
83 | _memcpy_s( &cfg_forward_connections_s, sizeof( bool ), next, sizeof( bool ) );
84 | next += sizeof( bool );
85 |
86 | _memcpy_s( &cfg_forward_port_s, sizeof( unsigned short ), next, sizeof( unsigned short ) );
87 | next += sizeof( unsigned short );
88 |
89 | _memcpy_s( &cfg_use_ssl, sizeof( bool ), next, sizeof( bool ) );
90 | next += sizeof( bool );
91 |
92 | _memcpy_s( &cfg_protocol, sizeof( unsigned char ), next, sizeof( unsigned char ) );
93 | next += sizeof( unsigned char );
94 |
95 | _memcpy_s( &cfg_certificate_type, sizeof( unsigned char ), next, sizeof( unsigned char ) );
96 | next += sizeof( unsigned char );
97 |
98 | _memcpy_s( &cfg_pkcs_password_is_null, sizeof( bool ), next, sizeof( bool ) );
99 | next += sizeof( bool );
100 |
101 | _memcpy_s( &cfg_decrypt_tunnel, sizeof( bool ), next, sizeof( bool ) );
102 | next += sizeof( bool );
103 |
104 | _memcpy_s( &cfg_timeout, sizeof( unsigned short ), next, sizeof( unsigned short ) );
105 | next += sizeof( unsigned short );
106 |
107 | _memcpy_s( &cfg_retry_client_timeout, sizeof( bool ), next, sizeof( bool ) );
108 | next += sizeof( bool );
109 |
110 | _memcpy_s( &cfg_thread_count, sizeof( unsigned long ), next, sizeof( unsigned long ) );
111 | next += sizeof( unsigned long );
112 |
113 | int string_length = 0;
114 | int cfg_val_length = 0;
115 |
116 | if ( ( DWORD )( next - cfg_buf ) < read )
117 | {
118 | // Length of the string - not including the NULL character.
119 | _memcpy_s( &g_auth_username_length, sizeof( unsigned long ), next, sizeof( unsigned short ) );
120 | next += sizeof( unsigned short );
121 |
122 | if ( g_auth_username_length > 0 )
123 | {
124 | if ( ( ( DWORD )( next - cfg_buf ) + g_auth_username_length < read ) )
125 | {
126 | // g_auth_username_length does not contain the NULL character of the string.
127 | cfg_auth_username = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * ( g_auth_username_length + 1 ) );
128 | _memcpy_s( cfg_auth_username, g_auth_username_length, next, g_auth_username_length );
129 | cfg_auth_username[ g_auth_username_length ] = 0; // Sanity;
130 |
131 | decode_cipher( cfg_auth_username, g_auth_username_length );
132 |
133 | next += g_auth_username_length;
134 | }
135 | else
136 | {
137 | read = 0;
138 | }
139 | }
140 | }
141 |
142 | if ( ( DWORD )( next - cfg_buf ) < read )
143 | {
144 | // Length of the string - not including the NULL character.
145 | _memcpy_s( &g_auth_password_length, sizeof( unsigned long ), next, sizeof( unsigned short ) );
146 | next += sizeof( unsigned short );
147 |
148 | if ( g_auth_password_length > 0 )
149 | {
150 | if ( ( ( DWORD )( next - cfg_buf ) + g_auth_password_length < read ) )
151 | {
152 | // g_auth_password_length does not contain the NULL character of the string.
153 | cfg_auth_password = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * ( g_auth_password_length + 1 ) );
154 | _memcpy_s( cfg_auth_password, g_auth_password_length, next, g_auth_password_length );
155 | cfg_auth_password[ g_auth_password_length ] = 0; // Sanity;
156 |
157 | decode_cipher( cfg_auth_password, g_auth_password_length );
158 |
159 | next += g_auth_password_length;
160 | }
161 | else
162 | {
163 | read = 0;
164 | }
165 | }
166 | }
167 |
168 | if ( ( DWORD )( next - cfg_buf ) < read )
169 | {
170 | // Length of the string - not including the NULL character.
171 | _memcpy_s( &g_auth_username_length_s, sizeof( unsigned long ), next, sizeof( unsigned short ) );
172 | next += sizeof( unsigned short );
173 |
174 | if ( g_auth_username_length_s > 0 )
175 | {
176 | if ( ( ( DWORD )( next - cfg_buf ) + g_auth_username_length_s < read ) )
177 | {
178 | // g_auth_username_length_s does not contain the NULL character of the string.
179 | cfg_auth_username_s = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * ( g_auth_username_length_s + 1 ) );
180 | _memcpy_s( cfg_auth_username_s, g_auth_username_length_s, next, g_auth_username_length_s );
181 | cfg_auth_username_s[ g_auth_username_length_s ] = 0; // Sanity;
182 |
183 | decode_cipher( cfg_auth_username_s, g_auth_username_length_s );
184 |
185 | next += g_auth_username_length_s;
186 | }
187 | else
188 | {
189 | read = 0;
190 | }
191 | }
192 | }
193 |
194 | if ( ( DWORD )( next - cfg_buf ) < read )
195 | {
196 | // Length of the string - not including the NULL character.
197 | _memcpy_s( &g_auth_password_length_s, sizeof( unsigned long ), next, sizeof( unsigned short ) );
198 | next += sizeof( unsigned short );
199 |
200 | if ( g_auth_password_length_s > 0 )
201 | {
202 | if ( ( ( DWORD )( next - cfg_buf ) + g_auth_password_length_s < read ) )
203 | {
204 | // g_auth_password_length_s does not contain the NULL character of the string.
205 | cfg_auth_password_s = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * ( g_auth_password_length_s + 1 ) );
206 | _memcpy_s( cfg_auth_password_s, g_auth_password_length_s, next, g_auth_password_length_s );
207 | cfg_auth_password_s[ g_auth_password_length_s ] = 0; // Sanity;
208 |
209 | decode_cipher( cfg_auth_password_s, g_auth_password_length_s );
210 |
211 | next += g_auth_password_length_s;
212 | }
213 | else
214 | {
215 | read = 0;
216 | }
217 | }
218 | }
219 |
220 | if ( ( DWORD )( next - cfg_buf ) < read )
221 | {
222 | // Length of the string - not including the NULL character.
223 | _memcpy_s( &string_length, sizeof( unsigned short ), next, sizeof( unsigned short ) );
224 | next += sizeof( unsigned short );
225 |
226 | if ( string_length > 0 )
227 | {
228 | if ( ( ( DWORD )( next - cfg_buf ) + string_length < read ) )
229 | {
230 | // string_length does not contain the NULL character of the string.
231 | char *certificate_password = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * ( string_length + 1 ) );
232 | _memcpy_s( certificate_password, string_length, next, string_length );
233 | certificate_password[ string_length ] = 0; // Sanity;
234 |
235 | decode_cipher( certificate_password, string_length );
236 |
237 | // Read password.
238 | cfg_val_length = MultiByteToWideChar( CP_UTF8, 0, certificate_password, string_length + 1, NULL, 0 ); // Include the NULL character.
239 | cfg_certificate_pkcs_password = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * cfg_val_length );
240 | MultiByteToWideChar( CP_UTF8, 0, certificate_password, string_length + 1, cfg_certificate_pkcs_password, cfg_val_length );
241 |
242 | GlobalFree( certificate_password );
243 |
244 | next += string_length;
245 | }
246 | else
247 | {
248 | read = 0;
249 | }
250 | }
251 | else if ( !cfg_pkcs_password_is_null )
252 | {
253 | // If the length is 0 and the password was not saved as a NULL password, then use the empty string as the password.
254 | cfg_certificate_pkcs_password = ( wchar_t * )GlobalAlloc( GPTR, sizeof( wchar_t ) );
255 | cfg_certificate_pkcs_password[ 0 ] = 0; // Sanity.
256 | }
257 | }
258 |
259 | if ( ( DWORD )( next - cfg_buf ) < read )
260 | {
261 | string_length = lstrlenA( next ) + 1;
262 |
263 | cfg_val_length = MultiByteToWideChar( CP_UTF8, 0, next, string_length, NULL, 0 ); // Include the NULL terminator.
264 | cfg_certificate_pkcs_file_name = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * cfg_val_length );
265 | MultiByteToWideChar( CP_UTF8, 0, next, string_length, cfg_certificate_pkcs_file_name, cfg_val_length );
266 |
267 | next += string_length;
268 | }
269 |
270 | if ( ( DWORD )( next - cfg_buf ) < read )
271 | {
272 | string_length = lstrlenA( next ) + 1;
273 |
274 | cfg_val_length = MultiByteToWideChar( CP_UTF8, 0, next, string_length, NULL, 0 ); // Include the NULL terminator.
275 | cfg_certificate_cer_file_name = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * cfg_val_length );
276 | MultiByteToWideChar( CP_UTF8, 0, next, string_length, cfg_certificate_cer_file_name, cfg_val_length );
277 |
278 | next += string_length;
279 | }
280 |
281 | if ( ( DWORD )( next - cfg_buf ) < read )
282 | {
283 | string_length = lstrlenA( next ) + 1;
284 |
285 | cfg_val_length = MultiByteToWideChar( CP_UTF8, 0, next, string_length, NULL, 0 ); // Include the NULL terminator.
286 | cfg_certificate_key_file_name = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * cfg_val_length );
287 | MultiByteToWideChar( CP_UTF8, 0, next, string_length, cfg_certificate_key_file_name, cfg_val_length );
288 |
289 | next += string_length;
290 | }
291 |
292 | if ( ( DWORD )( next - cfg_buf ) < read )
293 | {
294 | string_length = lstrlenA( next ) + 1;
295 |
296 | cfg_val_length = MultiByteToWideChar( CP_UTF8, 0, next, string_length, NULL, 0 ); // Include the NULL terminator.
297 | cfg_hostname_ip_address = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * cfg_val_length );
298 | MultiByteToWideChar( CP_UTF8, 0, next, string_length, cfg_hostname_ip_address, cfg_val_length );
299 |
300 | next += string_length;
301 | }
302 |
303 | if ( ( DWORD )( next - cfg_buf ) < read )
304 | {
305 | string_length = lstrlenA( next ) + 1;
306 |
307 | cfg_val_length = MultiByteToWideChar( CP_UTF8, 0, next, string_length, NULL, 0 ); // Include the NULL terminator.
308 | cfg_forward_hostname_ip_address = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * cfg_val_length );
309 | MultiByteToWideChar( CP_UTF8, 0, next, string_length, cfg_forward_hostname_ip_address, cfg_val_length );
310 |
311 | next += string_length;
312 | }
313 |
314 | if ( ( DWORD )( next - cfg_buf ) < read )
315 | {
316 | string_length = lstrlenA( next ) + 1;
317 |
318 | cfg_val_length = MultiByteToWideChar( CP_UTF8, 0, next, string_length, NULL, 0 ); // Include the NULL terminator.
319 | cfg_hostname_ip_address_s = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * cfg_val_length );
320 | MultiByteToWideChar( CP_UTF8, 0, next, string_length, cfg_hostname_ip_address_s, cfg_val_length );
321 |
322 | next += string_length;
323 | }
324 |
325 | if ( ( DWORD )( next - cfg_buf ) < read )
326 | {
327 | string_length = lstrlenA( next ) + 1;
328 |
329 | cfg_val_length = MultiByteToWideChar( CP_UTF8, 0, next, string_length, NULL, 0 ); // Include the NULL terminator.
330 | cfg_forward_hostname_ip_address_s = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * cfg_val_length );
331 | MultiByteToWideChar( CP_UTF8, 0, next, string_length, cfg_forward_hostname_ip_address_s, cfg_val_length );
332 |
333 | next += string_length;
334 | }
335 |
336 | // Set the default values for bad configuration values.
337 |
338 | if ( cfg_port == 0 ) { cfg_port = 1; }
339 | if ( cfg_port_s == 0 ) { cfg_port_s = 1; }
340 |
341 | if ( cfg_forward_port == 0 ) { cfg_forward_port = 1; }
342 | if ( cfg_forward_port_s == 0 ) { cfg_forward_port_s = 1; }
343 |
344 | if ( cfg_timeout > 300 || cfg_timeout < 1 ) { cfg_timeout = 30; }
345 |
346 | if ( cfg_thread_count > g_max_threads )
347 | {
348 | cfg_thread_count = max( ( g_max_threads / 2 ), 1 );
349 | }
350 | else if ( cfg_thread_count == 0 )
351 | {
352 | cfg_thread_count = 1;
353 | }
354 |
355 | if ( cfg_protocol > 4 ) { cfg_protocol = 4; } // TLS 1.2.
356 | }
357 | else
358 | {
359 | status = -2; // Bad file format.
360 | }
361 |
362 | GlobalFree( cfg_buf );
363 | }
364 | else
365 | {
366 | status = -3; // Incorrect file size.
367 | }
368 |
369 | CloseHandle( hFile_cfg );
370 | }
371 | else
372 | {
373 | status = -1; // Can't open file for reading.
374 | }
375 |
376 | if ( cfg_hostname_ip_address == NULL )
377 | {
378 | cfg_hostname_ip_address = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * 10 );
379 | _wmemcpy_s( cfg_hostname_ip_address, 10, L"localhost\0", 10 );
380 | cfg_hostname_ip_address[ 9 ] = 0; // Sanity.
381 | }
382 |
383 | if ( cfg_forward_hostname_ip_address == NULL )
384 | {
385 | cfg_forward_hostname_ip_address = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * 10 );
386 | _wmemcpy_s( cfg_forward_hostname_ip_address, 10, L"localhost\0", 10 );
387 | cfg_forward_hostname_ip_address[ 9 ] = 0; // Sanity.
388 | }
389 |
390 | if ( cfg_hostname_ip_address_s == NULL )
391 | {
392 | cfg_hostname_ip_address_s = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * 10 );
393 | _wmemcpy_s( cfg_hostname_ip_address_s, 10, L"localhost\0", 10 );
394 | cfg_hostname_ip_address_s[ 9 ] = 0; // Sanity.
395 | }
396 |
397 | if ( cfg_forward_hostname_ip_address_s == NULL )
398 | {
399 | cfg_forward_hostname_ip_address_s = ( wchar_t * )GlobalAlloc( GMEM_FIXED, sizeof( wchar_t ) * 10 );
400 | _wmemcpy_s( cfg_forward_hostname_ip_address_s, 10, L"localhost\0", 10 );
401 | cfg_forward_hostname_ip_address_s[ 9 ] = 0; // Sanity.
402 | }
403 |
404 | return status;
405 | }
406 |
407 | char save_config( wchar_t *filename )
408 | {
409 | char status = 0;
410 |
411 | HANDLE hFile_cfg = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
412 | if ( hFile_cfg != INVALID_HANDLE_VALUE )
413 | {
414 | int size = ( sizeof( unsigned short ) * 5 ) + ( sizeof( char ) * 9 ) + ( sizeof( bool ) * 10 ) + ( sizeof( unsigned long ) * 1 );
415 | int pos = 0;
416 |
417 | char *write_buf = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * size );
418 |
419 | _memcpy_s( write_buf + pos, size - pos, MAGIC_ID_SETTINGS, sizeof( char ) * 4 ); // Magic identifier for the main program's settings.
420 | pos += ( sizeof( char ) * 4 );
421 |
422 | _memcpy_s( write_buf + pos, size - pos, &cfg_proxy_type, sizeof( unsigned char ) );
423 | pos += sizeof( unsigned char );
424 |
425 | _memcpy_s( write_buf + pos, size - pos, &cfg_port, sizeof( unsigned short ) );
426 | pos += sizeof( unsigned short );
427 |
428 | _memcpy_s( write_buf + pos, size - pos, &cfg_require_authentication, sizeof( bool ) );
429 | pos += sizeof( bool );
430 |
431 | _memcpy_s( write_buf + pos, size - pos, &cfg_auth_type, sizeof( unsigned char ) );
432 | pos += sizeof( unsigned char );
433 |
434 | _memcpy_s( write_buf + pos, size - pos, &cfg_forward_authentication, sizeof( bool ) );
435 | pos += sizeof( bool );
436 |
437 | _memcpy_s( write_buf + pos, size - pos, &cfg_forward_connections, sizeof( bool ) );
438 | pos += sizeof( bool );
439 |
440 | _memcpy_s( write_buf + pos, size - pos, &cfg_forward_port, sizeof( unsigned short ) );
441 | pos += sizeof( unsigned short );
442 |
443 | _memcpy_s( write_buf + pos, size - pos, &cfg_port_s, sizeof( unsigned short ) );
444 | pos += sizeof( unsigned short );
445 |
446 | _memcpy_s( write_buf + pos, size - pos, &cfg_require_authentication_s, sizeof( bool ) );
447 | pos += sizeof( bool );
448 |
449 | _memcpy_s( write_buf + pos, size - pos, &cfg_auth_type_s, sizeof( unsigned char ) );
450 | pos += sizeof( unsigned char );
451 |
452 | _memcpy_s( write_buf + pos, size - pos, &cfg_forward_authentication_s, sizeof( bool ) );
453 | pos += sizeof( bool );
454 |
455 | _memcpy_s( write_buf + pos, size - pos, &cfg_forward_connections_s, sizeof( bool ) );
456 | pos += sizeof( bool );
457 |
458 | _memcpy_s( write_buf + pos, size - pos, &cfg_forward_port_s, sizeof( unsigned short ) );
459 | pos += sizeof( unsigned short );
460 |
461 | _memcpy_s( write_buf + pos, size - pos, &cfg_use_ssl, sizeof( bool ) );
462 | pos += sizeof( bool );
463 |
464 | _memcpy_s( write_buf + pos, size - pos, &cfg_protocol, sizeof( unsigned char ) );
465 | pos += sizeof( unsigned char );
466 |
467 | _memcpy_s( write_buf + pos, size - pos, &cfg_certificate_type, sizeof( unsigned char ) );
468 | pos += sizeof( unsigned char );
469 |
470 | _memcpy_s( write_buf + pos, size - pos, &cfg_pkcs_password_is_null, sizeof( bool ) );
471 | pos += sizeof( bool );
472 |
473 | _memcpy_s( write_buf + pos, size - pos, &cfg_decrypt_tunnel, sizeof( bool ) );
474 | pos += sizeof( bool );
475 |
476 | _memcpy_s( write_buf + pos, size - pos, &cfg_timeout, sizeof( unsigned short ) );
477 | pos += sizeof( unsigned short );
478 |
479 | _memcpy_s( write_buf + pos, size - pos, &cfg_retry_client_timeout, sizeof( bool ) );
480 | pos += sizeof( bool );
481 |
482 | _memcpy_s( write_buf + pos, size - pos, &cfg_thread_count, sizeof( unsigned long ) );
483 | //pos += sizeof( unsigned long );
484 |
485 | DWORD write = 0;
486 | WriteFile( hFile_cfg, write_buf, size, &write, NULL );
487 |
488 | GlobalFree( write_buf );
489 |
490 | int cfg_val_length = 0;
491 | char *utf8_cfg_val = NULL;
492 |
493 | if ( cfg_auth_username != NULL )
494 | {
495 | cfg_val_length = ( sizeof( char ) * ( g_auth_username_length + 1 ) ) + sizeof( unsigned short ); // Add 2 bytes for our encoded length.
496 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
497 |
498 | _memcpy_s( utf8_cfg_val, cfg_val_length, &g_auth_username_length, sizeof( unsigned short ) );
499 | _memcpy_s( utf8_cfg_val + sizeof( unsigned short ), cfg_val_length - sizeof( unsigned short ), cfg_auth_username, g_auth_username_length + 1 );
500 |
501 | encode_cipher( utf8_cfg_val + sizeof( unsigned short ), g_auth_username_length );
502 |
503 | WriteFile( hFile_cfg, utf8_cfg_val, g_auth_username_length + sizeof( unsigned short ), &write, NULL ); // Do not write the NULL terminator.
504 |
505 | GlobalFree( utf8_cfg_val );
506 | }
507 | else
508 | {
509 | WriteFile( hFile_cfg, "\0\0", 2, &write, NULL );
510 | }
511 |
512 | if ( cfg_auth_password != NULL )
513 | {
514 | cfg_val_length = ( sizeof( char ) * ( g_auth_password_length + 1 ) ) + sizeof( unsigned short ); // Add 2 bytes for our encoded length.
515 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
516 |
517 | _memcpy_s( utf8_cfg_val, cfg_val_length, &g_auth_password_length, sizeof( unsigned short ) );
518 | _memcpy_s( utf8_cfg_val + sizeof( unsigned short ), cfg_val_length - sizeof( unsigned short ), cfg_auth_password, g_auth_password_length + 1 );
519 |
520 | encode_cipher( utf8_cfg_val + sizeof( unsigned short ), g_auth_password_length );
521 |
522 | WriteFile( hFile_cfg, utf8_cfg_val, g_auth_password_length + sizeof( unsigned short ), &write, NULL ); // Do not write the NULL terminator.
523 |
524 | GlobalFree( utf8_cfg_val );
525 | }
526 | else
527 | {
528 | WriteFile( hFile_cfg, "\0\0", 2, &write, NULL );
529 | }
530 |
531 | if ( cfg_auth_username_s != NULL )
532 | {
533 | cfg_val_length = ( sizeof( char ) * ( g_auth_username_length_s + 1 ) ) + sizeof( unsigned short ); // Add 2 bytes for our encoded length.
534 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
535 |
536 | _memcpy_s( utf8_cfg_val, cfg_val_length, &g_auth_username_length_s, sizeof( unsigned short ) );
537 | _memcpy_s( utf8_cfg_val + sizeof( unsigned short ), cfg_val_length - sizeof( unsigned short ), cfg_auth_username_s, g_auth_username_length_s + 1 );
538 |
539 | encode_cipher( utf8_cfg_val + sizeof( unsigned short ), g_auth_username_length_s );
540 |
541 | WriteFile( hFile_cfg, utf8_cfg_val, g_auth_username_length_s + sizeof( unsigned short ), &write, NULL ); // Do not write the NULL terminator.
542 |
543 | GlobalFree( utf8_cfg_val );
544 | }
545 | else
546 | {
547 | WriteFile( hFile_cfg, "\0\0", 2, &write, NULL );
548 | }
549 |
550 | if ( cfg_auth_password_s != NULL )
551 | {
552 | cfg_val_length = ( sizeof( char ) * ( g_auth_password_length_s + 1 ) ) + sizeof( unsigned short ); // Add 2 bytes for our encoded length.
553 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
554 |
555 | _memcpy_s( utf8_cfg_val, cfg_val_length, &g_auth_password_length_s, sizeof( unsigned short ) );
556 | _memcpy_s( utf8_cfg_val + sizeof( unsigned short ), cfg_val_length - sizeof( unsigned short ), cfg_auth_password_s, g_auth_password_length_s + 1 );
557 |
558 | encode_cipher( utf8_cfg_val + sizeof( unsigned short ), g_auth_password_length_s );
559 |
560 | WriteFile( hFile_cfg, utf8_cfg_val, g_auth_password_length_s + sizeof( unsigned short ), &write, NULL ); // Do not write the NULL terminator.
561 |
562 | GlobalFree( utf8_cfg_val );
563 | }
564 | else
565 | {
566 | WriteFile( hFile_cfg, "\0\0", 2, &write, NULL );
567 | }
568 |
569 | if ( cfg_certificate_pkcs_password != NULL )
570 | {
571 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_certificate_pkcs_password, -1, NULL, 0, NULL, NULL ) + sizeof( unsigned short ); // Add 2 bytes for our encoded length.
572 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
573 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_certificate_pkcs_password, -1, utf8_cfg_val + sizeof( unsigned short ), cfg_val_length - sizeof( unsigned short ), NULL, NULL );
574 |
575 | int length = cfg_val_length - 1; // Exclude the NULL terminator.
576 | _memcpy_s( utf8_cfg_val, cfg_val_length, &length, sizeof( unsigned short ) );
577 |
578 | encode_cipher( utf8_cfg_val + sizeof( unsigned short ), length );
579 |
580 | WriteFile( hFile_cfg, utf8_cfg_val, length + sizeof( unsigned short ), &write, NULL ); // Do not write the NULL terminator.
581 |
582 | GlobalFree( utf8_cfg_val );
583 | }
584 | else
585 | {
586 | WriteFile( hFile_cfg, "\0\0", 2, &write, NULL );
587 | }
588 |
589 | if ( cfg_certificate_pkcs_file_name != NULL )
590 | {
591 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_certificate_pkcs_file_name, -1, NULL, 0, NULL, NULL );
592 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
593 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_certificate_pkcs_file_name, -1, utf8_cfg_val, cfg_val_length, NULL, NULL );
594 |
595 | WriteFile( hFile_cfg, utf8_cfg_val, cfg_val_length, &write, NULL );
596 |
597 | GlobalFree( utf8_cfg_val );
598 | }
599 | else
600 | {
601 | WriteFile( hFile_cfg, "\0", 1, &write, NULL );
602 | }
603 |
604 | if ( cfg_certificate_cer_file_name != NULL )
605 | {
606 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_certificate_cer_file_name, -1, NULL, 0, NULL, NULL );
607 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
608 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_certificate_cer_file_name, -1, utf8_cfg_val, cfg_val_length, NULL, NULL );
609 |
610 | WriteFile( hFile_cfg, utf8_cfg_val, cfg_val_length, &write, NULL );
611 |
612 | GlobalFree( utf8_cfg_val );
613 | }
614 | else
615 | {
616 | WriteFile( hFile_cfg, "\0", 1, &write, NULL );
617 | }
618 |
619 | if ( cfg_certificate_key_file_name != NULL )
620 | {
621 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_certificate_key_file_name, -1, NULL, 0, NULL, NULL );
622 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
623 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_certificate_key_file_name, -1, utf8_cfg_val, cfg_val_length, NULL, NULL );
624 |
625 | WriteFile( hFile_cfg, utf8_cfg_val, cfg_val_length, &write, NULL );
626 |
627 | GlobalFree( utf8_cfg_val );
628 | }
629 | else
630 | {
631 | WriteFile( hFile_cfg, "\0", 1, &write, NULL );
632 | }
633 |
634 | if ( cfg_hostname_ip_address != NULL )
635 | {
636 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_hostname_ip_address, -1, NULL, 0, NULL, NULL );
637 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
638 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_hostname_ip_address, -1, utf8_cfg_val, cfg_val_length, NULL, NULL );
639 |
640 | WriteFile( hFile_cfg, utf8_cfg_val, cfg_val_length, &write, NULL );
641 |
642 | GlobalFree( utf8_cfg_val );
643 | }
644 | else
645 | {
646 | WriteFile( hFile_cfg, "\0", 1, &write, NULL );
647 | }
648 |
649 | if ( cfg_forward_hostname_ip_address != NULL )
650 | {
651 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_forward_hostname_ip_address, -1, NULL, 0, NULL, NULL );
652 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
653 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_forward_hostname_ip_address, -1, utf8_cfg_val, cfg_val_length, NULL, NULL );
654 |
655 | WriteFile( hFile_cfg, utf8_cfg_val, cfg_val_length, &write, NULL );
656 |
657 | GlobalFree( utf8_cfg_val );
658 | }
659 | else
660 | {
661 | WriteFile( hFile_cfg, "\0", 1, &write, NULL );
662 | }
663 |
664 | if ( cfg_hostname_ip_address_s != NULL )
665 | {
666 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_hostname_ip_address_s, -1, NULL, 0, NULL, NULL );
667 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
668 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_hostname_ip_address_s, -1, utf8_cfg_val, cfg_val_length, NULL, NULL );
669 |
670 | WriteFile( hFile_cfg, utf8_cfg_val, cfg_val_length, &write, NULL );
671 |
672 | GlobalFree( utf8_cfg_val );
673 | }
674 | else
675 | {
676 | WriteFile( hFile_cfg, "\0", 1, &write, NULL );
677 | }
678 |
679 | if ( cfg_forward_hostname_ip_address_s != NULL )
680 | {
681 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_forward_hostname_ip_address_s, -1, NULL, 0, NULL, NULL );
682 | utf8_cfg_val = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * cfg_val_length ); // Size includes the null character.
683 | cfg_val_length = WideCharToMultiByte( CP_UTF8, 0, cfg_forward_hostname_ip_address_s, -1, utf8_cfg_val, cfg_val_length, NULL, NULL );
684 |
685 | WriteFile( hFile_cfg, utf8_cfg_val, cfg_val_length, &write, NULL );
686 |
687 | GlobalFree( utf8_cfg_val );
688 | }
689 | else
690 | {
691 | WriteFile( hFile_cfg, "\0", 1, &write, NULL );
692 | }
693 |
694 | CloseHandle( hFile_cfg );
695 | }
696 | else
697 | {
698 | status = -1; // Can't open file for writing.
699 | }
700 |
701 | return status;
702 | }
703 |
--------------------------------------------------------------------------------
/HTTP_Proxy/file_operations.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _FILE_OPERATIONS_H
20 | #define _FILE_OPERATIONS_H
21 |
22 | #define MAGIC_ID_SETTINGS "HPT\x00"
23 |
24 | char read_config( wchar_t *filename );
25 | char save_config( wchar_t *filename );
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/HTTP_Proxy/globals.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _GLOBALS_H
20 | #define _GLOBALS_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #include
27 | #include
28 |
29 | #include "lite_ntdll.h"
30 |
31 | #define FILETIME_TICKS_PER_SECOND 10000000LL
32 |
33 | #define _wcsicmp_s( a, b ) ( ( a == NULL && b == NULL ) ? 0 : ( a != NULL && b == NULL ) ? 1 : ( a == NULL && b != NULL ) ? -1 : lstrcmpiW( a, b ) )
34 | #define _stricmp_s( a, b ) ( ( a == NULL && b == NULL ) ? 0 : ( a != NULL && b == NULL ) ? 1 : ( a == NULL && b != NULL ) ? -1 : lstrcmpiA( a, b ) )
35 |
36 | #define SAFESTRA( s ) ( s != NULL ? s : "" )
37 | #define SAFESTR2A( s1, s2 ) ( s1 != NULL ? s1 : ( s2 != NULL ? s2 : "" ) )
38 |
39 | #define SAFESTRW( s ) ( s != NULL ? s : L"" )
40 | #define SAFESTR2W( s1, s2 ) ( s1 != NULL ? s1 : ( s2 != NULL ? s2 : L"" ) )
41 |
42 | #define is_digit( c ) ( c - '0' + 0U <= 9U )
43 | #define is_digit_w( c ) ( c - L'0' + 0U <= 9U )
44 |
45 | //
46 | extern unsigned char cfg_proxy_type;
47 | //
48 | extern wchar_t *cfg_hostname_ip_address;
49 | extern unsigned short cfg_port;
50 |
51 | extern wchar_t *g_hostname_ip_address;
52 |
53 | extern wchar_t *cfg_hostname_ip_address_s;
54 | extern unsigned short cfg_port_s;
55 |
56 | extern wchar_t *g_hostname_ip_address_s;
57 | //
58 |
59 | extern bool cfg_require_authentication;
60 | extern unsigned char cfg_auth_type;
61 |
62 | extern char *cfg_auth_username;
63 | extern char *cfg_auth_password;
64 | extern bool cfg_forward_authentication;
65 |
66 | extern char *g_authentication_key;
67 | extern unsigned long g_authentication_key_length;
68 | extern unsigned long g_auth_username_length;
69 | extern unsigned long g_auth_password_length;
70 |
71 | extern char *g_nonce;
72 | extern unsigned long g_nonce_length;
73 | extern char *g_opaque;
74 | extern unsigned long g_opaque_length;
75 |
76 | //
77 |
78 | extern bool cfg_require_authentication_s;
79 | extern unsigned char cfg_auth_type_s;
80 |
81 | extern char *cfg_auth_username_s;
82 | extern char *cfg_auth_password_s;
83 | extern bool cfg_forward_authentication_s;
84 |
85 | extern char *g_authentication_key_s;
86 | extern unsigned long g_authentication_key_length_s;
87 | extern unsigned long g_auth_username_length_s;
88 | extern unsigned long g_auth_password_length_s;
89 |
90 | extern char *g_nonce_s;
91 | extern unsigned long g_nonce_length_s;
92 | extern char *g_opaque_s;
93 | extern unsigned long g_opaque_length_s;
94 |
95 | //
96 | extern bool cfg_use_ssl;
97 | extern unsigned char cfg_protocol; // Default is 4 (TLS 1.2)
98 | extern unsigned char cfg_certificate_type;
99 | extern wchar_t *cfg_certificate_cer_file_name;
100 | extern wchar_t *cfg_certificate_key_file_name;
101 | extern wchar_t *cfg_certificate_pkcs_file_name;
102 | extern wchar_t *cfg_certificate_pkcs_password;
103 | extern bool cfg_pkcs_password_is_null;
104 | extern bool cfg_decrypt_tunnel;
105 | //
106 | extern bool cfg_forward_connections;
107 | extern wchar_t *cfg_forward_hostname_ip_address;
108 | extern unsigned short cfg_forward_port;
109 |
110 | extern wchar_t *g_forward_punycode_hostname_ip_address;
111 |
112 | extern bool cfg_forward_connections_s;
113 | extern wchar_t *cfg_forward_hostname_ip_address_s;
114 | extern unsigned short cfg_forward_port_s;
115 |
116 | extern wchar_t *g_forward_punycode_hostname_ip_address_s;
117 | //
118 | extern unsigned short cfg_timeout;
119 | extern bool cfg_retry_client_timeout;
120 | //
121 | extern unsigned long cfg_thread_count; // Default is 1.
122 | extern unsigned long g_max_threads; // Default is 2.
123 | //
124 |
125 | extern HCRYPTPROV g_hProvider;
126 |
127 | extern HANDLE g_hOutput; // Console output
128 |
129 | extern CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
130 |
131 | extern CRITICAL_SECTION console_cs;
132 |
133 | extern bool g_show_output;
134 |
135 | #endif
136 |
--------------------------------------------------------------------------------
/HTTP_Proxy/http.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _HTTP_H
20 | #define _HTTP_H
21 |
22 | #include "connection.h"
23 |
24 | void GetHeaderInfo( SOCKET_CONTEXT *context, char *buffer );
25 |
26 | bool HasTransferCompleted( SOCKET_CONTEXT *context );
27 |
28 | int ParseHTTPRequest( SOCKET_CONTEXT *context, char *buffer, unsigned int buffer_size );
29 |
30 | char HandleRequest( SOCKET_CONTEXT *context );
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_advapi32.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "lite_dlls.h"
20 | #include "lite_advapi32.h"
21 |
22 | #ifndef ADVAPI32_USE_STATIC_LIB
23 |
24 | pCryptAcquireContextW _CryptAcquireContextW;
25 | pCryptGenRandom _CryptGenRandom;
26 | pCryptReleaseContext _CryptReleaseContext;
27 |
28 | pCryptCreateHash _CryptCreateHash;
29 | pCryptDestroyHash _CryptDestroyHash;
30 |
31 | pCryptGetHashParam _CryptGetHashParam;
32 |
33 | pCryptHashData _CryptHashData;
34 |
35 | //pGetUserNameW _GetUserNameW;
36 |
37 | pCryptDestroyKey _CryptDestroyKey;
38 | pCryptImportKey _CryptImportKey;
39 |
40 | HMODULE hModule_advapi32 = NULL;
41 |
42 | unsigned char advapi32_state = 0; // 0 = Not running, 1 = running.
43 |
44 | bool InitializeAdvApi32()
45 | {
46 | if ( advapi32_state != ADVAPI32_STATE_SHUTDOWN )
47 | {
48 | return true;
49 | }
50 |
51 | hModule_advapi32 = LoadLibraryDEMW( L"advapi32.dll" );
52 |
53 | if ( hModule_advapi32 == NULL )
54 | {
55 | return false;
56 | }
57 |
58 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptAcquireContextW, "CryptAcquireContextW" ) )
59 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptGenRandom, "CryptGenRandom" ) )
60 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptReleaseContext, "CryptReleaseContext" ) )
61 |
62 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptCreateHash, "CryptCreateHash" ) )
63 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptDestroyHash, "CryptDestroyHash" ) )
64 |
65 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptGetHashParam, "CryptGetHashParam" ) )
66 |
67 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptHashData, "CryptHashData" ) )
68 |
69 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_GetUserNameW, "GetUserNameW" ) )
70 |
71 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptDestroyKey, "CryptDestroyKey" ) )
72 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_advapi32, ( void ** )&_CryptImportKey, "CryptImportKey" ) )
73 |
74 | advapi32_state = ADVAPI32_STATE_RUNNING;
75 |
76 | return true;
77 | }
78 |
79 | bool UnInitializeAdvApi32()
80 | {
81 | if ( advapi32_state != ADVAPI32_STATE_SHUTDOWN )
82 | {
83 | advapi32_state = ADVAPI32_STATE_SHUTDOWN;
84 |
85 | return ( FreeLibrary( hModule_advapi32 ) == FALSE ? false : true );
86 | }
87 |
88 | return true;
89 | }
90 |
91 | #endif
92 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_advapi32.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _LITE_ADVAPI32_H
20 | #define _LITE_ADVAPI32_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #include
27 |
28 | //#define ADVAPI32_USE_STATIC_LIB
29 |
30 | #ifdef ADVAPI32_USE_STATIC_LIB
31 |
32 | //__pragma( comment( lib, "advapi32.lib" ) )
33 |
34 | #define _CryptAcquireContextW CryptAcquireContextW
35 | #define _CryptGenRandom CryptGenRandom
36 | #define _CryptReleaseContext CryptReleaseContext
37 |
38 | #define _CryptCreateHash CryptCreateHash
39 | #define _CryptDestroyHash CryptDestroyHash
40 |
41 | #define _CryptGetHashParam CryptGetHashParam
42 |
43 | #define _CryptHashData CryptHashData
44 |
45 | //#define _GetUserNameW GetUserNameW
46 |
47 | #define _CryptDestroyKey CryptDestroyKey
48 | #define _CryptImportKey CryptImportKey
49 |
50 | #else
51 |
52 | #define ADVAPI32_STATE_SHUTDOWN 0
53 | #define ADVAPI32_STATE_RUNNING 1
54 |
55 | typedef BOOL ( WINAPI *pCryptAcquireContextW )( HCRYPTPROV *phProv, LPCTSTR pszContainer, LPCTSTR pszProvider, DWORD dwProvType, DWORD dwFlags );
56 | typedef BOOL ( WINAPI *pCryptGenRandom )( HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer );
57 | typedef BOOL ( WINAPI *pCryptReleaseContext )( HCRYPTPROV hProv, DWORD dwFlags );
58 |
59 | typedef BOOL ( WINAPI *pCryptCreateHash )( HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash );
60 | typedef BOOL ( WINAPI *pCryptDestroyHash )( HCRYPTHASH hHash );
61 |
62 | typedef BOOL ( WINAPI *pCryptGetHashParam )( HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags );
63 |
64 | typedef BOOL ( WINAPI *pCryptHashData )( HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWORD dwFlags );
65 |
66 | //typedef BOOL ( WINAPI *pGetUserNameW )( LPTSTR lpBuffer, LPDWORD lpnSize );
67 |
68 | typedef BOOL ( WINAPI *pCryptDestroyKey )( HCRYPTKEY hKey );
69 | typedef BOOL ( WINAPI *pCryptImportKey )( HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey );
70 |
71 | extern pCryptAcquireContextW _CryptAcquireContextW;
72 | extern pCryptGenRandom _CryptGenRandom;
73 | extern pCryptReleaseContext _CryptReleaseContext;
74 |
75 | extern pCryptCreateHash _CryptCreateHash;
76 | extern pCryptDestroyHash _CryptDestroyHash;
77 |
78 | extern pCryptGetHashParam _CryptGetHashParam;
79 |
80 | extern pCryptHashData _CryptHashData;
81 |
82 | //extern pGetUserNameW _GetUserNameW;
83 |
84 | extern pCryptDestroyKey _CryptDestroyKey;
85 | extern pCryptImportKey _CryptImportKey;
86 |
87 | extern unsigned char advapi32_state;
88 |
89 | bool InitializeAdvApi32();
90 | bool UnInitializeAdvApi32();
91 |
92 | #endif
93 |
94 | #endif
95 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_crypt32.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "lite_dlls.h"
20 | #include "lite_crypt32.h"
21 |
22 | #ifndef CRYPT32_USE_STATIC_LIB
23 |
24 | pCertFindCertificateInStore _CertFindCertificateInStore;
25 | pCertCloseStore _CertCloseStore;
26 | pCertFreeCertificateContext _CertFreeCertificateContext;
27 |
28 | pPFXImportCertStore _PFXImportCertStore;
29 |
30 | pCryptBinaryToStringA _CryptBinaryToStringA;
31 |
32 |
33 | pCryptMsgClose _CryptMsgClose;
34 | pCertSetCertificateContextProperty _CertSetCertificateContextProperty;
35 |
36 | pCryptDecodeObjectEx _CryptDecodeObjectEx;
37 | pCryptStringToBinaryA _CryptStringToBinaryA;
38 | pCryptQueryObject _CryptQueryObject;
39 |
40 | HMODULE hModule_crypt32 = NULL;
41 |
42 | unsigned char crypt32_state = 0; // 0 = Not running, 1 = running.
43 |
44 | bool InitializeCrypt32()
45 | {
46 | if ( crypt32_state != CRYPT32_STATE_SHUTDOWN )
47 | {
48 | return true;
49 | }
50 |
51 | hModule_crypt32 = LoadLibraryDEMW( L"crypt32.dll" );
52 |
53 | if ( hModule_crypt32 == NULL )
54 | {
55 | return false;
56 | }
57 |
58 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CertFindCertificateInStore, "CertFindCertificateInStore" ) )
59 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CertCloseStore, "CertCloseStore" ) )
60 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CertFreeCertificateContext, "CertFreeCertificateContext" ) )
61 |
62 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_PFXImportCertStore, "PFXImportCertStore" ) )
63 |
64 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CryptBinaryToStringA, "CryptBinaryToStringA" ) )
65 |
66 |
67 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CryptMsgClose, "CryptMsgClose" ) )
68 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CertSetCertificateContextProperty, "CertSetCertificateContextProperty" ) )
69 |
70 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CryptDecodeObjectEx, "CryptDecodeObjectEx" ) )
71 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CryptStringToBinaryA, "CryptStringToBinaryA" ) )
72 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_crypt32, ( void ** )&_CryptQueryObject, "CryptQueryObject" ) )
73 |
74 | crypt32_state = CRYPT32_STATE_RUNNING;
75 |
76 | return true;
77 | }
78 |
79 | bool UnInitializeCrypt32()
80 | {
81 | if ( crypt32_state != CRYPT32_STATE_SHUTDOWN )
82 | {
83 | crypt32_state = CRYPT32_STATE_SHUTDOWN;
84 |
85 | return ( FreeLibrary( hModule_crypt32 ) == FALSE ? false : true );
86 | }
87 |
88 | return true;
89 | }
90 |
91 | #endif
92 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_crypt32.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _LITE_CRYPT32_H
20 | #define _LITE_CRYPT32_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #include
27 |
28 | //#define CRYPT32_USE_STATIC_LIB
29 |
30 | #ifdef CRYPT32_USE_STATIC_LIB
31 |
32 | //__pragma( comment( lib, "crypt32.lib" ) )
33 |
34 | #define _CertFindCertificateInStore CertFindCertificateInStore
35 | #define _CertCloseStore CertCloseStore
36 | #define _CertFreeCertificateContext CertFreeCertificateContext
37 |
38 | #define _PFXImportCertStore PFXImportCertStore
39 |
40 | #define _CryptBinaryToStringA CryptBinaryToStringA
41 |
42 | #define _CryptMsgClose CryptMsgClose
43 | #define _CertSetCertificateContextProperty CertSetCertificateContextProperty
44 |
45 | #define _CryptDecodeObjectEx CryptDecodeObjectEx
46 | #define _CryptStringToBinaryA CryptStringToBinaryA
47 | #define _CryptQueryObject CryptQueryObject
48 |
49 | #else
50 |
51 | #define CRYPT32_STATE_SHUTDOWN 0
52 | #define CRYPT32_STATE_RUNNING 1
53 |
54 | typedef PCCERT_CONTEXT ( WINAPI *pCertFindCertificateInStore )( HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, const void *pvFindPara, PCCERT_CONTEXT pPrevCertContext );
55 | typedef BOOL ( WINAPI *pCertCloseStore )( HCERTSTORE hCertStore, DWORD dwFlags );
56 | typedef BOOL ( WINAPI *pCertFreeCertificateContext )( PCCERT_CONTEXT pCertContext );
57 |
58 | typedef HCERTSTORE ( WINAPI *pPFXImportCertStore )( CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, DWORD dwFlags );
59 |
60 | typedef BOOL ( WINAPI *pCryptBinaryToStringA )( const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString );
61 |
62 | typedef BOOL ( WINAPI *pCryptMsgClose )( HCRYPTMSG hCryptMsg );
63 | typedef BOOL ( WINAPI *pCertSetCertificateContextProperty )( PCCERT_CONTEXT pCertContext, DWORD dwPropId, DWORD dwFlags, const void *pvData );
64 |
65 | typedef BOOL ( WINAPI *pCryptDecodeObjectEx )( DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo );
66 | typedef BOOL ( WINAPI *pCryptStringToBinaryA )( LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags );
67 | typedef BOOL ( WINAPI *pCryptQueryObject )( DWORD dwObjectType, const void *pvObject, DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags, DWORD dwFlags, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg, const void **ppvContext );
68 |
69 | extern pCertFindCertificateInStore _CertFindCertificateInStore;
70 | extern pCertCloseStore _CertCloseStore;
71 | extern pCertFreeCertificateContext _CertFreeCertificateContext;
72 |
73 | extern pPFXImportCertStore _PFXImportCertStore;
74 |
75 | extern pCryptBinaryToStringA _CryptBinaryToStringA;
76 |
77 | extern pCryptMsgClose _CryptMsgClose;
78 | extern pCertSetCertificateContextProperty _CertSetCertificateContextProperty;
79 |
80 | extern pCryptDecodeObjectEx _CryptDecodeObjectEx;
81 | extern pCryptStringToBinaryA _CryptStringToBinaryA;
82 | extern pCryptQueryObject _CryptQueryObject;
83 |
84 | extern unsigned char crypt32_state;
85 |
86 | bool InitializeCrypt32();
87 | bool UnInitializeCrypt32();
88 |
89 | #endif
90 |
91 | #endif
92 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_dlls.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "lite_dlls.h"
20 |
21 | // LoadLibrary with disabled error mode
22 | HMODULE LoadLibraryDEMW( LPCWSTR lpLibFileName )
23 | {
24 | HMODULE hm = NULL;
25 | SetErrorMode( SEM_FAILCRITICALERRORS ); // Disable error MessageBox.
26 | hm = LoadLibraryW( lpLibFileName );
27 | SetErrorMode( 0 ); // Reset to default.
28 |
29 | return hm;
30 | }
31 |
32 | void *SetFunctionPointer( HMODULE &library, void **function_pointer, char *function_name )
33 | {
34 | *function_pointer = GetProcAddress( library, function_name );
35 | if ( *function_pointer == NULL )
36 | {
37 | FreeLibrary( library );
38 | library = NULL;
39 | }
40 |
41 | return *function_pointer;
42 | }
43 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_dlls.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _LITE_DLLS_H
20 | #define _LITE_DLLS_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #define VALIDATE_FUNCTION_POINTER( ret ){ if ( ret == NULL ){ return false; } }
27 |
28 | HMODULE LoadLibraryDEMW( LPCWSTR lpLibFileName );
29 | void *SetFunctionPointer( HMODULE &library, void **function_pointer, char *function_name );
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_normaliz.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "lite_dlls.h"
20 | #include "lite_normaliz.h"
21 |
22 | #ifndef NORMALIZ_USE_STATIC_LIB
23 |
24 | pIdnToAscii _IdnToAscii;
25 | //pIdnToUnicode _IdnToUnicode;
26 |
27 | HMODULE hModule_normaliz = NULL;
28 |
29 | unsigned char normaliz_state = 0; // 0 = Not running, 1 = running.
30 |
31 | bool InitializeNormaliz()
32 | {
33 | if ( normaliz_state != NORMALIZ_STATE_SHUTDOWN )
34 | {
35 | return true;
36 | }
37 |
38 | hModule_normaliz = LoadLibraryDEMW( L"normaliz.dll" );
39 |
40 | if ( hModule_normaliz == NULL )
41 | {
42 | return false;
43 | }
44 |
45 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_normaliz, ( void ** )&_IdnToAscii, "IdnToAscii" ) )
46 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_normaliz, ( void ** )&_IdnToUnicode, "IdnToUnicode" ) )
47 |
48 | normaliz_state = NORMALIZ_STATE_RUNNING;
49 |
50 | return true;
51 | }
52 |
53 | bool UnInitializeNormaliz()
54 | {
55 | if ( normaliz_state != NORMALIZ_STATE_SHUTDOWN )
56 | {
57 | normaliz_state = NORMALIZ_STATE_SHUTDOWN;
58 |
59 | return ( FreeLibrary( hModule_normaliz ) == FALSE ? false : true );
60 | }
61 |
62 | return true;
63 | }
64 |
65 | #endif
66 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_normaliz.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _LITE_NORMALIZ_H
20 | #define _LITE_NORMALIZ_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #include
27 |
28 | //#define NORMALIZ_USE_STATIC_LIB
29 |
30 | #ifdef NORMALIZ_USE_STATIC_LIB
31 |
32 | //__pragma( comment( lib, "normaliz.lib" ) )
33 |
34 | #define _IdnToAscii IdnToAscii
35 | //#define _IdnToUnicode IdnToUnicode
36 |
37 | #else
38 |
39 | #define NORMALIZ_STATE_SHUTDOWN 0
40 | #define NORMALIZ_STATE_RUNNING 1
41 |
42 | typedef int ( WINAPI *pIdnToAscii )( DWORD dwFlags, LPCWSTR lpUnicodeCharStr, int cchUnicodeChar, LPWSTR lpASCIICharStr, int cchASCIIChar );
43 | //typedef int ( WINAPI *pIdnToUnicode )( DWORD dwFlags, LPCWSTR lpASCIICharStr, int cchASCIIChar, LPWSTR lpUnicodeCharStr, int cchUnicodeChar );
44 |
45 | extern pIdnToAscii _IdnToAscii;
46 | //extern pIdnToUnicode _IdnToUnicode;
47 |
48 | extern unsigned char normaliz_state;
49 |
50 | bool InitializeNormaliz();
51 | bool UnInitializeNormaliz();
52 |
53 | #endif
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_ntdll.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "lite_dlls.h"
20 | #include "lite_ntdll.h"
21 |
22 | #ifndef NTDLL_USE_STATIC_LIB
23 |
24 | #ifdef __cplusplus
25 | extern "C"
26 | {
27 | #endif
28 | int _fltused = 1; // Dummy value so that the linker shuts up.
29 | #ifdef __cplusplus
30 | }
31 | #endif
32 |
33 | //pRtlLargeIntegerDivide _RtlLargeIntegerDivide;
34 |
35 | //p_allmul __allmul;
36 | //p_aulldiv __aulldiv;
37 | //p_alldiv __alldiv;
38 | //p_allshr __allshr;
39 | //p_ftol2 __ftol2;
40 |
41 | pabs _abs;
42 |
43 | pmemcpy _memcpy;
44 | pmemset _memset;
45 | pmemcmp _memcmp;
46 | pmemmove _memmove;
47 |
48 | //pwcsncpy _wcsncpy;
49 |
50 | pstrcmp _strcmp;
51 | //pstrncmp _strncmp;
52 | //p_stricmp __stricmp;
53 | //p_strnicmp __strnicmp;
54 |
55 | pwcscmp _wcscmp;
56 | //pwcsncmp _wcsncmp;
57 | //p_wcsicmp __wcsicmp;
58 | //p_wcsnicmp __wcsnicmp;
59 |
60 | //pstrchr _strchr;
61 | //pstrstr _strstr;
62 |
63 | //p_atoi64 __atoi64;
64 | pstrtoul _strtoul;
65 |
66 | pwcstoul _wcstoul;
67 |
68 | p_snprintf __snprintf;
69 | p_snwprintf __snwprintf;
70 |
71 | p_vsnprintf __vsnprintf;
72 | p_vsnwprintf __vsnwprintf;
73 |
74 | HMODULE hModule_ntdll = NULL;
75 |
76 | unsigned char ntdll_state = NTDLL_STATE_SHUTDOWN; // 0 = Not running, 1 = running.
77 |
78 | bool InitializeNTDLL()
79 | {
80 | if ( ntdll_state != NTDLL_STATE_SHUTDOWN )
81 | {
82 | return true;
83 | }
84 |
85 | hModule_ntdll = LoadLibraryDEMW( L"ntdll.dll" );
86 |
87 | if ( hModule_ntdll == NULL )
88 | {
89 | return false;
90 | }
91 |
92 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_RtlLargeIntegerDivide, "RtlLargeIntegerDivide" ) )
93 |
94 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__allmul, "_allmul" ) )
95 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__aulldiv, "_aulldiv" ) )
96 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__alldiv, "_alldiv" ) )
97 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__allshr, "_allshr" ) )
98 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__ftol2, "_ftol" ) )
99 |
100 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_abs, "abs" ) )
101 |
102 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_memcpy, "memcpy" ) )
103 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_memset, "memset" ) )
104 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_memcmp, "memcmp" ) )
105 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_memmove, "memmove" ) )
106 |
107 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_wcsncpy, "wcsncpy" ) )
108 |
109 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_strcmp, "strcmp" ) )
110 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_strncmp, "strncmp" ) )
111 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__stricmp, "_stricmp" ) )
112 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__strnicmp, "_strnicmp" ) )
113 |
114 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_wcscmp, "wcscmp" ) )
115 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_wcsncmp, "wcsncmp" ) )
116 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__wcsicmp, "_wcsicmp" ) )
117 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__wcsnicmp, "_wcsnicmp" ) )
118 |
119 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_strchr, "strchr" ) )
120 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_strstr, "strstr" ) )
121 |
122 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__atoi64, "_atoi64" ) )
123 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_strtoul, "strtoul" ) )
124 |
125 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_wcstoul, "wcstoul" ) )
126 |
127 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__snprintf, "_snprintf" ) )
128 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__snwprintf, "_snwprintf" ) )
129 |
130 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__vsnprintf, "_vsnprintf" ) )
131 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&__vsnwprintf, "_vsnwprintf" ) )
132 |
133 | ntdll_state = NTDLL_STATE_RUNNING;
134 |
135 | return true;
136 | }
137 |
138 | bool UnInitializeNTDLL()
139 | {
140 | if ( ntdll_state != NTDLL_STATE_SHUTDOWN )
141 | {
142 | ntdll_state = NTDLL_STATE_SHUTDOWN;
143 |
144 | return ( FreeLibrary( hModule_ntdll ) == FALSE ? false : true );
145 | }
146 |
147 | return true;
148 | }
149 |
150 | void * WINAPIV _memcpy_s( void *dest, size_t size, const void *src, size_t count )
151 | {
152 | if ( src == NULL || size < count )
153 | {
154 | _memzero( dest, size );
155 | return dest;
156 | }
157 |
158 | return _memcpy( dest, src, count );
159 | }
160 |
161 | void * WINAPIV _wmemcpy_s( void *dest, size_t size, const void *src, size_t count )
162 | {
163 | size_t wsize = sizeof( wchar_t ) * size;
164 | size_t wcount = sizeof( wchar_t ) * count;
165 |
166 | if ( src == NULL || wsize < wcount )
167 | {
168 | _memzero( dest, wsize );
169 | return dest;
170 | }
171 |
172 | return _memcpy( dest, src, wcount );
173 | }
174 |
175 | #endif
176 |
177 | //wchar_t * WINAPIV _wcsncpy_s( wchar_t *strDest, size_t size, const wchar_t *strSource, size_t count )
178 | wchar_t * WINAPI _wcsncpy_s( wchar_t *strDest, size_t size, const wchar_t *strSource, size_t count )
179 | {
180 | if ( size < count )
181 | {
182 | return NULL;
183 | }
184 |
185 | //return _wcsncpy( strDest, strSource, count );
186 | return lstrcpynW( strDest, strSource, count );
187 | }
188 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_ntdll.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _LITE_NTDLL_H
20 | #define _LITE_NTDLL_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | //#define NTDLL_USE_STATIC_LIB
27 |
28 | #ifdef NTDLL_USE_STATIC_LIB
29 |
30 | //__pragma( comment( lib, "msvcrt.lib" ) )
31 |
32 | #include
33 |
34 | //#define _RtlLargeIntegerDivide RtlLargeIntegerDivide
35 |
36 | //#define __allmul _allmul
37 | //#define __aulldiv _aulldiv
38 | //#define __alldiv _alldiv
39 | //#define __allshr _allshr
40 | //#define __ftol2 _ftol2
41 |
42 | #define _abs abs
43 |
44 | #define _memcpy memcpy
45 | #define _memset memset
46 | #define _memcmp memcmp
47 | #define _memmove memmove
48 |
49 | //#define _wcsncpy wcsncpy
50 |
51 | #define _strcmp strcmp
52 | //#define _strncmp strncmp
53 | //#define __stricmp _stricmp
54 | //#define __strnicmp _strnicmp
55 |
56 | #define _wcscmp wcscmp
57 | //#define _wcsncmp wcsncmp
58 | //#define __wcsicmp _wcsicmp
59 | //#define __wcsnicmp _wcsnicmp
60 |
61 | //#define _strchr strchr
62 | //#define _strstr strstr
63 |
64 | //#define __atoi64 _atoi64
65 | #define _strtoul strtoul
66 |
67 | #define _wcstoul wcstoul
68 |
69 | //#define __snprintf _snprintf
70 | #define __snprintf sprintf_s
71 | //#define __snwprintf _snwprintf
72 | #define __snwprintf swprintf_s
73 |
74 | //#define __vsnprintf _vsprintf_s
75 | #define __vsnprintf vsprintf_s
76 | //#define __vsnwprintf _vswprintf_s
77 | #define __vsnwprintf vswprintf_s
78 |
79 | #define _memcpy_s memcpy_s
80 | #define _wmemcpy_s( dest, size, src, count ) memcpy_s( dest, sizeof( wchar_t ) * ( size ), src, sizeof( wchar_t ) * ( count ) )
81 |
82 | #define THREAD_RETURN unsigned int WINAPI
83 |
84 | #define _CreateThread _beginthreadex
85 | #define _ExitThread _endthreadex
86 |
87 | #else
88 |
89 | #define NTDLL_STATE_SHUTDOWN 0
90 | #define NTDLL_STATE_RUNNING 1
91 |
92 | //typedef LARGE_INTEGER ( WINAPIV *pRtlLargeIntegerDivide )( LARGE_INTEGER Dividend, LARGE_INTEGER Divisor, PLARGE_INTEGER Remainder );
93 |
94 | //typedef __int64 ( WINAPIV *p_allmul )( __int64 a, __int64 b );
95 | //typedef unsigned __int64 ( WINAPIV *p_aulldiv )( unsigned __int64 a, unsigned __int64 b );
96 | //typedef __int64 ( WINAPIV *p_alldiv )( __int64 a, __int64 b );
97 | //typedef __int64 ( WINAPIV *p_allshr )( __int64 v, unsigned char s );
98 | //typedef long ( WINAPIV *p_ftol2 )( float v );
99 |
100 | typedef int ( WINAPIV *pabs )( int n );
101 |
102 | typedef void * ( WINAPIV *pmemcpy )( void *dest, const void *src, size_t count );
103 | typedef void * ( WINAPIV *pmemset )( void *dest, int c, size_t count );
104 | typedef int ( WINAPIV *pmemcmp )( const void *buf1, const void *buf2, size_t count );
105 | typedef void * ( WINAPIV *pmemmove )( void *dest, const void *src, size_t count );
106 |
107 | //typedef wchar_t * ( WINAPIV *pwcsncpy )( wchar_t *strDest, const wchar_t *strSource, size_t count );
108 |
109 | typedef int ( WINAPIV *pstrcmp )( const char *string1, const char *string2 );
110 | //typedef int ( WINAPIV *pstrncmp )( const char *string1, const char *string2, size_t count );
111 | //typedef int ( WINAPIV *p_stricmp )( const char *string1, const char *string2 );
112 | //typedef int ( WINAPIV *p_strnicmp )( const char *string1, const char *string2, size_t count );
113 |
114 | typedef int ( WINAPIV *pwcscmp )( const wchar_t *string1, const wchar_t *string2 );
115 | //typedef int ( WINAPIV *pwcsncmp )( const wchar_t *string1, const wchar_t *string2, size_t count );
116 | //typedef int ( WINAPIV *p_wcsicmp )( const wchar_t *string1, const wchar_t *string2 );
117 | //typedef int ( WINAPIV *p_wcsnicmp )( const wchar_t *string1, const wchar_t *string2, size_t count );
118 |
119 | //typedef char * ( WINAPIV *pstrchr )( const char *str, int c );
120 | //typedef char * ( WINAPIV *pstrstr )( const char *str, const char *strSearch );
121 |
122 | //typedef __int64 ( WINAPIV *p_atoi64 )( const char *str );
123 | typedef unsigned long ( WINAPIV *pstrtoul )( const char *nptr, char **endptr, int base );
124 |
125 | typedef unsigned long ( WINAPIV *pwcstoul )( const wchar_t *nptr, wchar_t **endptr, int base );
126 |
127 | typedef int ( WINAPIV *p_snprintf )( char *buffer, size_t count, const char *format, ... );
128 | typedef int ( WINAPIV *p_snwprintf )( wchar_t *buffer, size_t count, const wchar_t *format, ... );
129 |
130 | typedef int ( WINAPIV *p_vsnprintf )( char *buffer, size_t count, const char *format, va_list argptr );
131 | typedef int ( WINAPIV *p_vsnwprintf )( wchar_t *buffer, size_t count, const wchar_t *format, va_list argptr );
132 |
133 | //extern pRtlLargeIntegerDivide _RtlLargeIntegerDivide;
134 |
135 | //extern p_allmul __allmul;
136 | //extern p_aulldiv __aulldiv;
137 | //extern p_alldiv __alldiv;
138 | //extern p_allshr __allshr;
139 | //extern p_ftol2 __ftol2;
140 |
141 | extern pabs _abs;
142 |
143 | extern pmemcpy _memcpy;
144 | extern pmemset _memset;
145 | extern pmemcmp _memcmp;
146 | extern pmemmove _memmove;
147 |
148 | //extern pwcsncpy _wcsncpy;
149 |
150 | extern pstrcmp _strcmp;
151 | //extern pstrncmp _strncmp;
152 | //extern p_stricmp __stricmp;
153 | //extern p_strnicmp __strnicmp;
154 |
155 | extern pwcscmp _wcscmp;
156 | //extern pwcsncmp _wcsncmp;
157 | //extern p_wcsicmp __wcsicmp;
158 | //extern p_wcsnicmp __wcsnicmp;
159 |
160 | //extern pstrchr _strchr;
161 | //extern pstrstr _strstr;
162 |
163 | //extern p_atoi64 __atoi64;
164 | extern pstrtoul _strtoul;
165 |
166 | extern pwcstoul _wcstoul;
167 |
168 | extern p_snprintf __snprintf;
169 | extern p_snwprintf __snwprintf;
170 |
171 | extern p_vsnprintf __vsnprintf;
172 | extern p_vsnwprintf __vsnwprintf;
173 |
174 | extern unsigned char ntdll_state;
175 |
176 | bool InitializeNTDLL();
177 | bool UnInitializeNTDLL();
178 |
179 | void * WINAPIV _memcpy_s( void *dest, size_t size, const void *src, size_t count );
180 | void * WINAPIV _wmemcpy_s( void *dest, size_t size, const void *src, size_t count );
181 |
182 | #define THREAD_RETURN DWORD WINAPI
183 |
184 | #define _CreateThread CreateThread
185 | #define _ExitThread ExitThread
186 |
187 | #endif
188 |
189 | //wchar_t * WINAPIV _wcsncpy_s( wchar_t *strDest, size_t size, const wchar_t *strSource, size_t count );
190 | wchar_t * WINAPI _wcsncpy_s( wchar_t *strDest, size_t size, const wchar_t *strSource, size_t count );
191 |
192 | #define _memzero( dest, count ) _memset( dest, 0, count )
193 |
194 | #endif
195 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_rpcrt4.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "lite_dlls.h"
20 | #include "lite_rpcrt4.h"
21 |
22 | #ifndef RPCRT4_USE_STATIC_LIB
23 |
24 | pRpcStringFreeW _RpcStringFreeW;
25 | pUuidToStringW _UuidToStringW;
26 | pUuidCreate _UuidCreate;
27 |
28 | HMODULE hModule_rpcrt4 = NULL;
29 |
30 | unsigned char rpcrt4_state = 0; // 0 = Not running, 1 = running.
31 |
32 | bool InitializeRpcRt4()
33 | {
34 | if ( rpcrt4_state != RPCRT4_STATE_SHUTDOWN )
35 | {
36 | return true;
37 | }
38 |
39 | hModule_rpcrt4 = LoadLibraryDEMW( L"rpcrt4.dll" );
40 |
41 | if ( hModule_rpcrt4 == NULL )
42 | {
43 | return false;
44 | }
45 |
46 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_rpcrt4, ( void ** )&_RpcStringFreeW, "RpcStringFreeW" ) )
47 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_rpcrt4, ( void ** )&_UuidToStringW, "UuidToStringW" ) )
48 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_rpcrt4, ( void ** )&_UuidCreate, "UuidCreate" ) )
49 |
50 | rpcrt4_state = RPCRT4_STATE_RUNNING;
51 |
52 | return true;
53 | }
54 |
55 | bool UnInitializeRpcRt4()
56 | {
57 | if ( rpcrt4_state != RPCRT4_STATE_SHUTDOWN )
58 | {
59 | rpcrt4_state = RPCRT4_STATE_SHUTDOWN;
60 |
61 | return ( FreeLibrary( hModule_rpcrt4 ) == FALSE ? false : true );
62 | }
63 |
64 | return true;
65 | }
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_rpcrt4.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _LITE_RPCRT4_H
20 | #define _LITE_RPCRT4_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #include
27 |
28 | //#define RPCRT4_USE_STATIC_LIB
29 |
30 | #ifdef RPCRT4_USE_STATIC_LIB
31 |
32 | //__pragma( comment( lib, "rpcrt4.lib" ) )
33 |
34 | #define _RpcStringFreeW RpcStringFreeW
35 | #define _UuidToStringW UuidToStringW
36 | #define _UuidCreate UuidCreate
37 |
38 | #else
39 |
40 | #define RPCRT4_STATE_SHUTDOWN 0
41 | #define RPCRT4_STATE_RUNNING 1
42 |
43 | typedef RPC_STATUS ( RPC_ENTRY *pRpcStringFreeW )( RPC_WSTR __RPC_FAR *String );
44 | typedef RPC_STATUS ( RPC_ENTRY *pUuidToStringW )( UUID __RPC_FAR *Uuid, RPC_WSTR __RPC_FAR *StringUuid );
45 | typedef RPC_STATUS ( RPC_ENTRY *pUuidCreate )( UUID __RPC_FAR *Uuid );
46 |
47 | extern pRpcStringFreeW _RpcStringFreeW;
48 | extern pUuidToStringW _UuidToStringW;
49 | extern pUuidCreate _UuidCreate;
50 |
51 | extern unsigned char rpcrt4_state;
52 |
53 | bool InitializeRpcRt4();
54 | bool UnInitializeRpcRt4();
55 |
56 | #endif
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_shell32.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "lite_dlls.h"
20 | #include "lite_shell32.h"
21 |
22 | #ifndef SHELL32_USE_STATIC_LIB
23 |
24 | //pShell_NotifyIconW _Shell_NotifyIconW;
25 | //pShellExecuteW _ShellExecuteW;
26 |
27 | pStrChrA _StrChrA;
28 | pStrStrA _StrStrA;
29 | pStrStrIA _StrStrIA;
30 |
31 | pStrCmpNA _StrCmpNA;
32 | pStrCmpNIA _StrCmpNIA;
33 |
34 | pStrCmpNIW _StrCmpNIW;
35 |
36 | //pSHBrowseForFolderW _SHBrowseForFolderW;
37 | //pSHGetPathFromIDListW _SHGetPathFromIDListW;
38 |
39 | //pSHGetFolderPathW _SHGetFolderPathW;
40 |
41 | //pCommandLineToArgvW _CommandLineToArgvW;
42 |
43 | HMODULE hModule_shell32 = NULL;
44 |
45 | unsigned char shell32_state = SHELL32_STATE_SHUTDOWN;
46 |
47 | bool InitializeShell32()
48 | {
49 | if ( shell32_state != SHELL32_STATE_SHUTDOWN )
50 | {
51 | return true;
52 | }
53 |
54 | hModule_shell32 = LoadLibraryDEMW( L"shell32.dll" );
55 |
56 | if ( hModule_shell32 == NULL )
57 | {
58 | return false;
59 | }
60 |
61 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_Shell_NotifyIconW, "Shell_NotifyIconW" ) )
62 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_ShellExecuteW, "ShellExecuteW" ) )
63 |
64 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_StrChrA, "StrChrA" ) )
65 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_StrStrA, "StrStrA" ) )
66 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_StrStrIA, "StrStrIA" ) )
67 |
68 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_StrCmpNA, "StrCmpNA" ) )
69 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_StrCmpNIA, "StrCmpNIA" ) )
70 |
71 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_StrCmpNIW, "StrCmpNIW" ) )
72 |
73 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_SHBrowseForFolderW, "SHBrowseForFolderW" ) )
74 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_SHGetPathFromIDListW, "SHGetPathFromIDListW" ) )
75 |
76 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_SHGetFolderPathW, "SHGetFolderPathW" ) )
77 |
78 | //VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_CommandLineToArgvW, "CommandLineToArgvW" ) )
79 |
80 | shell32_state = SHELL32_STATE_RUNNING;
81 |
82 | return true;
83 | }
84 |
85 | bool UnInitializeShell32()
86 | {
87 | if ( shell32_state != SHELL32_STATE_SHUTDOWN )
88 | {
89 | shell32_state = SHELL32_STATE_SHUTDOWN;
90 |
91 | return ( FreeLibrary( hModule_shell32 ) == FALSE ? false : true );
92 | }
93 |
94 | return true;
95 | }
96 |
97 | #endif
98 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_shell32.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _LITE_SHELL32_H
20 | #define _LITE_SHELL32_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #include
27 | #include
28 |
29 | //#define SHELL32_USE_STATIC_LIB
30 |
31 | #ifdef SHELL32_USE_STATIC_LIB
32 |
33 | //__pragma( comment( lib, "shell32.lib" ) )
34 | //__pragma( comment( lib, "shlwapi.lib" ) )
35 |
36 | #include
37 |
38 | //#define _Shell_NotifyIconW Shell_NotifyIconW
39 | //#define _ShellExecuteW ShellExecuteW
40 |
41 | #define _StrChrA StrChrA
42 | #define _StrStrA StrStrA
43 | #define _StrStrIA StrStrIA
44 |
45 | #define _StrCmpNA StrCmpNA
46 | #define _StrCmpNIA StrCmpNIA
47 |
48 | #define _StrCmpNIW StrCmpNIW
49 |
50 | //#define _SHBrowseForFolderW SHBrowseForFolderW
51 | //#define _SHGetPathFromIDListW SHGetPathFromIDListW
52 |
53 | //#define _SHGetFolderPathW SHGetFolderPathW
54 |
55 | //#define _CommandLineToArgvW CommandLineToArgvW
56 |
57 | #else
58 |
59 | #define SHELL32_STATE_SHUTDOWN 0
60 | #define SHELL32_STATE_RUNNING 1
61 |
62 | //typedef BOOL ( WINAPI *pShell_NotifyIconW )( DWORD dwMessage, PNOTIFYICONDATA lpdata );
63 | //typedef HINSTANCE ( WINAPI *pShellExecuteW )( HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters, LPCTSTR lpDirectory, INT nShowCmd );
64 |
65 | typedef PSTR ( WINAPI *pStrChrA )( PSTR pszStart, CHAR wMatch );
66 | typedef PSTR ( WINAPI *pStrStrA )( PSTR pszFirst, PCSTR pszSrch );
67 | typedef PSTR ( WINAPI *pStrStrIA )( PSTR pszFirst, PCSTR pszSrch );
68 |
69 | typedef int ( WINAPI *pStrCmpNA )( PCSTR psz1, PCSTR psz2, int nChar );
70 | typedef int ( WINAPI *pStrCmpNIA )( PCSTR psz1, PCSTR psz2, int nChar );
71 |
72 | typedef int ( WINAPI *pStrCmpNIW )( PCTSTR psz1, PCTSTR psz2, int nChar );
73 |
74 | //typedef PIDLIST_ABSOLUTE ( WINAPI *pSHBrowseForFolderW )( LPBROWSEINFO lpbi );
75 | //typedef BOOL ( WINAPI *pSHGetPathFromIDListW )( PCIDLIST_ABSOLUTE pidl, LPTSTR pszPath );
76 |
77 | //typedef HRESULT ( WINAPI *pSHGetFolderPathW )( HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath );
78 |
79 | //typedef LPWSTR * ( WINAPI *pCommandLineToArgvW )( LPCWSTR lpCmdLine, int *pNumArgs );
80 |
81 | //extern pShell_NotifyIconW _Shell_NotifyIconW;
82 | //extern pShellExecuteW _ShellExecuteW;
83 |
84 | extern pStrChrA _StrChrA;
85 | extern pStrStrA _StrStrA;
86 | extern pStrStrIA _StrStrIA;
87 |
88 | extern pStrCmpNA _StrCmpNA;
89 | extern pStrCmpNIA _StrCmpNIA;
90 |
91 | extern pStrCmpNIW _StrCmpNIW;
92 |
93 | //extern pSHBrowseForFolderW _SHBrowseForFolderW;
94 | //extern pSHGetPathFromIDListW _SHGetPathFromIDListW;
95 |
96 | //extern pSHGetFolderPathW _SHGetFolderPathW;
97 |
98 | //extern pCommandLineToArgvW _CommandLineToArgvW;
99 |
100 |
101 |
102 | extern unsigned char shell32_state;
103 |
104 | bool InitializeShell32();
105 | bool UnInitializeShell32();
106 |
107 | #endif
108 |
109 | #endif
110 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_ws2_32.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "lite_dlls.h"
20 | #include "lite_ws2_32.h"
21 |
22 | unsigned char ws2_32_state = 0; // 0 = Not running, 1 = running.
23 |
24 | #ifndef WS2_32_USE_STATIC_LIB
25 |
26 | pWSAStartup _WSAStartup;
27 | pWSACleanup _WSACleanup;
28 |
29 | pWSAWaitForMultipleEvents _WSAWaitForMultipleEvents;
30 | pWSACreateEvent _WSACreateEvent;
31 | pWSASetEvent _WSASetEvent;
32 | pWSAResetEvent _WSAResetEvent;
33 | pWSACloseEvent _WSACloseEvent;
34 |
35 | pWSASocketW _WSASocketW;
36 | pWSAConnect _WSAConnect;
37 |
38 | pWSAAddressToStringA _WSAAddressToStringA;
39 | pWSAAddressToStringW _WSAAddressToStringW;
40 | pFreeAddrInfoW _FreeAddrInfoW;
41 | pGetAddrInfoW _GetAddrInfoW;
42 | pGetNameInfoW _GetNameInfoW;
43 |
44 | pWSAGetLastError _WSAGetLastError;
45 |
46 | pWSAIoctl _WSAIoctl;
47 |
48 | pWSASend _WSASend;
49 | pWSARecv _WSARecv;
50 |
51 | pWSASendTo _WSASendTo;
52 | pWSARecvFrom _WSARecvFrom;
53 |
54 | psocket _socket;
55 | pconnect _connect;
56 | plisten _listen;
57 | pbind _bind;
58 | pshutdown _shutdown;
59 | pclosesocket _closesocket;
60 |
61 | psetsockopt _setsockopt;
62 |
63 | psend _send;
64 | precv _recv;
65 |
66 | pgetaddrinfo _getaddrinfo;
67 | pfreeaddrinfo _freeaddrinfo;
68 | pgetpeername _getpeername;
69 | pgetsockname _getsockname;
70 |
71 | pinet_ntoa _inet_ntoa;
72 |
73 | phtonl _htonl;
74 | phtons _htons;
75 |
76 | HMODULE hModule_ws2_32 = NULL;
77 |
78 | bool InitializeWS2_32()
79 | {
80 | if ( ws2_32_state != WS2_32_STATE_SHUTDOWN )
81 | {
82 | return true;
83 | }
84 |
85 | hModule_ws2_32 = LoadLibraryDEMW( L"ws2_32.dll" );
86 |
87 | if ( hModule_ws2_32 == NULL )
88 | {
89 | return false;
90 | }
91 |
92 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSAStartup, "WSAStartup" ) )
93 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSACleanup, "WSACleanup" ) )
94 |
95 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSAWaitForMultipleEvents, "WSAWaitForMultipleEvents" ) )
96 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSACreateEvent, "WSACreateEvent" ) )
97 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSASetEvent, "WSASetEvent" ) )
98 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSAResetEvent, "WSAResetEvent" ) )
99 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSACloseEvent, "WSACloseEvent" ) )
100 |
101 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSASocketW, "WSASocketW" ) )
102 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSAConnect, "WSAConnect" ) )
103 |
104 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSAAddressToStringA, "WSAAddressToStringA" ) )
105 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSAAddressToStringW, "WSAAddressToStringW" ) )
106 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_FreeAddrInfoW, "FreeAddrInfoW" ) )
107 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_GetAddrInfoW, "GetAddrInfoW" ) )
108 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_GetNameInfoW, "GetNameInfoW" ) )
109 |
110 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSAGetLastError, "WSAGetLastError" ) )
111 |
112 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSAIoctl, "WSAIoctl" ) )
113 |
114 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSASend, "WSASend" ) )
115 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSARecv, "WSARecv" ) )
116 |
117 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSASendTo, "WSASendTo" ) )
118 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_WSARecvFrom, "WSARecvFrom" ) )
119 |
120 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_socket, "socket" ) )
121 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_connect, "connect" ) )
122 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_listen, "listen" ) )
123 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_bind, "bind" ) )
124 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_shutdown, "shutdown" ) )
125 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_closesocket, "closesocket" ) )
126 |
127 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_setsockopt, "setsockopt" ) )
128 |
129 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_send, "send" ) )
130 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_recv, "recv" ) )
131 |
132 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_getaddrinfo, "getaddrinfo" ) )
133 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_freeaddrinfo, "freeaddrinfo" ) )
134 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_getpeername, "getpeername" ) )
135 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_getsockname, "getsockname" ) )
136 |
137 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_inet_ntoa, "inet_ntoa" ) )
138 |
139 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_htonl, "htonl" ) )
140 | VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ws2_32, ( void ** )&_htons, "htons" ) )
141 |
142 | StartWS2_32();
143 |
144 | return true;
145 | }
146 |
147 | bool UnInitializeWS2_32()
148 | {
149 | if ( ws2_32_state != WS2_32_STATE_SHUTDOWN )
150 | {
151 | EndWS2_32();
152 |
153 | return ( FreeLibrary( hModule_ws2_32 ) == FALSE ? false : true );
154 | }
155 |
156 | return true;
157 | }
158 |
159 | #endif
160 |
161 | void StartWS2_32()
162 | {
163 | if ( ws2_32_state != WS2_32_STATE_RUNNING )
164 | {
165 | // Initialize Winsock
166 | WSADATA wsaData;
167 | _WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
168 | }
169 |
170 | ws2_32_state = WS2_32_STATE_RUNNING;
171 | }
172 |
173 | void EndWS2_32()
174 | {
175 | if ( ws2_32_state != WS2_32_STATE_SHUTDOWN )
176 | {
177 | // Cleanup Winsock.
178 | _WSACleanup();
179 | }
180 |
181 | ws2_32_state = WS2_32_STATE_SHUTDOWN;
182 | }
183 |
--------------------------------------------------------------------------------
/HTTP_Proxy/lite_ws2_32.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _LITE_WINSOCK_H
20 | #define _LITE_WINSOCK_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #include
27 | #include
28 |
29 | //#define WS2_32_USE_STATIC_LIB
30 |
31 | #define WS2_32_STATE_SHUTDOWN 0
32 | #define WS2_32_STATE_RUNNING 1
33 |
34 | #ifdef WS2_32_USE_STATIC_LIB
35 |
36 | //__pragma( comment( lib, "ws2_32.lib" ) )
37 |
38 | #define _WSAStartup WSAStartup
39 | #define _WSACleanup WSACleanup
40 |
41 | #define _WSAWaitForMultipleEvents WSAWaitForMultipleEvents
42 | #define _WSACreateEvent WSACreateEvent
43 | #define _WSASetEvent WSASetEvent
44 | #define _WSAResetEvent WSAResetEvent
45 | #define _WSACloseEvent WSACloseEvent
46 |
47 | #define _WSASocketW WSASocketW
48 | #define _WSAConnect WSAConnect
49 |
50 | #define _WSAAddressToStringA WSAAddressToStringA
51 | #define _WSAAddressToStringW WSAAddressToStringW
52 | #define _FreeAddrInfoW FreeAddrInfoW
53 | #define _GetAddrInfoW GetAddrInfoW
54 | #define _GetNameInfoW GetNameInfoW
55 |
56 | #define _WSAGetLastError WSAGetLastError
57 |
58 | #define _WSAIoctl WSAIoctl
59 |
60 | #define _WSASend WSASend
61 | #define _WSARecv WSARecv
62 |
63 | #define _WSASendTo WSASendTo
64 | #define _WSARecvFrom WSARecvFrom
65 |
66 | #define _socket socket
67 | #define _connect connect
68 | #define _listen listen
69 | #define _bind bind
70 | #define _shutdown shutdown
71 | #define _closesocket closesocket
72 |
73 | #define _setsockopt setsockopt
74 |
75 | #define _send send
76 | #define _recv recv
77 |
78 | #define _getaddrinfo getaddrinfo
79 | #define _freeaddrinfo freeaddrinfo
80 | #define _getpeername getpeername
81 | #define _getsockname getsockname
82 |
83 | #define _inet_ntoa inet_ntoa
84 |
85 | #define _htonl htonl
86 | #define _htons htons
87 |
88 | #else
89 |
90 | typedef int ( WSAAPI *pWSAStartup )( WORD wVersionRequested, LPWSADATA lpWSAData );
91 | typedef int ( WSAAPI *pWSACleanup )( void );
92 |
93 | typedef DWORD ( WSAAPI *pWSAWaitForMultipleEvents )( DWORD cEvents, const WSAEVENT *lphEvents, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable );
94 | typedef WSAEVENT ( WSAAPI *pWSACreateEvent )( void );
95 | typedef BOOL ( WSAAPI *pWSASetEvent )( WSAEVENT hEvent );
96 | typedef BOOL ( WSAAPI *pWSAResetEvent )( WSAEVENT hEvent );
97 | typedef BOOL ( WSAAPI *pWSACloseEvent )( WSAEVENT hEvent );
98 |
99 | typedef SOCKET ( WSAAPI *pWSASocketW )( int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags );
100 | typedef int ( WSAAPI *pWSAConnect )( SOCKET s, const struct sockaddr *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS );
101 |
102 | typedef INT ( WSAAPI *pWSAAddressToStringA )( LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFO lpProtocolInfo, LPSTR lpszAddressString, LPDWORD lpdwAddressStringLength );
103 | typedef INT ( WSAAPI *pWSAAddressToStringW )( LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFO lpProtocolInfo, LPTSTR lpszAddressString, LPDWORD lpdwAddressStringLength );
104 | typedef void ( WSAAPI *pFreeAddrInfoW )( PADDRINFOW pAddrInfo );
105 | typedef int ( WSAAPI *pGetAddrInfoW )( PCWSTR pNodeName, PCWSTR pServiceName, const ADDRINFOW *pHints, PADDRINFOW *ppResult );
106 | typedef int ( WSAAPI *pGetNameInfoW )( const SOCKADDR *pSockaddr, socklen_t SockaddrLength, PWCHAR pNodeBuffer, DWORD NodeBufferSize, PWCHAR pServiceBuffer, DWORD ServiceBufferSize, INT Flags );
107 |
108 | typedef int ( WSAAPI *pWSAGetLastError )( void );
109 |
110 | typedef int ( WSAAPI *pWSAIoctl )( SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
111 |
112 | typedef int ( WSAAPI *pWSASend )( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
113 | typedef int ( WSAAPI *pWSARecv )( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
114 |
115 | typedef int ( WSAAPI *pWSASendTo )( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, const struct sockaddr *lpTo, int iToLen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
116 | typedef int ( WSAAPI *pWSARecvFrom )( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct sockaddr *lpFrom, LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
117 |
118 | typedef SOCKET ( WSAAPI *psocket )( int af, int type, int protocol );
119 | typedef int ( WSAAPI *pconnect )( SOCKET s, const struct sockaddr *name, int namelen );
120 | typedef int ( WSAAPI *plisten )( SOCKET s, int backlog );
121 | typedef int ( WSAAPI *pbind )( SOCKET s, const struct sockaddr *name, int namelen );
122 | typedef int ( WSAAPI *pshutdown )( SOCKET s, int how );
123 | typedef int ( WSAAPI *pclosesocket )( SOCKET s );
124 |
125 | typedef int ( WSAAPI *psetsockopt )( SOCKET s, int level, int optname, const char *optval, int optlen );
126 |
127 | typedef int ( WSAAPI *psend )( SOCKET s, const char *buf, int len, int flags );
128 | typedef int ( WSAAPI *precv )( SOCKET s, const char *buf, int len, int flags );
129 |
130 | typedef int ( WSAAPI *pgetaddrinfo )( PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA *pHints, PADDRINFOA *ppResult );
131 | typedef void ( WSAAPI *pfreeaddrinfo )( struct addrinfo *ai );
132 | typedef int ( WSAAPI *pgetpeername )( SOCKET s, struct sockaddr *name, int *namelen );
133 | typedef int ( WSAAPI *pgetsockname )( SOCKET s, struct sockaddr *name, int *namelen );
134 |
135 | typedef char *FAR ( WSAAPI *pinet_ntoa )( struct in_addr in );
136 |
137 | typedef u_long ( WSAAPI *phtonl )( u_long hostlong );
138 | typedef u_short ( WSAAPI *phtons )( u_short hostshort );
139 |
140 | extern pWSAStartup _WSAStartup;
141 | extern pWSACleanup _WSACleanup;
142 |
143 | extern pWSAWaitForMultipleEvents _WSAWaitForMultipleEvents;
144 | extern pWSACreateEvent _WSACreateEvent;
145 | extern pWSASetEvent _WSASetEvent;
146 | extern pWSAResetEvent _WSAResetEvent;
147 | extern pWSACloseEvent _WSACloseEvent;
148 |
149 | extern pWSASocketW _WSASocketW;
150 | extern pWSAConnect _WSAConnect;
151 |
152 | extern pWSAAddressToStringA _WSAAddressToStringA;
153 | extern pWSAAddressToStringW _WSAAddressToStringW;
154 | extern pFreeAddrInfoW _FreeAddrInfoW;
155 | extern pGetAddrInfoW _GetAddrInfoW;
156 | extern pGetNameInfoW _GetNameInfoW;
157 |
158 | extern pWSAGetLastError _WSAGetLastError;
159 |
160 | extern pWSAIoctl _WSAIoctl;
161 |
162 | extern pWSASend _WSASend;
163 | extern pWSARecv _WSARecv;
164 |
165 | extern pWSASendTo _WSASendTo;
166 | extern pWSARecvFrom _WSARecvFrom;
167 |
168 | extern psocket _socket;
169 | extern pconnect _connect;
170 | extern plisten _listen;
171 | extern pbind _bind;
172 | extern pshutdown _shutdown;
173 | extern pclosesocket _closesocket;
174 |
175 | extern psetsockopt _setsockopt;
176 |
177 | extern psend _send;
178 | extern precv _recv;
179 |
180 | extern pgetaddrinfo _getaddrinfo;
181 | extern pfreeaddrinfo _freeaddrinfo;
182 | extern pgetpeername _getpeername;
183 | extern pgetsockname _getsockname;
184 |
185 | extern pinet_ntoa _inet_ntoa;
186 |
187 | extern phtonl _htonl;
188 | extern phtons _htons;
189 |
190 | bool InitializeWS2_32();
191 | bool UnInitializeWS2_32();
192 |
193 | #endif
194 |
195 | void StartWS2_32();
196 | void EndWS2_32();
197 |
198 | extern unsigned char ws2_32_state;
199 |
200 | #endif
201 |
--------------------------------------------------------------------------------
/HTTP_Proxy/ssl.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "ssl.h"
20 |
21 | #include "lite_dlls.h"
22 | #include "lite_ntdll.h"
23 | #include "lite_rpcrt4.h"
24 | #include "lite_advapi32.h"
25 | #include "lite_crypt32.h"
26 |
27 | #include "connection.h"
28 |
29 | HMODULE g_hSecurity = NULL;
30 | PSecurityFunctionTableA g_pSSPI;
31 |
32 | typedef BOOL ( WINAPI *pSslEmptyCacheW )( LPSTR pszTargetName, DWORD dwFlags );
33 | pSslEmptyCacheW _SslEmptyCacheW;
34 |
35 | unsigned char ssl_state = SSL_STATE_SHUTDOWN;
36 |
37 | CredHandle g_hCreds_server;
38 | CredHandle g_hCreds_client;
39 |
40 | void ResetServerCredentials()
41 | {
42 | if ( SecIsValidHandle( &g_hCreds_server ) )
43 | {
44 | g_pSSPI->FreeCredentialsHandle( &g_hCreds_server );
45 | SecInvalidateHandle( &g_hCreds_server );
46 | }
47 | }
48 |
49 | void ResetClientCredentials()
50 | {
51 | if ( SecIsValidHandle( &g_hCreds_client ) )
52 | {
53 | g_pSSPI->FreeCredentialsHandle( &g_hCreds_client );
54 | SecInvalidateHandle( &g_hCreds_client );
55 | }
56 | }
57 |
58 | int SSL_library_init( void )
59 | {
60 | if ( ssl_state != SSL_STATE_SHUTDOWN )
61 | {
62 | return 1;
63 | }
64 |
65 | g_hSecurity = LoadLibraryDEMW( L"schannel.dll" );
66 | if ( g_hSecurity == NULL )
67 | {
68 | return 0;
69 | }
70 |
71 | _SslEmptyCacheW = ( pSslEmptyCacheW )GetProcAddress( g_hSecurity, "SslEmptyCacheW" );
72 | if ( _SslEmptyCacheW == NULL )
73 | {
74 | FreeLibrary( g_hSecurity );
75 | g_hSecurity = NULL;
76 | return 0;
77 | }
78 |
79 | INIT_SECURITY_INTERFACE_A pInitSecurityInterface = ( INIT_SECURITY_INTERFACE_A )GetProcAddress( g_hSecurity, SECURITY_ENTRYPOINT_ANSIA );
80 | if ( pInitSecurityInterface != NULL )
81 | {
82 | g_pSSPI = pInitSecurityInterface();
83 | }
84 |
85 | if ( g_pSSPI == NULL )
86 | {
87 | FreeLibrary( g_hSecurity );
88 | g_hSecurity = NULL;
89 | return 0;
90 | }
91 |
92 | ssl_state = SSL_STATE_RUNNING;
93 |
94 | SecInvalidateHandle( &g_hCreds_server );
95 | SecInvalidateHandle( &g_hCreds_client );
96 |
97 | return 1;
98 | }
99 |
100 | int SSL_library_uninit( void )
101 | {
102 | BOOL ret = 0;
103 |
104 | if ( ssl_state != SSL_STATE_SHUTDOWN )
105 | {
106 | ResetServerCredentials();
107 | ResetClientCredentials();
108 |
109 | _SslEmptyCacheW( NULL, 0 );
110 |
111 | ret = FreeLibrary( g_hSecurity );
112 | }
113 |
114 | ssl_state = SSL_STATE_SHUTDOWN;
115 |
116 | return ret;
117 | }
118 |
119 | SSL *SSL_new( DWORD protocol, bool is_server )
120 | {
121 | SCHANNEL_CRED SchannelCred;
122 | TimeStamp tsExpiry;
123 | SECURITY_STATUS scRet;
124 |
125 | if ( g_hSecurity == NULL )
126 | {
127 | return NULL;
128 | }
129 |
130 | SSL *ssl = ( SSL * )GlobalAlloc( GPTR, sizeof( SSL ) );
131 | if ( ssl == NULL )
132 | {
133 | return NULL;
134 | }
135 |
136 | if ( is_server )
137 | {
138 | if ( !SecIsValidHandle( &g_hCreds_server ) )
139 | {
140 | _memzero( &SchannelCred, sizeof( SchannelCred ) );
141 |
142 | SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
143 | SchannelCred.cCreds = 1;
144 | SchannelCred.paCred = &g_pCertContext;
145 | SchannelCred.dwMinimumCipherStrength = -1;
146 | SchannelCred.grbitEnabledProtocols = protocol;
147 | SchannelCred.dwFlags = ( SCH_CRED_NO_SYSTEM_MAPPER | SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_REVOCATION_CHECK_CHAIN );
148 |
149 | scRet = g_pSSPI->AcquireCredentialsHandleA(
150 | NULL,
151 | UNISP_NAME_A,
152 | SECPKG_CRED_INBOUND,
153 | NULL,
154 | &SchannelCred,
155 | NULL,
156 | NULL,
157 | &g_hCreds_server,
158 | &tsExpiry );
159 |
160 | if ( scRet != SEC_E_OK )
161 | {
162 | ResetServerCredentials();
163 |
164 | GlobalFree( ssl );
165 |
166 | return NULL;
167 | }
168 | }
169 | }
170 | else
171 | {
172 | if ( !SecIsValidHandle( &g_hCreds_client ) )
173 | {
174 | _memzero( &SchannelCred, sizeof( SchannelCred ) );
175 |
176 | SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
177 | SchannelCred.grbitEnabledProtocols = protocol;
178 | SchannelCred.dwFlags = ( SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION );
179 |
180 | // Create an SSPI credential.
181 | scRet = g_pSSPI->AcquireCredentialsHandleA(
182 | NULL,
183 | UNISP_NAME_A,
184 | SECPKG_CRED_OUTBOUND,
185 | NULL,
186 | &SchannelCred,
187 | NULL,
188 | NULL,
189 | &g_hCreds_client,
190 | &tsExpiry );
191 |
192 | if ( scRet != SEC_E_OK )
193 | {
194 | ResetClientCredentials();
195 |
196 | GlobalFree( ssl );
197 | ssl = NULL;
198 | }
199 | }
200 | }
201 |
202 | return ssl;
203 | }
204 |
205 | void SSL_free( SSL *ssl )
206 | {
207 | if ( ssl == NULL )
208 | {
209 | return;
210 | }
211 |
212 | if ( ssl->sdd.OutBuffers[ 0 ].pvBuffer != NULL )
213 | {
214 | g_pSSPI->FreeContextBuffer( ssl->sdd.OutBuffers[ 0 ].pvBuffer );
215 | ssl->sdd.OutBuffers[ 0 ].pvBuffer = NULL;
216 | }
217 |
218 | /*if ( ssl->ad.OutBuffers[ 0 ].pvBuffer != NULL )
219 | {
220 | g_pSSPI->FreeContextBuffer( ssl->ad.OutBuffers[ 0 ].pvBuffer );
221 | ssl->ad.OutBuffers[ 0 ].pvBuffer = NULL;
222 | }
223 |
224 | if ( ssl->cd.OutBuffers[ 0 ].pvBuffer != NULL )
225 | {
226 | g_pSSPI->FreeContextBuffer( ssl->cd.OutBuffers[ 0 ].pvBuffer );
227 | ssl->cd.OutBuffers[ 0 ].pvBuffer = NULL;
228 | }*/
229 |
230 | if ( ssl->acd.OutBuffers[ 0 ].pvBuffer != NULL )
231 | {
232 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
233 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
234 | }
235 |
236 | if ( ssl->sd.pbDataBuffer != NULL )
237 | {
238 | GlobalFree( ssl->sd.pbDataBuffer );
239 | ssl->sd.pbDataBuffer = NULL;
240 | }
241 |
242 | if ( ssl->pbRecDataBuf != NULL )
243 | {
244 | GlobalFree( ssl->pbRecDataBuf );
245 | ssl->pbRecDataBuf = NULL;
246 | }
247 |
248 | if ( ssl->pbIoBuffer != NULL )
249 | {
250 | GlobalFree( ssl->pbIoBuffer );
251 | ssl->pbIoBuffer = NULL;
252 | }
253 |
254 | if ( SecIsValidHandle( &ssl->hContext ) )
255 | {
256 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
257 | SecInvalidateHandle( &ssl->hContext );
258 | }
259 |
260 | GlobalFree( ssl );
261 | }
262 |
263 | SECURITY_STATUS SSL_WSAAccept( SOCKET_CONTEXT *context, bool &sent )
264 | {
265 | SECURITY_STATUS scRet = SEC_E_INTERNAL_ERROR;
266 |
267 | sent = false;
268 |
269 | if ( context != NULL && context->ssl != NULL )
270 | {
271 | SSL *ssl = context->ssl;
272 | DWORD dwFlags = 0;
273 |
274 | // Begin our handshake.
275 | ssl->acd.fInitContext = true;
276 |
277 | ssl->cbIoBuffer = 0;
278 |
279 | ssl->acd.fDoRead = true;
280 |
281 | ssl->acd.scRet = SEC_I_CONTINUE_NEEDED;
282 | scRet = ssl->acd.scRet;
283 |
284 | WSABUF encrypted_buf;
285 |
286 | // If buffer not large enough reallocate buffer
287 | if ( ssl->sbIoBuffer <= ssl->cbIoBuffer )
288 | {
289 | ssl->sbIoBuffer += 2048;
290 |
291 | if ( ssl->pbIoBuffer == NULL )
292 | {
293 | ssl->pbIoBuffer = ( PUCHAR )GlobalAlloc( GPTR, ssl->sbIoBuffer );
294 | }
295 | else
296 | {
297 | ssl->pbIoBuffer = ( PUCHAR )GlobalReAlloc( ssl->pbIoBuffer, ssl->sbIoBuffer, GMEM_MOVEABLE );
298 | }
299 | }
300 |
301 | sent = true;
302 |
303 | encrypted_buf.buf = ( char * )ssl->pbIoBuffer + ssl->cbIoBuffer;
304 | encrypted_buf.len = ssl->sbIoBuffer - ssl->cbIoBuffer;
305 |
306 | int nRet = _WSARecv( ssl->s, &encrypted_buf, 1, NULL, &dwFlags, &context->overlapped_read, NULL );
307 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
308 | {
309 | sent = false;
310 | ssl->acd.scRet = SEC_E_INTERNAL_ERROR;
311 | scRet = ssl->acd.scRet;
312 | }
313 | }
314 |
315 | return scRet;
316 | }
317 |
318 | SECURITY_STATUS SSL_WSAAccept_Reply( SOCKET_CONTEXT *context, bool &sent )
319 | {
320 | SECURITY_STATUS scRet = SEC_E_INTERNAL_ERROR;
321 |
322 | sent = false;
323 |
324 | if ( context != NULL && context->ssl != NULL )
325 | {
326 | SSL *ssl = context->ssl;
327 | SecBufferDesc InBuffer;
328 | SecBufferDesc OutBuffer;
329 | TimeStamp tsExpiry;
330 | DWORD dwSSPIFlags;
331 | DWORD dwSSPIOutFlags;
332 |
333 | scRet = ssl->acd.scRet;
334 |
335 | dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT |
336 | ASC_REQ_REPLAY_DETECT |
337 | ASC_REQ_CONFIDENTIALITY |
338 | ASC_REQ_EXTENDED_ERROR |
339 | ASC_REQ_ALLOCATE_MEMORY |
340 | ASC_REQ_STREAM;
341 |
342 | if ( scRet == SEC_I_CONTINUE_NEEDED || scRet == SEC_E_INCOMPLETE_MESSAGE || scRet == SEC_I_INCOMPLETE_CREDENTIALS )
343 | {
344 | // Set up the input buffers. Buffer 0 is used to pass in data
345 | // received from the server. Schannel will consume some or all
346 | // of this. Leftover data (if any) will be placed in buffer 1 and
347 | // given a buffer type of SECBUFFER_EXTRA.
348 |
349 | ssl->acd.InBuffers[ 0 ].pvBuffer = ssl->pbIoBuffer;
350 | ssl->acd.InBuffers[ 0 ].cbBuffer = ssl->cbIoBuffer;
351 | ssl->acd.InBuffers[ 0 ].BufferType = SECBUFFER_TOKEN;
352 |
353 | ssl->acd.InBuffers[ 1 ].pvBuffer = NULL;
354 | ssl->acd.InBuffers[ 1 ].cbBuffer = 0;
355 | ssl->acd.InBuffers[ 1 ].BufferType = SECBUFFER_EMPTY;
356 |
357 | InBuffer.cBuffers = 2;
358 | InBuffer.pBuffers = ssl->acd.InBuffers;
359 | InBuffer.ulVersion = SECBUFFER_VERSION;
360 |
361 | // Set up the output buffers. These are initialized to NULL
362 | // so as to make it less likely we'll attempt to free random
363 | // garbage later.
364 |
365 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
366 | ssl->acd.OutBuffers[ 0 ].BufferType = SECBUFFER_TOKEN;
367 | ssl->acd.OutBuffers[ 0 ].cbBuffer = 0;
368 |
369 | OutBuffer.cBuffers = 1;
370 | OutBuffer.pBuffers = ssl->acd.OutBuffers;
371 | OutBuffer.ulVersion = SECBUFFER_VERSION;
372 |
373 | /*if ( !ssl->acd.fInitContext )
374 | {
375 | dwSSPIFlags |= ASC_REQ_MUTUAL_AUTH;
376 | }*/
377 |
378 | ssl->acd.scRet = g_pSSPI->AcceptSecurityContext(
379 | &g_hCreds_server,
380 | ( ssl->acd.fInitContext ? NULL : &ssl->hContext ),
381 | &InBuffer,
382 | dwSSPIFlags,
383 | SECURITY_NATIVE_DREP,
384 | ( ssl->acd.fInitContext ? &ssl->hContext : NULL ),
385 | &OutBuffer,
386 | &dwSSPIOutFlags,
387 | &tsExpiry );
388 |
389 | scRet = ssl->acd.scRet;
390 |
391 | ssl->acd.fInitContext = false;
392 |
393 | // If success (or if the error was one of the special extended ones), send the contents of the output buffer to the client.
394 | if ( scRet == SEC_E_OK || scRet == SEC_I_CONTINUE_NEEDED || FAILED( scRet ) && ( dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR ) )
395 | {
396 | if ( ssl->acd.OutBuffers[ 0 ].cbBuffer != 0 && ssl->acd.OutBuffers[ 0 ].pvBuffer != NULL )
397 | {
398 | sent = true;
399 |
400 | context->wsabuf_write.buf = ( char * )ssl->acd.OutBuffers[ 0 ].pvBuffer;
401 | context->wsabuf_write.len = ssl->acd.OutBuffers[ 0 ].cbBuffer;
402 |
403 | context->current_operation_write = IO_Write;
404 |
405 | int nRet = _WSASend( ssl->s, &context->wsabuf_write, 1, NULL, 0, &context->overlapped_write, NULL );
406 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
407 | {
408 | sent = false;
409 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
410 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
411 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
412 | SecInvalidateHandle( &ssl->hContext );
413 |
414 | return SEC_E_INTERNAL_ERROR;
415 | }
416 |
417 | // ssl->acd.OutBuffers[ 0 ].pvBuffer is freed in SSL_WSAAccept_Response (assuming we get a response).
418 |
419 | return SEC_I_CONTINUE_NEEDED;
420 | }
421 | else if ( scRet == SEC_E_OK )
422 | {
423 | // Store remaining data for further use
424 | if ( ssl->acd.InBuffers[ 1 ].BufferType == SECBUFFER_EXTRA ) // The extra data is actually the HTTP request.
425 | {
426 | _memmove( ssl->pbIoBuffer, ssl->pbIoBuffer + ( ssl->cbIoBuffer - ssl->acd.InBuffers[ 1 ].cbBuffer ), ssl->acd.InBuffers[ 1 ].cbBuffer );
427 | ssl->cbIoBuffer = ssl->acd.InBuffers[ 1 ].cbBuffer;
428 | }
429 | else
430 | {
431 | ssl->cbIoBuffer = 0;
432 |
433 | if ( ssl->pbIoBuffer != NULL )
434 | {
435 | GlobalFree( ssl->pbIoBuffer );
436 | ssl->pbIoBuffer = NULL;
437 | }
438 |
439 | ssl->sbIoBuffer = 0;
440 | }
441 |
442 | if ( ssl->acd.OutBuffers[ 0 ].pvBuffer != NULL )
443 | {
444 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
445 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
446 | }
447 | }
448 | }
449 | }
450 | }
451 |
452 | return scRet;
453 | }
454 |
455 | SECURITY_STATUS SSL_WSAAccept_Response( SOCKET_CONTEXT *context, bool &sent )
456 | {
457 | SECURITY_STATUS scRet = SEC_E_INTERNAL_ERROR;
458 |
459 | sent = false;
460 |
461 | if ( context != NULL && context->ssl != NULL )
462 | {
463 | SSL *ssl = context->ssl;
464 | DWORD dwFlags = 0;
465 |
466 | WSABUF encrypted_buf;
467 |
468 | scRet = ssl->acd.scRet;
469 |
470 | // Created in our call to SSL_WSAAccept_Reply.
471 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
472 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
473 |
474 | if ( scRet == SEC_I_CONTINUE_NEEDED || scRet == SEC_E_INCOMPLETE_MESSAGE || scRet == SEC_I_INCOMPLETE_CREDENTIALS )
475 | {
476 | // Server just requested client authentication.
477 | if ( scRet == SEC_I_INCOMPLETE_CREDENTIALS )
478 | {
479 | // Go around again.
480 | ssl->acd.fDoRead = false;
481 | ssl->acd.scRet = SEC_I_CONTINUE_NEEDED;
482 |
483 | return ssl->acd.scRet;
484 | }
485 |
486 | // We need to read more data from the server and try again.
487 | if ( scRet == SEC_E_INCOMPLETE_MESSAGE )
488 | {
489 | return scRet;
490 | }
491 |
492 | // Copy any leftover data from the buffer, and go around again.
493 | if ( ssl->acd.InBuffers[ 1 ].BufferType == SECBUFFER_EXTRA )
494 | {
495 | _memmove( ssl->pbIoBuffer, ssl->pbIoBuffer + ( ssl->cbIoBuffer - ssl->acd.InBuffers[ 1 ].cbBuffer ), ssl->acd.InBuffers[ 1 ].cbBuffer );
496 |
497 | ssl->cbIoBuffer = ssl->acd.InBuffers[ 1 ].cbBuffer;
498 | }
499 | else
500 | {
501 | ssl->cbIoBuffer = 0;
502 | }
503 |
504 | // Read client data.
505 | if ( ssl->cbIoBuffer == 0 )
506 | {
507 | if ( ssl->acd.fDoRead )
508 | {
509 | // Reallocate the buffer if it needs to be larger.
510 | if ( ssl->sbIoBuffer <= ssl->cbIoBuffer )
511 | {
512 | ssl->sbIoBuffer += 2048;
513 |
514 | if ( ssl->pbIoBuffer == NULL )
515 | {
516 | ssl->pbIoBuffer = ( PUCHAR )GlobalAlloc( GPTR, ssl->sbIoBuffer );
517 | }
518 | else
519 | {
520 | ssl->pbIoBuffer = ( PUCHAR )GlobalReAlloc( ssl->pbIoBuffer, ssl->sbIoBuffer, GMEM_MOVEABLE );
521 | }
522 | }
523 |
524 | sent = true;
525 |
526 | encrypted_buf.buf = ( char * )ssl->pbIoBuffer + ssl->cbIoBuffer;
527 | encrypted_buf.len = ssl->sbIoBuffer - ssl->cbIoBuffer;
528 |
529 | int nRet = _WSARecv( ssl->s, &encrypted_buf, 1, NULL, &dwFlags, &context->overlapped_read, NULL );
530 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
531 | {
532 | sent = false;
533 |
534 | if ( ssl->pbIoBuffer != NULL )
535 | {
536 | GlobalFree( ssl->pbIoBuffer );
537 | ssl->pbIoBuffer = NULL;
538 | }
539 |
540 | ssl->sbIoBuffer = 0;
541 |
542 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
543 | SecInvalidateHandle( &ssl->hContext );
544 |
545 | return SEC_E_INTERNAL_ERROR;
546 | }
547 | }
548 | else
549 | {
550 | ssl->acd.fDoRead = true;
551 | }
552 | }
553 | }
554 | else if ( scRet == SEC_E_OK ) // Handshake completed successfully.
555 | {
556 | // Store remaining data for further use
557 | if ( ssl->acd.InBuffers[ 1 ].BufferType == SECBUFFER_EXTRA ) // The extra data is actually the HTTP request.
558 | {
559 | _memmove( ssl->pbIoBuffer, ssl->pbIoBuffer + ( ssl->cbIoBuffer - ssl->acd.InBuffers[ 1 ].cbBuffer ), ssl->acd.InBuffers[ 1 ].cbBuffer );
560 | ssl->cbIoBuffer = ssl->acd.InBuffers[ 1 ].cbBuffer;
561 | }
562 | else
563 | {
564 | ssl->cbIoBuffer = 0;
565 |
566 | if ( ssl->pbIoBuffer != NULL )
567 | {
568 | GlobalFree( ssl->pbIoBuffer );
569 | ssl->pbIoBuffer = NULL;
570 | }
571 |
572 | ssl->sbIoBuffer = 0;
573 | }
574 | }
575 | else if ( FAILED( scRet ) ) // Delete the security context in the case of a fatal error.
576 | {
577 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
578 | SecInvalidateHandle( &ssl->hContext );
579 | }
580 | }
581 |
582 | // We've completed everything above. Return our final status.
583 | return scRet;
584 | }
585 |
586 | SECURITY_STATUS SSL_WSAConnect( SOCKET_CONTEXT *context, char *host, bool &sent )
587 | {
588 | SECURITY_STATUS scRet = SEC_E_INTERNAL_ERROR;
589 |
590 | sent = false;
591 |
592 | if ( context != NULL && context->ssl != NULL )
593 | {
594 | SSL *ssl = context->ssl;
595 | SecBufferDesc OutBuffer;
596 | DWORD dwSSPIFlags;
597 | DWORD dwSSPIOutFlags;
598 | TimeStamp tsExpiry;
599 |
600 | ssl->cbIoBuffer = 0;
601 |
602 | ssl->acd.fDoRead = true;
603 |
604 | ssl->acd.scRet = SEC_I_CONTINUE_NEEDED;
605 | scRet = ssl->acd.scRet;
606 |
607 | dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT |
608 | ISC_REQ_REPLAY_DETECT |
609 | ISC_REQ_CONFIDENTIALITY |
610 | ISC_RET_EXTENDED_ERROR |
611 | ISC_REQ_ALLOCATE_MEMORY |
612 | ISC_REQ_STREAM;
613 |
614 | // Initiate a ClientHello message and generate a token.
615 |
616 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
617 | ssl->acd.OutBuffers[ 0 ].BufferType = SECBUFFER_TOKEN;
618 | ssl->acd.OutBuffers[ 0 ].cbBuffer = 0;
619 |
620 | OutBuffer.cBuffers = 1;
621 | OutBuffer.pBuffers = ssl->acd.OutBuffers;
622 | OutBuffer.ulVersion = SECBUFFER_VERSION;
623 |
624 | /*struct sockaddr_in sock;
625 | int slen = sizeof( struct sockaddr );
626 | _getpeername( ssl->s, ( struct sockaddr * ) &sock, &slen );*/
627 |
628 | scRet = g_pSSPI->InitializeSecurityContextA(
629 | &g_hCreds_client,
630 | NULL,
631 | host/*_inet_ntoa( sock.sin_addr )*/,
632 | dwSSPIFlags,
633 | 0,
634 | SECURITY_NATIVE_DREP,
635 | NULL,
636 | 0,
637 | &ssl->hContext,
638 | &OutBuffer,
639 | &dwSSPIOutFlags,
640 | &tsExpiry );
641 |
642 | if ( scRet != SEC_I_CONTINUE_NEEDED )
643 | {
644 | return scRet;
645 | }
646 |
647 | ssl->acd.scRet = scRet;
648 |
649 | // Send response to server if there is one.
650 | if ( ssl->acd.OutBuffers[ 0 ].cbBuffer != 0 && ssl->acd.OutBuffers[ 0 ].pvBuffer != NULL )
651 | {
652 | sent = true;
653 |
654 | context->wsabuf_write.buf = ( char * )ssl->acd.OutBuffers[ 0 ].pvBuffer;
655 | context->wsabuf_write.len = ssl->acd.OutBuffers[ 0 ].cbBuffer;
656 |
657 | context->current_operation_write = IO_Write;
658 |
659 | int nRet = _WSASend( ssl->s, &context->wsabuf_write, 1, NULL, 0, &context->overlapped_write, NULL );
660 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
661 | {
662 | sent = false;
663 |
664 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
665 |
666 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
667 | SecInvalidateHandle( &ssl->hContext );
668 |
669 | ssl->acd.scRet = SEC_E_INTERNAL_ERROR;
670 | scRet = ssl->acd.scRet;
671 | }
672 | }
673 | }
674 |
675 | return scRet;
676 | }
677 |
678 | SECURITY_STATUS SSL_WSAConnect_Response( SOCKET_CONTEXT *context, bool &sent )
679 | {
680 | SECURITY_STATUS scRet = SEC_E_INTERNAL_ERROR;
681 |
682 | sent = false;
683 |
684 | if ( context != NULL && context->ssl != NULL )
685 | {
686 | SSL *ssl = context->ssl;
687 | WSABUF encrypted_buf;
688 |
689 | scRet = ssl->acd.scRet;
690 |
691 | // Free the output buffer from our SSL_WSAConnect.
692 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
693 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
694 |
695 | if ( scRet == SEC_I_CONTINUE_NEEDED || scRet == SEC_E_INCOMPLETE_MESSAGE || scRet == SEC_I_INCOMPLETE_CREDENTIALS )
696 | {
697 | // Server requested client authentication.
698 | if ( scRet == SEC_I_INCOMPLETE_CREDENTIALS )
699 | {
700 | // Go around again.
701 | ssl->acd.fDoRead = false;
702 | ssl->acd.scRet = SEC_I_CONTINUE_NEEDED;
703 |
704 | return ssl->acd.scRet;
705 | }
706 |
707 | if ( scRet == SEC_I_CONTINUE_NEEDED )
708 | {
709 | // Copy any leftover data from the buffer, and go around again.
710 | if ( ssl->acd.InBuffers[ 1 ].BufferType == SECBUFFER_EXTRA )
711 | {
712 | _memmove( ssl->pbIoBuffer, ssl->pbIoBuffer + ( ssl->cbIoBuffer - ssl->acd.InBuffers[ 1 ].cbBuffer ), ssl->acd.InBuffers[ 1 ].cbBuffer );
713 |
714 | ssl->cbIoBuffer = ssl->acd.InBuffers[ 1 ].cbBuffer;
715 | }
716 | else
717 | {
718 | ssl->cbIoBuffer = 0;
719 | }
720 | }
721 |
722 | // Read server data
723 | if ( ssl->cbIoBuffer == 0 || scRet == SEC_E_INCOMPLETE_MESSAGE )
724 | {
725 | if ( ssl->acd.fDoRead )
726 | {
727 | // If buffer not large enough reallocate buffer
728 | if ( ssl->sbIoBuffer <= ssl->cbIoBuffer )
729 | {
730 | ssl->sbIoBuffer += 2048;
731 |
732 | if ( ssl->pbIoBuffer == NULL )
733 | {
734 | ssl->pbIoBuffer = ( PUCHAR )GlobalAlloc( GPTR, ssl->sbIoBuffer );
735 | }
736 | else
737 | {
738 | ssl->pbIoBuffer = ( PUCHAR )GlobalReAlloc( ssl->pbIoBuffer, ssl->sbIoBuffer, GMEM_MOVEABLE );
739 | }
740 | }
741 |
742 | sent = true;
743 |
744 | encrypted_buf.buf = ( char * )ssl->pbIoBuffer + ssl->cbIoBuffer;
745 | encrypted_buf.len = ssl->sbIoBuffer - ssl->cbIoBuffer;
746 |
747 | DWORD dwFlags = 0;
748 |
749 | int nRet = _WSARecv( ssl->s, &encrypted_buf, 1, NULL, &dwFlags, &context->overlapped_read, NULL );
750 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
751 | {
752 | sent = false;
753 |
754 | if ( ssl->pbIoBuffer != NULL )
755 | {
756 | GlobalFree( ssl->pbIoBuffer );
757 | ssl->pbIoBuffer = NULL;
758 | }
759 |
760 | ssl->sbIoBuffer = 0;
761 |
762 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
763 | SecInvalidateHandle( &ssl->hContext );
764 |
765 | return SEC_E_INTERNAL_ERROR;
766 | }
767 |
768 | // UPDATED AFTER COMPLETION IN THE REPLY CASE
769 | //ssl->cbIoBuffer += cbData;
770 | }
771 | else
772 | {
773 | ssl->acd.fDoRead = true;
774 | }
775 | }
776 | else
777 | {
778 | sent = true;
779 |
780 | // Do not post the ssl->cbIoBuffer size.
781 | PostQueuedCompletionStatus( g_hIOCP, 0, ( ULONG_PTR )context, &context->overlapped_read );
782 | }
783 | }
784 | else if ( scRet == SEC_E_OK ) // Handshake completed successfully.
785 | {
786 | // Store remaining data for further use
787 | if ( ssl->acd.InBuffers[ 1 ].BufferType == SECBUFFER_EXTRA )
788 | {
789 | _memmove( ssl->pbIoBuffer, ssl->pbIoBuffer + ( ssl->cbIoBuffer - ssl->acd.InBuffers[ 1 ].cbBuffer ), ssl->acd.InBuffers[ 1 ].cbBuffer );
790 | ssl->cbIoBuffer = ssl->acd.InBuffers[ 1 ].cbBuffer;
791 | }
792 | else
793 | {
794 | ssl->cbIoBuffer = 0;
795 |
796 | if ( ssl->pbIoBuffer != NULL )
797 | {
798 | GlobalFree( ssl->pbIoBuffer );
799 | ssl->pbIoBuffer = NULL;
800 | }
801 |
802 | ssl->sbIoBuffer = 0;
803 | }
804 | }
805 | else if ( FAILED( scRet ) ) // Check for fatal error.
806 | {
807 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
808 | SecInvalidateHandle( &ssl->hContext );
809 | }
810 | }
811 |
812 | // We've completed everything above. Return our final status.
813 | return scRet;
814 | }
815 |
816 | SECURITY_STATUS SSL_WSAConnect_Reply( SOCKET_CONTEXT *context, bool &sent )
817 | {
818 | SECURITY_STATUS scRet = SEC_E_INTERNAL_ERROR;
819 |
820 | sent = false;
821 |
822 | if ( context != NULL && context->ssl != NULL )
823 | {
824 | SSL *ssl = context->ssl;
825 |
826 | SecBufferDesc InBuffer;
827 | SecBufferDesc OutBuffer;
828 | DWORD dwSSPIFlags;
829 | DWORD dwSSPIOutFlags;
830 | TimeStamp tsExpiry;
831 |
832 | scRet = ssl->acd.scRet;
833 |
834 | dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT |
835 | ISC_REQ_REPLAY_DETECT |
836 | ISC_REQ_CONFIDENTIALITY |
837 | ISC_RET_EXTENDED_ERROR |
838 | ISC_REQ_ALLOCATE_MEMORY |
839 | ISC_REQ_STREAM;
840 |
841 |
842 | if ( scRet == SEC_I_CONTINUE_NEEDED || scRet == SEC_E_INCOMPLETE_MESSAGE || scRet == SEC_I_INCOMPLETE_CREDENTIALS )
843 | {
844 | // Set up the input buffers. Buffer 0 is used to pass in data
845 | // received from the server. Schannel will consume some or all
846 | // of this. Leftover data (if any) will be placed in buffer 1 and
847 | // given a buffer type of SECBUFFER_EXTRA.
848 |
849 | ssl->acd.InBuffers[ 0 ].pvBuffer = ssl->pbIoBuffer;
850 | ssl->acd.InBuffers[ 0 ].cbBuffer = ssl->cbIoBuffer;
851 | ssl->acd.InBuffers[ 0 ].BufferType = SECBUFFER_TOKEN;
852 |
853 | ssl->acd.InBuffers[ 1 ].pvBuffer = NULL;
854 | ssl->acd.InBuffers[ 1 ].cbBuffer = 0;
855 | ssl->acd.InBuffers[ 1 ].BufferType = SECBUFFER_EMPTY;
856 |
857 | InBuffer.cBuffers = 2;
858 | InBuffer.pBuffers = ssl->acd.InBuffers;
859 | InBuffer.ulVersion = SECBUFFER_VERSION;
860 |
861 | // Set up the output buffers. These are initialized to NULL
862 | // so as to make it less likely we'll attempt to free random
863 | // garbage later.
864 |
865 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
866 | ssl->acd.OutBuffers[ 0 ].BufferType= SECBUFFER_TOKEN;
867 | ssl->acd.OutBuffers[ 0 ].cbBuffer = 0;
868 |
869 | OutBuffer.cBuffers = 1;
870 | OutBuffer.pBuffers = ssl->acd.OutBuffers;
871 | OutBuffer.ulVersion = SECBUFFER_VERSION;
872 |
873 | ssl->acd.scRet = g_pSSPI->InitializeSecurityContextA(
874 | &g_hCreds_client,
875 | &ssl->hContext,
876 | NULL,
877 | dwSSPIFlags,
878 | 0,
879 | SECURITY_NATIVE_DREP,
880 | &InBuffer,
881 | 0,
882 | NULL,
883 | &OutBuffer,
884 | &dwSSPIOutFlags,
885 | &tsExpiry );
886 |
887 | scRet = ssl->acd.scRet;
888 |
889 | // If success (or if the error was one of the special extended ones), send the contents of the output buffer to the server.
890 | if ( scRet == SEC_E_OK || scRet == SEC_I_CONTINUE_NEEDED || FAILED( scRet ) && ( dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR ) )
891 | {
892 | if ( ssl->acd.OutBuffers[ 0 ].cbBuffer != 0 && ssl->acd.OutBuffers[ 0 ].pvBuffer != NULL )
893 | {
894 | sent = true;
895 |
896 | context->wsabuf_write.buf = ( char * )ssl->acd.OutBuffers[ 0 ].pvBuffer;
897 | context->wsabuf_write.len = ssl->acd.OutBuffers[ 0 ].cbBuffer;
898 |
899 | context->current_operation_write = IO_Write;
900 |
901 | int nRet = _WSASend( ssl->s, &context->wsabuf_write, 1, NULL, 0, &context->overlapped_write, NULL );
902 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
903 | {
904 | sent = false;
905 |
906 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
907 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
908 |
909 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
910 | SecInvalidateHandle( &ssl->hContext );
911 |
912 | return SEC_E_INTERNAL_ERROR;
913 | }
914 |
915 | // Freed in SSL_WSAConnect_Response (assuming we get a response).
916 | //g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
917 | //ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
918 |
919 | return SEC_I_CONTINUE_NEEDED;
920 | }
921 | else if ( scRet == SEC_I_CONTINUE_NEEDED || scRet == SEC_E_INCOMPLETE_MESSAGE ) // Request more data until we get something.
922 | {
923 | if ( ssl->acd.OutBuffers[ 0 ].pvBuffer != NULL )
924 | {
925 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
926 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
927 | }
928 |
929 | sent = true;
930 |
931 | PostQueuedCompletionStatus( g_hIOCP, 0, ( ULONG_PTR )context, &context->overlapped_read );
932 |
933 | return scRet;
934 | }
935 | else if ( scRet == SEC_E_OK )
936 | {
937 | // Store remaining data for further use
938 | if ( ssl->acd.InBuffers[ 1 ].BufferType == SECBUFFER_EXTRA )
939 | {
940 | _memmove( ssl->pbIoBuffer, ssl->pbIoBuffer + ( ssl->cbIoBuffer - ssl->acd.InBuffers[ 1 ].cbBuffer ), ssl->acd.InBuffers[ 1 ].cbBuffer );
941 | ssl->cbIoBuffer = ssl->acd.InBuffers[ 1 ].cbBuffer;
942 | }
943 | else
944 | {
945 | ssl->cbIoBuffer = 0;
946 |
947 | if ( ssl->pbIoBuffer != NULL )
948 | {
949 | GlobalFree( ssl->pbIoBuffer );
950 | ssl->pbIoBuffer = NULL;
951 | }
952 |
953 | ssl->sbIoBuffer = 0;
954 | }
955 |
956 | if ( ssl->acd.OutBuffers[ 0 ].pvBuffer != NULL )
957 | {
958 | g_pSSPI->FreeContextBuffer( ssl->acd.OutBuffers[ 0 ].pvBuffer );
959 | ssl->acd.OutBuffers[ 0 ].pvBuffer = NULL;
960 | }
961 | }
962 | }
963 | }
964 | }
965 |
966 | return scRet;
967 | }
968 |
969 | SECURITY_STATUS SSL_WSAShutdown( SOCKET_CONTEXT *context, bool &sent )
970 | {
971 | SECURITY_STATUS scRet = SEC_E_INTERNAL_ERROR;
972 |
973 | sent = false;
974 |
975 | if ( context != NULL && context->ssl != NULL )
976 | {
977 | SSL *ssl = context->ssl;
978 | DWORD dwType;
979 |
980 | DWORD dwSSPIFlags;
981 | DWORD dwSSPIOutFlags;
982 | TimeStamp tsExpiry;
983 |
984 | SecBufferDesc OutBuffer;
985 |
986 | if ( ssl == NULL )
987 | {
988 | return SOCKET_ERROR;
989 | }
990 |
991 | dwType = SCHANNEL_SHUTDOWN;
992 |
993 | ssl->sdd.OutBuffers[ 0 ].pvBuffer = &dwType; // NEVER MAKE THIS NULL. System will break and restart.
994 | ssl->sdd.OutBuffers[ 0 ].BufferType = SECBUFFER_TOKEN;
995 | ssl->sdd.OutBuffers[ 0 ].cbBuffer = sizeof( dwType );
996 |
997 | OutBuffer.cBuffers = 1;
998 | OutBuffer.pBuffers = ssl->sdd.OutBuffers;
999 | OutBuffer.ulVersion = SECBUFFER_VERSION;
1000 |
1001 | scRet = g_pSSPI->ApplyControlToken( &ssl->hContext, &OutBuffer );
1002 | if ( FAILED( scRet ) )
1003 | {
1004 | ssl->sdd.OutBuffers[ 0 ].pvBuffer = NULL;
1005 |
1006 | return scRet;
1007 | }
1008 |
1009 | // Build an SSL close notify message.
1010 |
1011 | ssl->sdd.OutBuffers[ 0 ].pvBuffer = NULL;
1012 | ssl->sdd.OutBuffers[ 0 ].BufferType = SECBUFFER_TOKEN;
1013 | ssl->sdd.OutBuffers[ 0 ].cbBuffer = 0;
1014 |
1015 | OutBuffer.cBuffers = 1;
1016 | OutBuffer.pBuffers = ssl->sdd.OutBuffers;
1017 | OutBuffer.ulVersion = SECBUFFER_VERSION;
1018 |
1019 | dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT |
1020 | ASC_REQ_REPLAY_DETECT |
1021 | ASC_REQ_CONFIDENTIALITY |
1022 | ASC_REQ_EXTENDED_ERROR |
1023 | ASC_REQ_ALLOCATE_MEMORY |
1024 | ASC_REQ_STREAM;
1025 |
1026 | scRet = g_pSSPI->AcceptSecurityContext(
1027 | ( context->context_type == CONTEXT_TYPE_SERVER ? &g_hCreds_server : &g_hCreds_client ),
1028 | &ssl->hContext,
1029 | NULL,
1030 | dwSSPIFlags,
1031 | SECURITY_NATIVE_DREP,
1032 | NULL,
1033 | &OutBuffer,
1034 | &dwSSPIOutFlags,
1035 | &tsExpiry );
1036 |
1037 | if ( FAILED( scRet ) )
1038 | {
1039 | if ( ssl->sdd.OutBuffers[ 0 ].pvBuffer != NULL )
1040 | {
1041 | g_pSSPI->FreeContextBuffer( ssl->sdd.OutBuffers[ 0 ].pvBuffer );
1042 | ssl->sdd.OutBuffers[ 0 ].pvBuffer = NULL;
1043 | }
1044 |
1045 | return scRet;
1046 | }
1047 |
1048 | // Send the close notify message to the server.
1049 | if ( ssl->sdd.OutBuffers[ 0 ].pvBuffer != NULL && ssl->sdd.OutBuffers[ 0 ].cbBuffer != 0 )
1050 | {
1051 | sent = true;
1052 |
1053 | context->wsabuf_write.buf = ( char * )ssl->sdd.OutBuffers[ 0 ].pvBuffer;
1054 | context->wsabuf_write.len = ssl->sdd.OutBuffers[ 0 ].cbBuffer;
1055 |
1056 | context->current_operation_write = IO_Write;
1057 |
1058 | int nRet = _WSASend( ssl->s, &context->wsabuf_write, 1, NULL, 0, &context->overlapped_write, NULL );
1059 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
1060 | {
1061 | sent = false;
1062 | g_pSSPI->FreeContextBuffer( ssl->sdd.OutBuffers[ 0 ].pvBuffer );
1063 | ssl->sdd.OutBuffers[ 0 ].pvBuffer = NULL;
1064 |
1065 | scRet = SEC_E_INTERNAL_ERROR;
1066 | }
1067 | /*else // Freed in SSL_free.
1068 | {
1069 | g_pSSPI->FreeContextBuffer( ssl->sdd.OutBuffers[ 0 ].pvBuffer );
1070 | ssl->sdd.OutBuffers[ 0 ].pvBuffer = NULL;
1071 | }*/
1072 | }
1073 |
1074 | // Freed in SSL_free.
1075 | // Free the security context.
1076 | //g_pSSPI->DeleteSecurityContext( &ssl->hContext );
1077 | //SecInvalidateHandle( &ssl->hContext );
1078 | }
1079 |
1080 | return scRet;
1081 | }
1082 |
1083 | SECURITY_STATUS SSL_WSASend( SOCKET_CONTEXT *context, WSABUF *send_buf, bool &sent )
1084 | {
1085 | SECURITY_STATUS scRet = SEC_E_INTERNAL_ERROR;
1086 |
1087 | sent = false;
1088 |
1089 | if ( context != NULL && context->ssl != NULL )
1090 | {
1091 | SSL *ssl = context->ssl;
1092 | SecBuffer Buffers[ 4 ];
1093 | DWORD cbMessage;
1094 | SecBufferDesc Message;
1095 |
1096 | // ssl->sd.pbDataBuffer is freed when we clean up the connection.
1097 | if ( ssl->sd.pbDataBuffer == NULL )
1098 | {
1099 | scRet = g_pSSPI->QueryContextAttributesA( &ssl->hContext, SECPKG_ATTR_STREAM_SIZES, &ssl->sd.Sizes );
1100 | if ( scRet != SEC_E_OK )
1101 | {
1102 | return scRet;
1103 | }
1104 |
1105 | // The size includes the SSL header, max message length (16 KB), and SSL trailer.
1106 | ssl->sd.pbDataBuffer = ( PUCHAR )GlobalAlloc( GPTR, ( ssl->sd.Sizes.cbHeader + ssl->sd.Sizes.cbMaximumMessage + ssl->sd.Sizes.cbTrailer ) );
1107 | }
1108 |
1109 | // Copy our message to the buffer. Truncate the message if it's larger than the maximum allowed size (16 KB).
1110 | cbMessage = min( ssl->sd.Sizes.cbMaximumMessage, ( DWORD )send_buf->len );
1111 | _memcpy_s( ssl->sd.pbDataBuffer + ssl->sd.Sizes.cbHeader, ssl->sd.Sizes.cbMaximumMessage, send_buf->buf, cbMessage );
1112 |
1113 | send_buf->len -= cbMessage;
1114 | send_buf->buf += cbMessage;
1115 |
1116 | // Header location. (Beginning of the data buffer).
1117 | Buffers[ 0 ].pvBuffer = ssl->sd.pbDataBuffer;
1118 | Buffers[ 0 ].cbBuffer = ssl->sd.Sizes.cbHeader;
1119 | Buffers[ 0 ].BufferType = SECBUFFER_STREAM_HEADER;
1120 |
1121 | // Message location. (After the header).
1122 | Buffers[ 1 ].pvBuffer = ssl->sd.pbDataBuffer + ssl->sd.Sizes.cbHeader;
1123 | Buffers[ 1 ].cbBuffer = cbMessage;
1124 | Buffers[ 1 ].BufferType = SECBUFFER_DATA;
1125 |
1126 | // Trailer location. (After the message).
1127 | Buffers[ 2 ].pvBuffer = ssl->sd.pbDataBuffer + ssl->sd.Sizes.cbHeader + cbMessage;
1128 | Buffers[ 2 ].cbBuffer = ssl->sd.Sizes.cbTrailer;
1129 | Buffers[ 2 ].BufferType = SECBUFFER_STREAM_TRAILER;
1130 |
1131 | Buffers[ 3 ].BufferType = SECBUFFER_EMPTY;
1132 |
1133 | Message.ulVersion = SECBUFFER_VERSION;
1134 | Message.cBuffers = 4;
1135 | Message.pBuffers = Buffers;
1136 |
1137 | if ( g_pSSPI->EncryptMessage != NULL )
1138 | {
1139 | scRet = g_pSSPI->EncryptMessage( &ssl->hContext, 0, &Message, 0 );
1140 | }
1141 | else
1142 | {
1143 | scRet = ( ( ENCRYPT_MESSAGE_FN )g_pSSPI->Reserved3 )( &ssl->hContext, 0, &Message, 0 );
1144 | }
1145 |
1146 | if ( FAILED( scRet ) )
1147 | {
1148 | return scRet;
1149 | }
1150 |
1151 | sent = true;
1152 |
1153 | context->wsabuf_write.buf = ( char * )ssl->sd.pbDataBuffer;
1154 | context->wsabuf_write.len = Buffers[ 0 ].cbBuffer + Buffers[ 1 ].cbBuffer + Buffers[ 2 ].cbBuffer; // Calculate encrypted packet size
1155 |
1156 | context->current_operation_write = IO_Write;
1157 |
1158 | int nRet = _WSASend( ssl->s, &context->wsabuf_write, 1, NULL, 0, &context->overlapped_write, NULL );
1159 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
1160 | {
1161 | sent = false;
1162 |
1163 | g_pSSPI->DeleteSecurityContext( &ssl->hContext );
1164 | SecInvalidateHandle( &ssl->hContext );
1165 |
1166 | scRet = SEC_E_INTERNAL_ERROR;
1167 | }
1168 | }
1169 |
1170 | return scRet;
1171 | }
1172 |
1173 |
1174 | SECURITY_STATUS SSL_WSARecv( SOCKET_CONTEXT *context, bool &sent )
1175 | {
1176 | sent = false;
1177 |
1178 | if ( context != NULL && context->ssl != NULL )
1179 | {
1180 | SSL *ssl = context->ssl;
1181 | DWORD dwFlags = 0;
1182 | WSABUF encrypted_buf;
1183 | int nRet = 0;
1184 |
1185 | if ( ssl->cbIoBuffer == 0 || ssl->rd.scRet == SEC_E_INCOMPLETE_MESSAGE )
1186 | {
1187 | if ( ssl->sbIoBuffer <= ssl->cbIoBuffer )
1188 | {
1189 | ssl->sbIoBuffer += 2048;
1190 |
1191 | if ( ssl->pbIoBuffer == NULL )
1192 | {
1193 | ssl->pbIoBuffer = ( PUCHAR )GlobalAlloc( GPTR, ssl->sbIoBuffer );
1194 | }
1195 | else
1196 | {
1197 | ssl->pbIoBuffer = ( PUCHAR )GlobalReAlloc( ssl->pbIoBuffer, ssl->sbIoBuffer, GMEM_MOVEABLE );
1198 | }
1199 | }
1200 |
1201 | sent = true;
1202 |
1203 | encrypted_buf.buf = ( char * )ssl->pbIoBuffer + ssl->cbIoBuffer;
1204 | encrypted_buf.len = ssl->sbIoBuffer - ssl->cbIoBuffer;
1205 |
1206 | nRet = _WSARecv( ssl->s, &encrypted_buf, 1, NULL, &dwFlags, &context->overlapped_read, NULL );
1207 | if ( nRet == SOCKET_ERROR && ( _WSAGetLastError() != ERROR_IO_PENDING ) )
1208 | {
1209 | sent = false;
1210 | ssl->rd.scRet = SEC_E_INTERNAL_ERROR;
1211 |
1212 | return ssl->rd.scRet;
1213 | }
1214 |
1215 | return SEC_E_OK;
1216 | }
1217 |
1218 | return ssl->rd.scRet;
1219 | }
1220 | else
1221 | {
1222 | return SEC_E_INTERNAL_ERROR;
1223 | }
1224 | }
1225 |
1226 | SECURITY_STATUS SSL_WSARecv_Decrypt( SSL *ssl, LPWSABUF lpBuffers, DWORD &lpNumberOfBytesDecrypted )
1227 | {
1228 | lpNumberOfBytesDecrypted = 0;
1229 | SecBufferDesc Message;
1230 | SecBuffer *pDataBuffer;
1231 | SecBuffer *pExtraBuffer;
1232 |
1233 | if ( ssl == NULL )
1234 | {
1235 | return -1;
1236 | }
1237 |
1238 | if ( ssl->rd.scRet == SEC_I_CONTINUE_NEEDED )
1239 | {
1240 | // Handle any remaining data that was already decoded.
1241 | if ( lpBuffers->buf != NULL && lpBuffers->len > 0 && ssl->cbRecDataBuf > 0 )
1242 | {
1243 | lpNumberOfBytesDecrypted = min( ( DWORD )lpBuffers->len, ssl->cbRecDataBuf );
1244 | _memcpy_s( lpBuffers->buf, lpBuffers->len, ssl->pbRecDataBuf, lpNumberOfBytesDecrypted );
1245 |
1246 | DWORD rbytes = ssl->cbRecDataBuf - lpNumberOfBytesDecrypted;
1247 | if ( rbytes > 0 )
1248 | {
1249 | _memmove( ssl->pbRecDataBuf, ( ( char * )ssl->pbRecDataBuf ) + lpNumberOfBytesDecrypted, rbytes );
1250 | }
1251 | else
1252 | {
1253 | ssl->rd.scRet = SEC_E_OK;
1254 | }
1255 | ssl->cbRecDataBuf = rbytes;
1256 | }
1257 |
1258 | return ssl->rd.scRet;
1259 | }
1260 |
1261 | _memzero( ssl->rd.Buffers, sizeof( SecBuffer ) * 4 );
1262 |
1263 | //ssl->cbIoBuffer = lpBuffers->len;
1264 |
1265 | // Attempt to decrypt the received data.
1266 | ssl->rd.Buffers[ 0 ].pvBuffer = ssl->pbIoBuffer;
1267 | ssl->rd.Buffers[ 0 ].cbBuffer = ssl->cbIoBuffer;
1268 | ssl->rd.Buffers[ 0 ].BufferType = SECBUFFER_DATA;
1269 |
1270 | ssl->rd.Buffers[ 1 ].BufferType = SECBUFFER_EMPTY;
1271 | ssl->rd.Buffers[ 2 ].BufferType = SECBUFFER_EMPTY;
1272 | ssl->rd.Buffers[ 3 ].BufferType = SECBUFFER_EMPTY;
1273 |
1274 | Message.ulVersion = SECBUFFER_VERSION;
1275 | Message.cBuffers = 4;
1276 | Message.pBuffers = ssl->rd.Buffers;
1277 |
1278 | if ( g_pSSPI->DecryptMessage != NULL )
1279 | {
1280 | ssl->rd.scRet = g_pSSPI->DecryptMessage( &ssl->hContext, &Message, 0, NULL );
1281 | }
1282 | else
1283 | {
1284 | ssl->rd.scRet = ( ( DECRYPT_MESSAGE_FN )g_pSSPI->Reserved4 )( &ssl->hContext, &Message, 0, NULL );
1285 | }
1286 |
1287 | if ( ssl->rd.scRet == SEC_E_INCOMPLETE_MESSAGE )
1288 | {
1289 | // The input buffer contains only a fragment of an encrypted record. Need to read some more data.
1290 | return ssl->rd.scRet;
1291 | }
1292 |
1293 | // Sender has signaled end of session
1294 | if ( ssl->rd.scRet == SEC_I_CONTEXT_EXPIRED )
1295 | {
1296 | return ssl->rd.scRet;
1297 | }
1298 |
1299 | if ( ssl->rd.scRet != SEC_E_OK && ssl->rd.scRet != SEC_I_RENEGOTIATE )
1300 | {
1301 | return ssl->rd.scRet;
1302 | }
1303 |
1304 | // Locate data and (optional) extra buffers.
1305 | pDataBuffer = NULL;
1306 | pExtraBuffer = NULL;
1307 | for ( int i = 1; i < 4; i++ )
1308 | {
1309 | if ( pDataBuffer == NULL && ssl->rd.Buffers[ i ].BufferType == SECBUFFER_DATA )
1310 | {
1311 | pDataBuffer = &ssl->rd.Buffers[ i ];
1312 | }
1313 |
1314 | if ( pExtraBuffer == NULL && ssl->rd.Buffers[ i ].BufferType == SECBUFFER_EXTRA )
1315 | {
1316 | pExtraBuffer = &ssl->rd.Buffers[ i ];
1317 | }
1318 | }
1319 |
1320 | // Return decrypted data.
1321 | if ( pDataBuffer != NULL )
1322 | {
1323 | lpNumberOfBytesDecrypted = min( ( DWORD )lpBuffers->len, pDataBuffer->cbBuffer );
1324 | _memcpy_s( lpBuffers->buf, lpBuffers->len, pDataBuffer->pvBuffer, lpNumberOfBytesDecrypted );
1325 |
1326 | // Remaining bytes.
1327 | DWORD rbytes = pDataBuffer->cbBuffer - lpNumberOfBytesDecrypted;
1328 | if ( rbytes > 0 )
1329 | {
1330 | if ( ssl->sbRecDataBuf < rbytes )
1331 | {
1332 | ssl->sbRecDataBuf = rbytes;
1333 |
1334 | if ( ssl->pbRecDataBuf == NULL )
1335 | {
1336 | ssl->pbRecDataBuf = ( PUCHAR )GlobalAlloc( GPTR, ssl->sbRecDataBuf );
1337 | }
1338 | else
1339 | {
1340 | ssl->pbRecDataBuf = ( PUCHAR )GlobalReAlloc( ssl->pbRecDataBuf, ssl->sbRecDataBuf, GMEM_MOVEABLE );
1341 | }
1342 | }
1343 |
1344 | _memcpy_s( ssl->pbRecDataBuf, ssl->sbRecDataBuf, ( char * )pDataBuffer->pvBuffer + lpNumberOfBytesDecrypted, rbytes );
1345 | ssl->cbRecDataBuf = rbytes;
1346 |
1347 | ssl->rd.scRet = SEC_I_CONTINUE_NEEDED;
1348 | }
1349 | }
1350 |
1351 | // Move any extra data to the input buffer.
1352 | if ( pExtraBuffer != NULL )
1353 | {
1354 | _memmove( ssl->pbIoBuffer, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer );
1355 | ssl->cbIoBuffer = pExtraBuffer->cbBuffer;
1356 | }
1357 | else
1358 | {
1359 | ssl->cbIoBuffer = 0;
1360 | }
1361 |
1362 | /*if ( pDataBuffer != NULL && lpNumberOfBytesDecrypted != 0 )
1363 | {
1364 | return ssl->rd.scRet;
1365 | }
1366 |
1367 | if ( ssl->rd.scRet == SEC_I_RENEGOTIATE )
1368 | {
1369 | return ssl->rd.scRet;
1370 | }*/
1371 |
1372 | return ssl->rd.scRet;
1373 | }
1374 |
1375 | PCCERT_CONTEXT LoadPublicPrivateKeyPair( wchar_t *cer, wchar_t *key )
1376 | {
1377 | bool failed = false;
1378 | PCCERT_CONTEXT pCertContext = NULL;
1379 | HCRYPTPROV hProv = NULL;
1380 | HCRYPTKEY hKey = NULL;
1381 |
1382 |
1383 | HCERTSTORE hMyCertStore = NULL;
1384 | HCRYPTMSG hCryptMsg = NULL;
1385 |
1386 | DWORD dwMsgAndCertEncodingType = 0;
1387 | DWORD dwContentType = 0;
1388 | DWORD dwFormatType = 0;
1389 |
1390 | LPWSTR pwszUuid = NULL;
1391 |
1392 | LPBYTE pbBuffer = NULL, pbKeyBlob = NULL;
1393 | DWORD dwBufferLen = 0, cbKeyBlob = 0;
1394 | BYTE *szPemPrivKey = NULL;
1395 |
1396 | #ifndef RPCRT4_USE_STATIC_LIB
1397 | if ( rpcrt4_state == RPCRT4_STATE_SHUTDOWN )
1398 | {
1399 | if ( !InitializeRpcRt4() ){ return NULL; }
1400 | }
1401 | #endif
1402 |
1403 | //hMyCertStore = _CertOpenStore( CERT_STORE_PROV_FILENAME, 0, NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, cer );
1404 | //pCertContext = _CertFindCertificateInStore( hMyCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL );
1405 | _CryptQueryObject( CERT_QUERY_OBJECT_FILE, cer, CERT_QUERY_CONTENT_FLAG_CERT, CERT_QUERY_FORMAT_FLAG_ALL, 0, &dwMsgAndCertEncodingType, &dwContentType, &dwFormatType, &hMyCertStore, &hCryptMsg, ( const void ** )&pCertContext );
1406 |
1407 | HANDLE hFile_cfg = CreateFile( key, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
1408 | if ( hFile_cfg != INVALID_HANDLE_VALUE )
1409 | {
1410 | dwBufferLen = GetFileSize( hFile_cfg, NULL );
1411 |
1412 | szPemPrivKey = ( BYTE * )GlobalAlloc( GMEM_FIXED, sizeof( BYTE ) * dwBufferLen );
1413 |
1414 | ReadFile( hFile_cfg, szPemPrivKey, sizeof( char ) * dwBufferLen, &dwBufferLen, NULL );
1415 |
1416 | CloseHandle( hFile_cfg );
1417 |
1418 | // Let's assume the key is also in the same format.
1419 | if ( dwFormatType == CERT_QUERY_FORMAT_BASE64_ENCODED ) // PEM format.
1420 | {
1421 | if ( _CryptStringToBinaryA( ( LPCSTR )szPemPrivKey, 0, CRYPT_STRING_BASE64HEADER, NULL, &dwBufferLen, NULL, NULL ) == FALSE )
1422 | {
1423 | failed = true;
1424 | goto CLEANUP;
1425 | }
1426 |
1427 | pbBuffer = ( LPBYTE )GlobalAlloc( GMEM_FIXED, dwBufferLen );
1428 | if ( _CryptStringToBinaryA( ( LPCSTR )szPemPrivKey, 0, CRYPT_STRING_BASE64HEADER, pbBuffer, &dwBufferLen, NULL, NULL ) == FALSE )
1429 | {
1430 | failed = true;
1431 | goto CLEANUP;
1432 | }
1433 | }
1434 | else // DER format.
1435 | {
1436 | pbBuffer = szPemPrivKey;
1437 | szPemPrivKey = NULL;
1438 | }
1439 |
1440 | if ( _CryptDecodeObjectEx( dwMsgAndCertEncodingType, PKCS_RSA_PRIVATE_KEY, pbBuffer, dwBufferLen, 0, NULL, NULL, &cbKeyBlob ) == FALSE )
1441 | {
1442 | failed = true;
1443 | goto CLEANUP;
1444 | }
1445 |
1446 | pbKeyBlob = ( LPBYTE )GlobalAlloc( GMEM_FIXED, cbKeyBlob );
1447 | if ( _CryptDecodeObjectEx( dwMsgAndCertEncodingType, PKCS_RSA_PRIVATE_KEY, pbBuffer, dwBufferLen, 0, NULL, pbKeyBlob, &cbKeyBlob ) == FALSE )
1448 | {
1449 | failed = true;
1450 | goto CLEANUP;
1451 | }
1452 |
1453 | UUID uuid;
1454 | _UuidCreate( &uuid );
1455 | _UuidToStringW( &uuid, ( RPC_WSTR * )&pwszUuid );
1456 |
1457 | if ( _CryptAcquireContextW( &hProv, pwszUuid, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET ) == FALSE )
1458 | {
1459 | failed = true;
1460 | goto CLEANUP;
1461 | }
1462 |
1463 | if ( _CryptImportKey( hProv, pbKeyBlob, cbKeyBlob, NULL, 0, &hKey ) == FALSE )
1464 | {
1465 | failed = true;
1466 | goto CLEANUP;
1467 | }
1468 |
1469 | CRYPT_KEY_PROV_INFO privateKeyData;
1470 | _memzero( &privateKeyData, sizeof( CRYPT_KEY_PROV_INFO ) );
1471 | privateKeyData.pwszContainerName = pwszUuid;
1472 | privateKeyData.pwszProvName = MS_ENHANCED_PROV;
1473 | privateKeyData.dwProvType = PROV_RSA_FULL;
1474 | privateKeyData.dwFlags = 0;
1475 | privateKeyData.dwKeySpec = AT_KEYEXCHANGE;
1476 |
1477 | if ( _CertSetCertificateContextProperty( pCertContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &privateKeyData ) == FALSE )
1478 | {
1479 | failed = true;
1480 | goto CLEANUP;
1481 | }
1482 | }
1483 |
1484 | CLEANUP:
1485 |
1486 | if ( pwszUuid != NULL )
1487 | {
1488 | _RpcStringFreeW( ( RPC_WSTR * )&pwszUuid );
1489 | }
1490 |
1491 | if ( pbBuffer != NULL )
1492 | {
1493 | GlobalFree( pbBuffer );
1494 | }
1495 |
1496 | if ( szPemPrivKey != NULL )
1497 | {
1498 | GlobalFree( szPemPrivKey );
1499 | }
1500 |
1501 | if ( pbKeyBlob != NULL )
1502 | {
1503 | GlobalFree( pbKeyBlob );
1504 | }
1505 |
1506 | if ( hCryptMsg != NULL )
1507 | {
1508 | _CryptMsgClose( hCryptMsg );
1509 | }
1510 |
1511 | if ( hKey != NULL )
1512 | {
1513 | _CryptDestroyKey( hKey );
1514 | }
1515 | if ( hProv != NULL )
1516 | {
1517 | _CryptReleaseContext( hProv, 0 );
1518 | }
1519 |
1520 | if ( hMyCertStore != NULL )
1521 | {
1522 | _CertCloseStore( hMyCertStore, 0 );
1523 | }
1524 |
1525 | if ( failed && pCertContext != NULL )
1526 | {
1527 | _CertFreeCertificateContext( pCertContext );
1528 | pCertContext = NULL;
1529 | }
1530 |
1531 | return pCertContext;
1532 | }
1533 |
1534 | PCCERT_CONTEXT LoadPKCS12( wchar_t *p12_file, wchar_t *password )
1535 | {
1536 | PCCERT_CONTEXT pCertContext = NULL;
1537 |
1538 | HANDLE hFile_cfg = CreateFile( p12_file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
1539 | if ( hFile_cfg != INVALID_HANDLE_VALUE )
1540 | {
1541 | CRYPT_DATA_BLOB cdb;
1542 | DWORD read = 0, pos = 0;
1543 | DWORD fz = GetFileSize( hFile_cfg, NULL );
1544 |
1545 | cdb.cbData = fz;
1546 | cdb.pbData = ( BYTE * )GlobalAlloc( GMEM_FIXED, sizeof( BYTE ) * fz );
1547 |
1548 | ReadFile( hFile_cfg, cdb.pbData, sizeof( char ) * fz, &read, NULL );
1549 |
1550 | CloseHandle( hFile_cfg );
1551 |
1552 | HCERTSTORE hMyCertStore = _PFXImportCertStore( &cdb, password, 0 );
1553 |
1554 | GlobalFree( cdb.pbData );
1555 |
1556 | int err = GetLastError();
1557 | if ( hMyCertStore == NULL || err != 0 )
1558 | {
1559 | _CertCloseStore( hMyCertStore, 0 );
1560 |
1561 | return NULL;
1562 | }
1563 |
1564 | pCertContext = _CertFindCertificateInStore( hMyCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL );
1565 |
1566 | _CertCloseStore( hMyCertStore, 0 );
1567 | }
1568 |
1569 | return pCertContext;
1570 | }
1571 |
--------------------------------------------------------------------------------
/HTTP_Proxy/ssl.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _SCHANNEL_SSL_H
20 | #define _SCHANNEL_SSL_H
21 |
22 | #define STRICT
23 | #define WIN32_LEAN_AND_MEAN
24 | #include
25 |
26 | #define SECURITY_WIN32
27 | #include
28 | #include
29 |
30 | #include "lite_ws2_32.h"
31 |
32 | #define SSL_STATE_SHUTDOWN 0
33 | #define SSL_STATE_RUNNING 1
34 |
35 | #define SP_PROT_TLS1_1_SERVER 0x00000100
36 | #define SP_PROT_TLS1_1_CLIENT 0x00000200
37 | #define SP_PROT_TLS1_1 ( SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_1_CLIENT )
38 | #define SP_PROT_TLS1_2_SERVER 0x00000400
39 | #define SP_PROT_TLS1_2_CLIENT 0x00000800
40 | #define SP_PROT_TLS1_2 ( SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_2_CLIENT )
41 |
42 | /*struct ACCEPT_DATA
43 | {
44 | SecBuffer InBuffers[ 2 ];
45 | SecBuffer OutBuffers[ 1 ];
46 |
47 | SECURITY_STATUS scRet;
48 |
49 | bool fInitContext;
50 | bool fDoRead;
51 | };
52 |
53 | struct CONNECT_DATA
54 | {
55 | SecBuffer InBuffers[ 2 ];
56 | SecBuffer OutBuffers[ 1 ];
57 |
58 | SECURITY_STATUS scRet;
59 |
60 | bool fDoRead;
61 | };*/
62 |
63 | struct ACCEPT_CONNECT_DATA
64 | {
65 | SecBuffer InBuffers[ 2 ];
66 | SecBuffer OutBuffers[ 1 ];
67 |
68 | SECURITY_STATUS scRet;
69 |
70 | bool fInitContext;
71 | bool fDoRead;
72 | };
73 |
74 | struct RECV_DATA
75 | {
76 | SecBuffer Buffers[ 4 ];
77 |
78 | SECURITY_STATUS scRet;
79 | };
80 |
81 | struct SEND_DATA
82 | {
83 | SecPkgContext_StreamSizes Sizes;
84 |
85 | PUCHAR pbDataBuffer;
86 | };
87 |
88 | struct SHUTDOWN_DATA
89 | {
90 | SecBuffer OutBuffers[ 1 ];
91 | };
92 |
93 | struct SSL
94 | {
95 | SEND_DATA sd;
96 | ACCEPT_CONNECT_DATA acd;
97 | RECV_DATA rd;
98 | SHUTDOWN_DATA sdd;
99 |
100 | CtxtHandle hContext;
101 |
102 | BYTE *pbRecDataBuf;
103 | BYTE *pbIoBuffer;
104 |
105 | SOCKET s;
106 |
107 | //DWORD dwProtocol;
108 |
109 | DWORD cbRecDataBuf;
110 | DWORD sbRecDataBuf;
111 |
112 | DWORD cbIoBuffer;
113 | DWORD sbIoBuffer;
114 | };
115 |
116 | int SSL_library_init( void );
117 | int SSL_library_uninit( void );
118 |
119 | SSL *SSL_new( DWORD protocol, bool is_server );
120 | void SSL_free( SSL *ssl );
121 |
122 | PCCERT_CONTEXT LoadPublicPrivateKeyPair( wchar_t *cer, wchar_t *key );
123 | PCCERT_CONTEXT LoadPKCS12( wchar_t *p12_file, wchar_t *password );
124 |
125 | extern PCCERT_CONTEXT g_pCertContext;
126 |
127 | extern unsigned char ssl_state;
128 |
129 | #endif
130 |
--------------------------------------------------------------------------------
/HTTP_Proxy/utilities.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "utilities.h"
20 | #include "globals.h"
21 | #include "lite_ntdll.h"
22 | #include "lite_ws2_32.h"
23 | #include "lite_advapi32.h"
24 | #include "lite_crypt32.h"
25 | #include "lite_shell32.h"
26 |
27 | #include
28 |
29 | #define ROTATE_LEFT( x, n ) ( ( ( x ) << ( n ) ) | ( ( x ) >> ( 8 - ( n ) ) ) )
30 | #define ROTATE_RIGHT( x, n ) ( ( ( x ) >> ( n ) ) | ( ( x ) << ( 8 - ( n ) ) ) )
31 |
32 | void encode_cipher( char *buffer, int buffer_length )
33 | {
34 | int offset = buffer_length + 128;
35 | for ( int i = 0; i < buffer_length; ++i )
36 | {
37 | *buffer ^= ( unsigned char )buffer_length;
38 | *buffer = ( *buffer + offset ) % 256;
39 | *buffer = ROTATE_LEFT( ( unsigned char )*buffer, offset % 8 );
40 |
41 | buffer++;
42 | --offset;
43 | }
44 | }
45 |
46 | void decode_cipher( char *buffer, int buffer_length )
47 | {
48 | int offset = buffer_length + 128;
49 | for ( int i = buffer_length; i > 0; --i )
50 | {
51 | *buffer = ROTATE_RIGHT( ( unsigned char )*buffer, offset % 8 );
52 | *buffer = ( *buffer - offset ) % 256;
53 | *buffer ^= ( unsigned char )buffer_length;
54 |
55 | buffer++;
56 | --offset;
57 | }
58 | }
59 |
60 | // Must use GlobalFree on this.
61 | char *GlobalStrDupA( const char *_Str )
62 | {
63 | if ( _Str == NULL )
64 | {
65 | return NULL;
66 | }
67 |
68 | size_t size = lstrlenA( _Str ) + sizeof( char );
69 |
70 | char *ret = ( char * )GlobalAlloc( GMEM_FIXED, size );
71 |
72 | if ( ret == NULL )
73 | {
74 | return NULL;
75 | }
76 |
77 | _memcpy_s( ret, size, _Str, size );
78 |
79 | return ret;
80 | }
81 |
82 | void GetMD5String( HCRYPTHASH *hHash, char **md5, DWORD *md5_length )
83 | {
84 | DWORD cbHash = MD5_LENGTH;
85 | BYTE Hash[ MD5_LENGTH ];
86 |
87 | *md5 = NULL;
88 | *md5_length = 0;
89 |
90 | if ( _CryptGetHashParam( *hHash, HP_HASHVAL, Hash, &cbHash, 0 ) )
91 | {
92 | *md5_length = cbHash * 2;
93 | *md5 = ( char * )GlobalAlloc( GPTR, sizeof( char ) * ( *md5_length + 1 ) );
94 |
95 | CHAR digits[] = "0123456789abcdef";
96 | for ( DWORD i = 0; i < cbHash; ++i )
97 | {
98 | __snprintf( *md5 + ( 2 * i ), *md5_length - ( 2 * i ), "%c%c", digits[ Hash[ i ] >> 4 ], digits[ Hash[ i ] & 0xF ] );
99 | }
100 | *( *md5 + *md5_length ) = 0; // Sanity.
101 | }
102 | }
103 |
104 | void CreateDigestInfo( char **nonce, unsigned long &nonce_length, char **opaque, unsigned long &opaque_length )
105 | {
106 | char *HA1 = NULL;
107 |
108 | if ( *nonce != NULL )
109 | {
110 | GlobalFree( *nonce );
111 | *nonce = NULL;
112 | }
113 |
114 | nonce_length = 0;
115 |
116 | if ( *opaque != NULL )
117 | {
118 | GlobalFree( *opaque );
119 | *opaque = NULL;
120 | }
121 |
122 | opaque_length = 0;
123 |
124 | HCRYPTPROV hProv = NULL;
125 | if ( _CryptAcquireContextW( &hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) )
126 | {
127 | HCRYPTHASH hHash = NULL;
128 |
129 | BYTE rbuffer[ 16 ];
130 |
131 | if ( _CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash ) )
132 | {
133 | _CryptGenRandom( hProv, 16, ( BYTE * )&rbuffer );
134 |
135 | _CryptHashData( hHash, rbuffer, 16, 0 );
136 |
137 | GetMD5String( &hHash, nonce, &nonce_length );
138 | }
139 |
140 | if ( hHash != NULL )
141 | {
142 | _CryptDestroyHash( hHash );
143 | hHash = NULL;
144 | }
145 |
146 | if ( _CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash ) )
147 | {
148 | _CryptGenRandom( hProv, 16, ( BYTE * )&rbuffer );
149 |
150 | _CryptHashData( hHash, rbuffer, 16, 0 );
151 |
152 | GetMD5String( &hHash, opaque, &opaque_length );
153 | }
154 |
155 | if ( hHash != NULL )
156 | {
157 | _CryptDestroyHash( hHash );
158 | }
159 | }
160 |
161 | if ( hProv != NULL )
162 | {
163 | _CryptReleaseContext( hProv, 0 );
164 | }
165 |
166 | GlobalFree( HA1 );
167 | }
168 |
169 | void CreateBasicAuthentication( char *username, unsigned long username_length, char *password, unsigned long password_length, char **authentication, unsigned long &authentication_length )
170 | {
171 | int concatenated_offset = 0;
172 |
173 | if ( *authentication != NULL )
174 | {
175 | GlobalFree( *authentication );
176 | *authentication = NULL;
177 | }
178 |
179 | authentication_length = 0;
180 |
181 | // username:password
182 | int concatenated_authentication_length = username_length + 1 + password_length;
183 | char *concatenated_authentication = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * ( concatenated_authentication_length + 1 ) );
184 |
185 | if ( username != NULL )
186 | {
187 | _memcpy_s( concatenated_authentication, concatenated_authentication_length + 1, username, username_length );
188 | concatenated_offset += username_length;
189 | }
190 |
191 | concatenated_authentication[ concatenated_offset++ ] = ':';
192 |
193 | if ( password != NULL )
194 | {
195 | _memcpy_s( concatenated_authentication + concatenated_offset, ( concatenated_authentication_length + 1 ) - concatenated_offset, password, password_length );
196 | concatenated_offset += password_length;
197 | }
198 |
199 | concatenated_authentication[ concatenated_offset ] = 0; // Sanity.
200 |
201 | _CryptBinaryToStringA( ( BYTE * )concatenated_authentication, concatenated_authentication_length, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &authentication_length );
202 |
203 | *authentication = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * authentication_length );
204 | _CryptBinaryToStringA( ( BYTE * )concatenated_authentication, concatenated_authentication_length, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, ( LPSTR )( *authentication ), &authentication_length );
205 | *( ( *authentication ) + authentication_length ) = 0; // Sanity.
206 |
207 | GlobalFree( concatenated_authentication );
208 | }
209 |
210 | bool VerifyBasicAuthorization( char *encoded_credentials, unsigned long encoded_credientials_length, AUTH_INFO *auth_info )
211 | {
212 | // See if the keys match.
213 | if ( ( auth_info->basic_encode_end - auth_info->basic_encode ) == encoded_credientials_length &&
214 | encoded_credentials != NULL &&
215 | _memcmp( auth_info->basic_encode, encoded_credentials, encoded_credientials_length ) == 0 )
216 | {
217 | return true;
218 | }
219 |
220 | return false;
221 | }
222 |
223 | bool VerifyDigestAuthorization( char *username, unsigned long username_length, char *password, unsigned long password_length, char *nonce, unsigned long nonce_length, char *opaque, unsigned long opaque_length, char *method, unsigned long method_length, AUTH_INFO *auth_info )
224 | {
225 | bool ret = false;
226 |
227 | char *HA1 = NULL;
228 | DWORD HA1_length = 0;
229 |
230 | char *HA2 = NULL;
231 | DWORD HA2_length = 0;
232 |
233 | char *response = NULL;
234 | DWORD response_length = 0;
235 |
236 | int cnonce_length = ( auth_info->cnonce_end - auth_info->cnonce );
237 | int realm_length = ( auth_info->realm_end - auth_info->realm );
238 | int uri_length = ( auth_info->uri_end - auth_info->uri );
239 | int qop_length = ( auth_info->qop_end - auth_info->qop );
240 |
241 | // We can verify realm, nonce, and opaque to ensure the client responded correctly.
242 | if ( ( auth_info->realm_end - auth_info->realm ) != 29 || _memcmp( auth_info->realm, "Proxy Authentication Required", 29 != 0 ) )
243 | {
244 | return false;
245 | }
246 |
247 | if ( ( auth_info->nonce_end - auth_info->nonce ) != nonce_length || _memcmp( auth_info->nonce, nonce, nonce_length ) != 0 )
248 | {
249 | return false;
250 | }
251 |
252 | if ( ( auth_info->opaque_end - auth_info->opaque ) != opaque_length || _memcmp( auth_info->opaque, opaque, opaque_length ) != 0 )
253 | {
254 | return false;
255 | }
256 |
257 | HCRYPTPROV hProv = NULL;
258 | if ( _CryptAcquireContextW( &hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) )
259 | {
260 | HCRYPTHASH hHash = NULL;
261 |
262 | // If auth_info->algorithm is not set, then assume it's MD5.
263 |
264 | // Create HA1.
265 | if ( _CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash ) )
266 | {
267 | _CryptHashData( hHash, ( BYTE * )username, username_length, 0 );
268 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
269 | _CryptHashData( hHash, ( BYTE * )auth_info->realm, realm_length, 0 );
270 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
271 | _CryptHashData( hHash, ( BYTE * )password, password_length, 0 );
272 |
273 | GetMD5String( &hHash, &HA1, &HA1_length );
274 |
275 | // MD5-sess
276 | if ( auth_info->algorithm == 2 )
277 | {
278 | if ( hHash != NULL )
279 | {
280 | _CryptDestroyHash( hHash );
281 | hHash = NULL;
282 | }
283 |
284 | if ( _CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash ) )
285 | {
286 | _CryptHashData( hHash, ( BYTE * )HA1, HA1_length, 0 );
287 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
288 | _CryptHashData( hHash, ( BYTE * )nonce, nonce_length, 0 );
289 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
290 | _CryptHashData( hHash, ( BYTE * )auth_info->cnonce, cnonce_length, 0 );
291 |
292 | GlobalFree( HA1 );
293 | HA1 = NULL;
294 | HA1_length = 0;
295 |
296 | GetMD5String( &hHash, &HA1, &HA1_length );
297 | }
298 | }
299 | }
300 |
301 | if ( hHash != NULL )
302 | {
303 | _CryptDestroyHash( hHash );
304 | hHash = NULL;
305 | }
306 |
307 | // Create HA2.
308 | if ( _CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash ) )
309 | {
310 | _CryptHashData( hHash, ( BYTE * )method, method_length, 0 );
311 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
312 | _CryptHashData( hHash, ( BYTE * )auth_info->uri, uri_length, 0 );
313 |
314 | // auth-int
315 | // We're not supporting this.
316 | // We'd have to stream in the HTTP payload body and who knows how large that could be. Forget it!
317 | if ( auth_info->qop_type == 2 )
318 | {
319 | char *entity_body = NULL;
320 | int entity_body_length = 0;
321 |
322 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
323 | _CryptHashData( hHash, ( BYTE * )entity_body, entity_body_length, 0 );
324 | }
325 |
326 | GetMD5String( &hHash, &HA2, &HA2_length );
327 | }
328 |
329 | if ( hHash != NULL )
330 | {
331 | _CryptDestroyHash( hHash );
332 | hHash = NULL;
333 | }
334 |
335 | // Create response.
336 | if ( _CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash ) )
337 | {
338 | _CryptHashData( hHash, ( BYTE * )HA1, HA1_length, 0 );
339 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
340 | _CryptHashData( hHash, ( BYTE * )nonce, nonce_length, 0 );
341 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
342 |
343 | if ( auth_info->qop_type != 0 )
344 | {
345 | char ncount[ 9 ];
346 | __snprintf( ncount, 9, "%08x", auth_info->nc ); // Hex must be lowercase.
347 |
348 | _CryptHashData( hHash, ( BYTE * )ncount, 8, 0 );
349 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
350 | _CryptHashData( hHash, ( BYTE * )auth_info->cnonce, cnonce_length, 0 );
351 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
352 | _CryptHashData( hHash, ( BYTE * )auth_info->qop, qop_length, 0 );
353 | _CryptHashData( hHash, ( BYTE * )":", 1, 0 );
354 | }
355 |
356 | _CryptHashData( hHash, ( BYTE * )HA2, HA2_length, 0 );
357 |
358 | GetMD5String( &hHash, &response, &response_length );
359 | }
360 |
361 | if ( hHash != NULL )
362 | {
363 | _CryptDestroyHash( hHash );
364 | hHash = NULL;
365 | }
366 | }
367 |
368 | if ( hProv != NULL )
369 | {
370 | _CryptReleaseContext( hProv, 0 );
371 | }
372 |
373 | GlobalFree( HA1 );
374 | GlobalFree( HA2 );
375 |
376 | if ( response != NULL )
377 | {
378 | if ( response_length == ( auth_info->response_end - auth_info->response ) && _StrCmpNA( response, auth_info->response, response_length ) == 0 )
379 | {
380 | ret = true;
381 | }
382 |
383 | GlobalFree( response );
384 | }
385 |
386 | return ret;
387 | }
388 |
389 | // Default is base 10.
390 | unsigned long long strtoull( char *str, bool base16 )
391 | {
392 | if ( str == NULL )
393 | {
394 | return 0;
395 | }
396 |
397 | char *p = str;
398 |
399 | ULARGE_INTEGER uli;
400 | uli.QuadPart = 0;
401 |
402 | unsigned char digit = 0;
403 |
404 | if ( !base16 )
405 | {
406 | while ( *p && ( *p >= '0' && *p <= '9' ) )
407 | {
408 | if ( uli.QuadPart > ( ULLONG_MAX / 10 ) )
409 | {
410 | uli.QuadPart = ULLONG_MAX;
411 | break;
412 | }
413 |
414 | uli.QuadPart *= 10;
415 |
416 | /*__asm
417 | {
418 | mov eax, dword ptr [ uli.QuadPart + 4 ]
419 | cmp eax, 0 ;// See if our QuadPart's value extends to 64 bits.
420 | mov ecx, 10 ;// Store the base (10) multiplier (low order bits).
421 | jne short hard10 ;// If there are high order bits in QuadPart, then multiply/add high and low bits.
422 |
423 | mov eax, dword ptr [ uli.QuadPart + 0 ] ;// Store the QuadPart's low order bits.
424 | mul ecx ;// Multiply the low order bits.
425 |
426 | jmp finish10 ;// Store the results in our 64 bit value.
427 |
428 | hard10:
429 |
430 | push ebx ;// Save value to stack.
431 |
432 | mul ecx ;// Multiply the high order bits of QuadPart with the low order bits of base (10).
433 | mov ebx, eax ;// Store the result.
434 |
435 | mov eax, dword ptr [ uli.QuadPart + 0 ] ;// Store QuadPart's low order bits.
436 | mul ecx ;// Multiply the low order bits of QuadPart with the low order bits of base (10). edx = high, eax = low
437 | add edx, ebx ;// Add the low order bits (ebx) to the high order bits (edx).
438 |
439 | pop ebx ;// Restore value from stack.
440 |
441 | finish10:
442 |
443 | mov uli.HighPart, edx ;// Store the high order bits.
444 | mov uli.LowPart, eax ;// Store the low order bits.
445 | }*/
446 |
447 | digit = *p - '0';
448 |
449 | if ( uli.QuadPart > ( ULLONG_MAX - digit ) )
450 | {
451 | uli.QuadPart = ULLONG_MAX;
452 | break;
453 | }
454 |
455 | uli.QuadPart += digit;
456 |
457 | ++p;
458 | }
459 | }
460 | else
461 | {
462 | while ( *p )
463 | {
464 | if ( *p >= '0' && *p <= '9' )
465 | {
466 | digit = *p - '0';
467 | }
468 | else if ( *p >= 'a' && *p <= 'f' )
469 | {
470 | digit = *p - 'a' + 10;
471 | }
472 | else if ( *p >= 'A' && *p <= 'F' )
473 | {
474 | digit = *p - 'A' + 10;
475 | }
476 | else
477 | {
478 | break;
479 | }
480 |
481 | if ( uli.QuadPart > ( ULLONG_MAX / 16 ) )
482 | {
483 | uli.QuadPart = ULLONG_MAX;
484 | break;
485 | }
486 |
487 | uli.QuadPart *= 16;
488 |
489 | /*__asm
490 | {
491 | mov eax, dword ptr [ uli.QuadPart + 4 ]
492 | cmp eax, 0 ;// See if our QuadPart's value extends to 64 bits.
493 | mov ecx, 16 ;// Store the base (16) multiplier (low order bits).
494 | jne short hard16 ;// If there are high order bits in QuadPart, then multiply/add high and low bits.
495 |
496 | mov eax, dword ptr [ uli.QuadPart + 0 ] ;// Store the QuadPart's low order bits.
497 | mul ecx ;// Multiply the low order bits.
498 |
499 | jmp finish16 ;// Store the results in our 64 bit value.
500 |
501 | hard16:
502 |
503 | push ebx ;// Save value to stack.
504 |
505 | mul ecx ;// Multiply the high order bits of QuadPart with the low order bits of base (16).
506 | mov ebx, eax ;// Store the result.
507 |
508 | mov eax, dword ptr [ uli.QuadPart + 0 ] ;// Store QuadPart's low order bits.
509 | mul ecx ;// Multiply the low order bits of QuadPart with the low order bits of base (16). edx = high, eax = low
510 | add edx, ebx ;// Add the low order bits (ebx) to the high order bits (edx).
511 |
512 | pop ebx ;// Restore value from stack.
513 |
514 | finish16:
515 |
516 | mov uli.HighPart, edx ;// Store the high order bits.
517 | mov uli.LowPart, eax ;// Store the low order bits.
518 | }*/
519 |
520 | if ( uli.QuadPart > ( ULLONG_MAX - digit ) )
521 | {
522 | uli.QuadPart = ULLONG_MAX;
523 | break;
524 | }
525 |
526 | uli.QuadPart += digit;
527 |
528 | ++p;
529 | }
530 | }
531 |
532 | return uli.QuadPart;
533 | }
534 |
535 | __int64 htonll( __int64 i )
536 | {
537 | unsigned int t = 0;
538 | unsigned int b = 0;
539 |
540 | unsigned int v[ 2 ];
541 |
542 | _memcpy_s( v, sizeof( unsigned int ) * 2, &i, sizeof( unsigned __int64 ) );
543 |
544 | t = _htonl( v[ 0 ] );
545 | v[ 0 ] = _htonl( v[ 1 ] );
546 | v[ 1 ] = t;
547 |
548 | _memcpy_s( &i, sizeof( __int64 ), ( void * )v, sizeof( unsigned int ) * 2 );
549 |
550 | return i;
551 |
552 | //return ( ( __int64 )_htonl( i & 0xFFFFFFFFU ) << 32 ) | _htonl( ( __int64 )( i >> 32 ) );
553 | }
554 |
555 | char from_hex( char c )
556 | {
557 | //_CharLowerBuffA( ( LPSTR )c, 1 );
558 | //return is_digit( *c ) ? *c - '0' : *c - 'a' + 10;
559 |
560 | if ( is_digit( c ) )
561 | {
562 | return c - '0';
563 | }
564 | else if ( c - 'a' + 0U < 6U )
565 | {
566 | return c - 'a' + 10;
567 | }
568 | else if ( c - 'A' + 0U < 6U )
569 | {
570 | return c - 'A' + 10;
571 | }
572 |
573 | return c;
574 | }
575 |
576 | bool is_hex( char c )
577 | {
578 | //_CharLowerBuffA( ( LPSTR )c, 1 );
579 | //return ( is_digit( *c ) || ( *c - 'a' + 0U < 6U ) );
580 |
581 | return ( is_digit( c ) || ( c - 'a' + 0U < 6U ) || ( c - 'A' + 0U < 6U ) );
582 | }
583 |
584 | char *url_decode( char *str, unsigned int str_len, unsigned int *dec_len )
585 | {
586 | char *pstr = str;
587 | char *buf = ( char * )GlobalAlloc( GMEM_FIXED, sizeof( char ) * ( str_len + 1 ) );
588 | char *pbuf = buf;
589 |
590 | while ( pstr < ( str + str_len ) )
591 | {
592 | if ( *pstr == '%' )
593 | {
594 | // Look at the next two characters.
595 | if ( ( ( pstr + 3 ) <= ( str + str_len ) ) )
596 | {
597 | // See if they're both hex values.
598 | if ( ( pstr[ 1 ] != NULL && is_hex( pstr[ 1 ] ) ) &&
599 | ( pstr[ 2 ] != NULL && is_hex( pstr[ 2 ] ) ) )
600 | {
601 | *pbuf++ = from_hex( pstr[ 1 ] ) << 4 | from_hex( pstr[ 2 ] );
602 | pstr += 2;
603 | }
604 | else
605 | {
606 | *pbuf++ = *pstr;
607 | }
608 | }
609 | else
610 | {
611 | *pbuf++ = *pstr;
612 | }
613 | }
614 | else if ( *pstr == '+' )
615 | {
616 | *pbuf++ = ' ';
617 | }
618 | else
619 | {
620 | *pbuf++ = *pstr;
621 | }
622 |
623 | pstr++;
624 | }
625 |
626 | *pbuf = '\0';
627 |
628 | if ( dec_len != NULL )
629 | {
630 | *dec_len = pbuf - buf;
631 | }
632 |
633 | return buf;
634 | }
635 |
636 | int _printf( const char *_Format, ... )
637 | {
638 | if ( g_hOutput != NULL )
639 | {
640 | DWORD written = 0;
641 | va_list arglist;
642 |
643 | va_start( arglist, _Format );
644 |
645 | //char buffer[ 4016 ]; // This is the largest we can set this buffer with a local stack size of 4096.
646 | char buffer[ 8192 ];
647 |
648 | int buffer_length = __vsnprintf( buffer, 8192, _Format, arglist );
649 |
650 | va_end( arglist );
651 |
652 | if ( buffer_length >= 0 && WriteConsoleA( g_hOutput, buffer, buffer_length, &written, NULL ) )
653 | {
654 | return written;
655 | }
656 | else
657 | {
658 | return -1;
659 | }
660 | }
661 | else
662 | {
663 | return -1;
664 | }
665 | }
666 |
667 | int _wprintf( const wchar_t *_Format, ... )
668 | {
669 | if ( g_hOutput != NULL )
670 | {
671 | DWORD written = 0;
672 | va_list arglist;
673 |
674 | va_start( arglist, _Format );
675 |
676 | //wchar_t buffer[ 2008 ]; // This is the largest we can set this buffer with a local stack size of 4096.
677 | wchar_t buffer[ 8192 ];
678 |
679 | int buffer_length = __vsnwprintf( buffer, 8192, _Format, arglist );
680 |
681 | va_end( arglist );
682 |
683 | if ( buffer_length >= 0 && WriteConsoleW( g_hOutput, buffer, buffer_length, &written, NULL ) )
684 | {
685 | return written;
686 | }
687 | else
688 | {
689 | return -1;
690 | }
691 | }
692 | else
693 | {
694 | return -1;
695 | }
696 | }
697 |
698 | unsigned char CountIntegerDigits( unsigned int integer )
699 | {
700 | return ( integer < 10 ? 1 : ( integer < 100 ? 2 : ( integer < 1000 ? 3 : ( integer < 10000 ? 4 : ( integer < 100000 ? 5 : ( integer < 1000000 ? 6 : ( integer < 10000000 ? 7 : ( integer < 100000000 ? 8 : ( integer < 1000000000 ? 9 : 10 ) ) ) ) ) ) ) ) );
701 | }
702 |
--------------------------------------------------------------------------------
/HTTP_Proxy/utilities.h:
--------------------------------------------------------------------------------
1 | /*
2 | HTTP Proxy can proxy HTTP and HTTPS connections.
3 | Copyright (C) 2016-2018 Eric Kutcher
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef _UTILITIES_H
20 | #define _UTILITIES_H
21 |
22 | #define MD5_LENGTH 16
23 |
24 | struct AUTH_INFO
25 | {
26 | char *auth_start;
27 | char *auth_end;
28 | char *basic_encode;
29 | char *basic_encode_end;
30 | char *username;
31 | char *username_end;
32 | char *realm;
33 | char *realm_end;
34 | char *nonce;
35 | char *nonce_end;
36 | char *uri;
37 | char *uri_end;
38 | char *response;
39 | char *response_end;
40 | char *opaque;
41 | char *opaque_end;
42 | char *qop;
43 | char *qop_end;
44 | char *cnonce;
45 | char *cnonce_end;
46 | unsigned int nc;
47 | char qop_type; // 0 = not found, 1 = auth, 2 = auth-int, 3 = unhandled
48 | char algorithm; // 0 = not found, 1 = MD5, 2 = MD5-sess, 3 = unhandled
49 | };
50 |
51 | void encode_cipher( char *buffer, int buffer_length );
52 | void decode_cipher( char *buffer, int buffer_length );
53 |
54 | void CreateBasicAuthentication( char *username, unsigned long username_length, char *password, unsigned long password_length, char **authentication, unsigned long &authentication_length );
55 | void CreateDigestInfo( char **nonce, unsigned long &nonce_length, char **opaque, unsigned long &opaque_length );
56 |
57 | bool VerifyBasicAuthorization( char *encoded_credentials, unsigned long encoded_credientials_length, AUTH_INFO *auth_info );
58 | bool VerifyDigestAuthorization( char *username, unsigned long username_length, char *password, unsigned long password_length, char *nonce, unsigned long nonce_length, char *opaque, unsigned long opaque_length, char *method, unsigned long method_length, AUTH_INFO *auth_info );
59 |
60 | char *GlobalStrDupA( const char *_Str );
61 | unsigned long long strtoull( char *str, bool base16 = false );
62 | __int64 htonll( __int64 i );
63 | char *url_decode( char *str, unsigned int str_len, unsigned int *dec_len );
64 |
65 | int _printf( const char *_Format, ... );
66 | int _wprintf( const wchar_t *_Format, ... );
67 |
68 | unsigned char CountIntegerDigits( unsigned int integer );
69 |
70 | #endif
71 |
--------------------------------------------------------------------------------