ReactOS 0.4.15-dev-8109-gd7be748
dispatcher.c File Reference
#include "precomp.h"
#include <stdio.h>
#include <process.h>
#include <io.h>
#include <errno.h>
#include <fcntl.h>
#include <wine/debug.h>
Include dependency graph for dispatcher.c:

Go to the source code of this file.

Macros

#define INITIAL_BUFFER_SIZE   200
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (ntlm)
 
charflatten_cmdline (const char *prog, char *const argv[])
 
SECURITY_STATUS fork_helper (PNegoHelper *new_helper, const char *prog, char *const argv[])
 
static SECURITY_STATUS read_line (PNegoHelper helper, int *offset_len)
 
static SECURITY_STATUS preserve_unused (PNegoHelper helper, int offset_len)
 
SECURITY_STATUS run_helper (PNegoHelper helper, char *buffer, unsigned int max_buflen, int *buflen)
 
void cleanup_helper (PNegoHelper helper)
 
void check_version (PNegoHelper helper)
 

Macro Definition Documentation

◆ INITIAL_BUFFER_SIZE

#define INITIAL_BUFFER_SIZE   200

Definition at line 38 of file dispatcher.c.

Function Documentation

◆ check_version()

void check_version ( PNegoHelper  helper)

Definition at line 408 of file dispatcher.c.

409{
410 char temp[80];
411 char *newline;
412 int major = 0, minor = 0, micro = 0, ret;
413
414 TRACE("Checking version of helper\n");
415 if(helper != NULL)
416 {
417 int len = read(helper->pipe_in, temp, sizeof(temp)-1);
418 if (len > 8)
419 {
420 if((newline = memchr(temp, '\n', len)) != NULL)
421 *newline = '\0';
422 else
423 temp[len] = 0;
424
425 TRACE("Exact version is %s\n", debugstr_a(temp));
426 ret = sscanf(temp, "Version %d.%d.%d", &major, &minor, &micro);
427 if(ret != 3)
428 {
429 ERR("Failed to get the helper version.\n");
430 helper->major = helper->minor = helper->micro = -1;
431 }
432 else
433 {
434 TRACE("Version recognized: %d.%d.%d\n", major, minor, micro);
435 helper->major = major;
436 helper->minor = minor;
437 helper->micro = micro;
438 }
439 }
440 }
441}
#define read
Definition: acwin.h:96
#define ERR(fmt,...)
Definition: debug.h:113
#define NULL
Definition: types.h:112
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define debugstr_a
Definition: kernel32.h:31
#define memchr(s, c, n)
Definition: mkisofs.h:875
#define minor(rdev)
Definition: propsheet.cpp:929
#define major(rdev)
Definition: propsheet.cpp:928
static calc_node_t temp
Definition: rpn_ieee.c:38
#define TRACE(s)
Definition: solgame.cpp:4
int minor
Definition: ntlm.h:31
int pipe_in
Definition: ntlm.h:28
int major
Definition: ntlm.h:30
int micro
Definition: ntlm.h:32
int ret

◆ cleanup_helper()

void cleanup_helper ( PNegoHelper  helper)

Definition at line 377 of file dispatcher.c.

378{
379
380 TRACE("Killing helper %p\n", helper);
381 if(helper == NULL)
382 return;
383
384 HeapFree(GetProcessHeap(), 0, helper->com_buf);
385 HeapFree(GetProcessHeap(), 0, helper->session_key);
386
387 /* closing stdin will terminate ntlm_auth */
388 close(helper->pipe_out);
389 close(helper->pipe_in);
390
391#ifndef __REACTOS__
392
393#ifdef HAVE_FORK
394 if (helper->helper_pid > 0) /* reap child */
395 {
396 pid_t wret;
397 do {
398 wret = waitpid(helper->helper_pid, NULL, 0);
399 } while (wret < 0 && errno == EINTR);
400 }
401#endif
402
403#endif
404
405 HeapFree(GetProcessHeap(), 0, helper);
406}
#define EINTR
Definition: acclib.h:80
#define close
Definition: acwin.h:98
DWORD pid_t
Definition: types.h:91
#define GetProcessHeap()
Definition: compat.h:736
#define HeapFree(x, y, z)
Definition: compat.h:735
#define errno
Definition: errno.h:18
pid_t helper_pid
Definition: ntlm.h:23
int pipe_out
Definition: ntlm.h:29
BYTE * session_key
Definition: ntlm.h:36
char * com_buf
Definition: ntlm.h:33

