└── 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 | --------------------------------------------------------------------------------