Referenced by ntlm_AcceptSecurityContext(), ntlm_DeleteSecurityContext(), ntlm_InitializeSecurityContextW(), and SECUR32_initNTLMSP().

◆ flatten_cmdline()

char * flatten_cmdline ( const char prog,
char *const  argv[] 
)

Definition at line 40 of file dispatcher.c.

41{
42 int i;
43 SIZE_T argstr_size = 0;
44 char *argstr, *p;
45
46 /* Compute space needed for the new string, and allocate it */
47 argstr_size += strlen(prog) + 3; // 3 == 2 quotes between 'prog', and 1 space
48 for(i = 0; argv[i] != NULL; ++i)
49 {
50 argstr_size += strlen(argv[i]) + 1; // 1 for space
51 }
52 argstr = HeapAlloc(GetProcessHeap(), 0, (argstr_size + 1) * sizeof(CHAR));
53 if (argstr == NULL)
54 {
55 ERR("ERROR: Not enough memory\n");
56 return NULL;
57 }
58
59 /* Copy the contents and NULL-terminate the string */
60 p = argstr;
61 strcpy(p, "\""); // Open quote
62 strcat(p, prog);
63 strcat(p, "\" "); // Close quote + space
64 p += strlen(p);
65 for(i = 0; argv[i] != NULL; ++i)
66 {
67 strcpy(p, argv[i]);
68 p += strlen(argv[i]);
69 *p++ = ' ';
70 }
71 *p = '\0';
72
73 return argstr;
74}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define HeapAlloc
Definition: compat.h:733
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
char * prog
Definition: isohybrid.c:47
#define argv
Definition: mplay32.c:18
ULONG_PTR SIZE_T
Definition: typedefs.h:80
char CHAR
Definition: xmlstorage.h:175

Referenced by fork_helper().

◆ fork_helper()

SECURITY_STATUS fork_helper ( PNegoHelper new_helper,
const char prog,
char *const  argv[] 
)

Definition at line 76 of file dispatcher.c.

78{
79 int pipe_in[2];
80 int pipe_out[2];
81#ifdef __REACTOS__
82 HANDLE hPipe;
84 STARTUPINFOA si;
85 char* cmdline;
86#endif
87 int i;
88 PNegoHelper helper;
89
90 TRACE("%s ", debugstr_a(prog));
91 for(i = 0; argv[i] != NULL; ++i)
92 {
93 TRACE("%s ", debugstr_a(argv[i]));
94 }
95 TRACE("\n");
96
97#ifndef __REACTOS__
98
99#ifdef HAVE_PIPE2
100 if (pipe2( pipe_in, O_CLOEXEC ) < 0 )
101#endif
102 {
103 if( pipe(pipe_in) < 0 ) return SEC_E_INTERNAL_ERROR;
104 fcntl( pipe_in[0], F_SETFD, FD_CLOEXEC );
105 fcntl( pipe_in[1], F_SETFD, FD_CLOEXEC );
106 }
107#ifdef HAVE_PIPE2
108 if (pipe2( pipe_out, O_CLOEXEC ) < 0 )
109#endif
110 {
111 if( pipe(pipe_out) < 0 )
112 {
113 close(pipe_in[0]);
114 close(pipe_in[1]);
116 }
117 fcntl( pipe_out[0], F_SETFD, FD_CLOEXEC );
118 fcntl( pipe_out[1], F_SETFD, FD_CLOEXEC );
119 }
120
121#else
122
123 if (_pipe(pipe_in, 0, _O_BINARY /* _O_TEXT */ | _O_NOINHERIT) < 0)
124 {
126 }
127
128 if (_pipe(pipe_out, 0, _O_BINARY /* _O_TEXT */ | _O_NOINHERIT) < 0)
129 {
130 close(pipe_in[0]);
131 close(pipe_in[1]);
133 }
134
135#endif
136
137 if (!(helper = HeapAlloc(GetProcessHeap(),0, sizeof(NegoHelper))))
138 {
139 close(pipe_in[0]);
140 close(pipe_in[1]);
141 close(pipe_out[0]);
142 close(pipe_out[1]);
144 }
145
146#ifndef __REACTOS__
147 helper->helper_pid = fork();
148#else
149
151 if (!cmdline)
152 {
153 close(pipe_in[0]);
154 close(pipe_in[1]);
155 close(pipe_out[0]);
156 close(pipe_out[1]);
157 HeapFree( GetProcessHeap(), 0, helper );
159 }
160
161 ZeroMemory(&pi, sizeof(pi));
162 ZeroMemory(&si, sizeof(si));
163 si.cb = sizeof(si);
164
166
167 /* The reading side of the pipe is STDIN for this process */
168 hPipe = (HANDLE)_get_osfhandle(pipe_out[0]);
170 si.hStdInput = hPipe;
171
172 /* The writing side of the pipe is STDOUT for this process */
173 hPipe = (HANDLE)_get_osfhandle(pipe_in[1]);
175 si.hStdOutput = hPipe;
176 si.hStdError = hPipe;
177
179 {
180 /* We fail just afterwards */
181 helper->helper_pid = (HANDLE)-1;
182 }
183 else
184 {
185 helper->helper_pid = pi.hProcess;
186 CloseHandle(pi.hThread);
187 CloseHandle(pi.hProcess);
188 }
189
191
192#endif
193
194#ifndef __REACTOS__
195 if(helper->helper_pid == -1)
196#else
197 if(helper->helper_pid == (HANDLE)-1)
198#endif
199 {
200 close(pipe_in[0]);
201 close(pipe_in[1]);
202 close(pipe_out[0]);
203 close(pipe_out[1]);
204 HeapFree( GetProcessHeap(), 0, helper );
206 }
207
208#ifndef __REACTOS__
209 if(helper->helper_pid == 0)
210 {
211 /* We're in the child now */
212 dup2(pipe_out[0], 0);
213 close(pipe_out[0]);
214 close(pipe_out[1]);
215
216 dup2(pipe_in[1], 1);
217 close(pipe_in[0]);
218 close(pipe_in[1]);
219
220 execvp(prog, argv);
221
222 /* Whoops, we shouldn't get here. Big badaboom.*/
223 write(STDOUT_FILENO, "BH\n", 3);
224 _exit(1);
225 }
226 else
227#endif
228 {
229 *new_helper = helper;
230 helper->major = helper->minor = helper->micro = -1;
231 helper->com_buf = NULL;
232 helper->com_buf_size = 0;
233 helper->com_buf_offset = 0;
234 helper->session_key = NULL;
235 helper->neg_flags = 0;
236 helper->crypt.ntlm.a4i = NULL;
237 helper->crypt.ntlm2.send_a4i = NULL;
238 helper->crypt.ntlm2.recv_a4i = NULL;
239 helper->crypt.ntlm2.send_sign_key = NULL;
240 helper->crypt.ntlm2.send_seal_key = NULL;
241 helper->crypt.ntlm2.recv_sign_key = NULL;
242 helper->crypt.ntlm2.recv_seal_key = NULL;
243 helper->pipe_in = pipe_in[0]; // Keep in(read)
244 close(pipe_in[1]); // Close in(write)
245 helper->pipe_out = pipe_out[1]; // Keep out(write)
246 close(pipe_out[0]); // Close out(read)
247 }
248
249 return SEC_E_OK;
250}
void _exit(int exitcode)
Definition: _exit.c:25
#define write
Definition: acwin.h:97
#define TRUE
Definition: types.h:120
#define _O_BINARY
Definition: cabinet.h:51
#define _O_NOINHERIT
Definition: cabinet.h:45
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI SetHandleInformation(IN HANDLE hObject, IN DWORD dwMask, IN DWORD dwFlags)
Definition: handle.c:78
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4741
char * flatten_cmdline(const char *prog, char *const argv[])
Definition: dispatcher.c:40
static refpint_t pi[]
Definition: server.c:96
#define STDOUT_FILENO
Definition: syshdrs.h:89
_CRTIMP intptr_t __cdecl _get_osfhandle(_In_ int _FileHandle)
_Check_return_ _CRTIMP int __cdecl _pipe(_Inout_updates_(2) int *_PtHandles, _In_ unsigned int _PipeSize, _In_ int _TextMode)
_Check_return_ _CRTIMP int __cdecl dup2(_In_ int _FileHandleSrc, _In_ int _FileHandleDst)
_CRTIMP intptr_t __cdecl execvp(_In_z_ const char *_Filename, _In_z_ char *const _ArgList[])
TCHAR * cmdline
Definition: stretchblt.cpp:32
int com_buf_offset
Definition: ntlm.h:35
struct _NegoHelper::@553 crypt
int com_buf_size
Definition: ntlm.h:34
ULONG neg_flags
Definition: ntlm.h:37
HANDLE hStdOutput
Definition: winbase.h:847
HANDLE hStdError
Definition: winbase.h:848
DWORD dwFlags
Definition: winbase.h:842
DWORD cb
Definition: winbase.h:831
HANDLE hStdInput
Definition: winbase.h:846
#define FD_CLOEXEC
Definition: fcntl.h:102
PVOID HANDLE
Definition: typedefs.h:73
#define ZeroMemory
Definition: winbase.h:1712
#define HANDLE_FLAG_INHERIT
Definition: winbase.h:264
#define CREATE_NO_WINDOW
Definition: winbase.h:195
#define STARTF_USESTDHANDLES
Definition: winbase.h:499
#define SEC_E_OK
Definition: winerror.h:2356
#define SEC_E_INTERNAL_ERROR
Definition: winerror.h:2913
#define SEC_E_INSUFFICIENT_MEMORY
Definition: winerror.h:2909

Referenced by ntlm_AcceptSecurityContext(), ntlm_InitializeSecurityContextW(), and SECUR32_initNTLMSP().

◆ preserve_unused()

static SECURITY_STATUS preserve_unused ( PNegoHelper  helper,
int  offset_len 
)
static

Definition at line 312 of file dispatcher.c.

313{
314 TRACE("offset_len = %d\n", offset_len);
315
316 if(offset_len > 0)
317 {
318 memmove(helper->com_buf, helper->com_buf + helper->com_buf_offset,
319 offset_len);
320 helper->com_buf_offset = offset_len;
321 }
322 else
323 {
324 helper->com_buf_offset = 0;
325 }
326
327 TRACE("helper->com_buf_offset was set to: %d\n", helper->com_buf_offset);
328 return SEC_E_OK;
329}
#define memmove(s1, s2, n)
Definition: mkisofs.h:881

Referenced by run_helper().

◆ read_line()

static SECURITY_STATUS read_line ( PNegoHelper  helper,
int offset_len 
)
static

Definition at line 252 of file dispatcher.c.

253{
254 char *newline;
255 int read_size;
256
257 if(helper->com_buf == NULL)
258 {
259 TRACE("Creating a new buffer for the helper\n");
262
263 /* Created a new buffer, size is INITIAL_BUFFER_SIZE, offset is 0 */
265 helper->com_buf_offset = 0;
266 }
267
268 do
269 {
270 TRACE("offset = %d, size = %d\n", helper->com_buf_offset, helper->com_buf_size);
271 if(helper->com_buf_offset + INITIAL_BUFFER_SIZE > helper->com_buf_size)
272 {
273 /* increment buffer size in INITIAL_BUFFER_SIZE steps */
274 char *buf = HeapReAlloc(GetProcessHeap(), 0, helper->com_buf,
276 TRACE("Resizing buffer!\n");
277 if (!buf) return SEC_E_INSUFFICIENT_MEMORY;
279 helper->com_buf = buf;
280 }
281 if((read_size = read(helper->pipe_in, helper->com_buf + helper->com_buf_offset,
282 helper->com_buf_size - helper->com_buf_offset)) <= 0)
283 {
285 }
286
287 TRACE("read_size = %d, read: %s\n", read_size,
288 debugstr_a(helper->com_buf + helper->com_buf_offset));
289 helper->com_buf_offset += read_size;
290 newline = memchr(helper->com_buf, '\n', helper->com_buf_offset);
291 }while(newline == NULL);
292
293 /* Now, if there's a newline character, and we read more than that newline,
294 * we have to store the offset so we can preserve the additional data.*/
295 if( newline != helper->com_buf + helper->com_buf_offset)
296 {
297 TRACE("offset_len is calculated from %p - %p\n",
298 (helper->com_buf + helper->com_buf_offset), newline+1);
299 /* the length of the offset is the number of chars after the newline */
300 *offset_len = (helper->com_buf + helper->com_buf_offset) - (newline + 1);
301 }
302 else
303 {
304 *offset_len = 0;
305 }
306
307 *newline = '\0';
308
309 return SEC_E_OK;
310}
#define HeapReAlloc
Definition: compat.h:734
#define INITIAL_BUFFER_SIZE
Definition: dispatcher.c:38
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751

◆ run_helper()

SECURITY_STATUS run_helper ( PNegoHelper  helper,
char buffer,
unsigned int  max_buflen,
int buflen 
)

Definition at line 331 of file dispatcher.c.

333{
334 int offset_len;
335 SECURITY_STATUS sec_status = SEC_E_OK;
336
337 TRACE("In helper: sending %s\n", debugstr_a(buffer));
338
339 /* buffer + '\n' */
340 write(helper->pipe_out, buffer, lstrlenA(buffer));
341 write(helper->pipe_out, "\n", 1);
342
343 if((sec_status = read_line(helper, &offset_len)) != SEC_E_OK)
344 {
345 return sec_status;
346 }
347
348 TRACE("In helper: received %s\n", debugstr_a(helper->com_buf));
349 *buflen = lstrlenA(helper->com_buf);
350
351 if( *buflen > max_buflen)
352 {
353 ERR("Buffer size too small(%d given, %d required) dropping data!\n",
354 max_buflen, *buflen);
356 }
357
358 if( *buflen < 2 )
359 {
361 }
362
363 /* We only get ERR if the input size is too big. On a GENSEC error,
364 * ntlm_auth will return BH */
365 if(strncmp(helper->com_buf, "ERR", 3) == 0)
366 {
367 return SEC_E_INVALID_TOKEN;
368 }
369
370 memcpy(buffer, helper->com_buf, *buflen+1);
371
372 sec_status = preserve_unused(helper, offset_len);
373
374 return sec_status;
375}
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static SECURITY_STATUS preserve_unused(PNegoHelper helper, int offset_len)
Definition: dispatcher.c:312
GLuint buffer
Definition: glext.h:5915
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
LONG SECURITY_STATUS
Definition: sspi.h:34
int read_line()
#define SEC_E_BUFFER_TOO_SMALL
Definition: winerror.h:2937
#define SEC_E_ILLEGAL_MESSAGE
Definition: winerror.h:2943
#define SEC_E_INVALID_TOKEN
Definition: winerror.h:2917

Referenced by ntlm_AcceptSecurityContext(), and ntlm_InitializeSecurityContextW().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( ntlm  )