ksgi

Форк
0
/
child.c 
2264 строки · 52.7 Кб
1
/*	$Id$ */
2
/*
3
 * Copyright (c) 2012, 2014--2020 Kristaps Dzonsons <kristaps@bsd.lv>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
#include "config.h"
18

19
#include <arpa/inet.h>
20

21
#include <assert.h>
22
#include <ctype.h>
23
#include <errno.h>
24
#include <inttypes.h>
25
#include <limits.h>
26
#if HAVE_MD5
27
# include <sys/types.h>
28
# include <md5.h>
29
#endif
30
#include <poll.h>
31
#include <stdarg.h>
32
#include <stdio.h>
33
#include <stddef.h>
34
#include <stdint.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <unistd.h>
38

39
#include "kcgi.h"
40
#include "extern.h"
41

42
#define MD5Updatec(_ctx, _b, _sz) \
43
	MD5Update((_ctx), (const uint8_t *)(_b), (_sz))
44

45
enum	mimetype {
46
	MIMETYPE_UNKNOWN,
47
	MIMETYPE_TRANSFER_ENCODING,
48
	MIMETYPE_DISPOSITION,
49
	MIMETYPE_TYPE
50
};
51

52
/*
53
 * For handling HTTP multipart forms.
54
 * This consists of data for a single multipart form entry.
55
 */
56
struct	mime {
57
	char	 *disp; /* content disposition */
58
	char	 *name; /* name of form entry */
59
	size_t	  namesz; /* size of "name" string */
60
	char	 *file; /* whether a file was specified */
61
	char	 *ctype; /* content type */
62
	size_t	  ctypepos; /* position of ctype in mimes */
63
	char	 *xcode; /* encoding type */
64
	char	 *bound; /* form entry boundary */
65
};
66

67
/*
68
 * Both CGI and FastCGI use an environment for their HTTP parameters.
69
 * CGI gets it from the actual environment; FastCGI from a transmitted
70
 * environment.
71
 * We use an abstract representation of those key-value pairs here so
72
 * that we can use the same functions for both.
73
 */
74
struct	env {
75
	char	*key; /* key (e.g., HTTP_HOST) */
76
	size_t	 keysz;
77
	char	*val; /* value (e.g., `foo.com') */
78
	size_t	 valsz;
79
};
80

81
/* 
82
 * Types of FastCGI requests.
83
 * Defined in the FastCGI v1.0 spec, section 8.
84
 */
85
enum	fcgi_type {
86
	FCGI_BEGIN_REQUEST = 1,
87
	FCGI_ABORT_REQUEST = 2,
88
	FCGI_END_REQUEST = 3,
89
	FCGI_PARAMS = 4,
90
	FCGI_STDIN = 5,
91
	FCGI_STDOUT = 6,
92
	FCGI_STDERR = 7,
93
	FCGI_DATA = 8,
94
	FCGI_GET_VALUES = 9,
95
	FCGI_GET_VALUES_RESULT = 10,
96
	FCGI_UNKNOWN_TYPE = 11,
97
	FCGI__MAX
98
};
99

100
/*
101
 * The FastCGI `FCGI_Header' header layout.
102
 * Defined in the FastCGI v1.0 spec, section 8.
103
 */
104
struct 	fcgi_hdr {
105
	uint8_t	 version;
106
	uint8_t	 type;
107
	uint16_t requestId;
108
	uint16_t contentLength;
109
	uint8_t	 paddingLength;
110
	uint8_t	 reserved;
111
};
112

113
/*
114
 * The FastCGI `FCGI_BeginRequestBody' header layout.
115
 * Defined in the FastCGI v1.0 spec, section 8.
116
 */
117
struct	fcgi_bgn {
118
	uint16_t role;
119
	uint8_t	 flags;
120
	uint8_t	 res[5];
121
};
122

123
/*
124
 * A buffer of reads from kfcgi_control().
125
 */
126
struct	fcgi_buf {
127
	size_t	 sz; /* bytes in buffer */
128
	size_t	 pos; /* current position (from last read) */
129
	int	 fd; /* file descriptor */
130
	char	*buf; /* buffer itself */
131
};
132

133
/*
134
 * Parameters required to validate fields.
135
 */
136
struct	parms {
137
	int	 		 fd;
138
	const char *const	*mimes;
139
	size_t			 mimesz;
140
	const struct kvalid	*keys;
141
	size_t			 keysz;
142
	enum input		 type;
143
};
144

145
const char *const kmethods[KMETHOD__MAX] = {
146
	"ACL", /* KMETHOD_ACL */
147
	"CONNECT", /* KMETHOD_CONNECT */
148
	"COPY", /* KMETHOD_COPY */
149
	"DELETE", /* KMETHOD_DELETE */
150
	"GET", /* KMETHOD_GET */
151
	"HEAD", /* KMETHOD_HEAD */
152
	"LOCK", /* KMETHOD_LOCK */
153
	"MKCALENDAR", /* KMETHOD_MKCALENDAR */
154
	"MKCOL", /* KMETHOD_MKCOL */
155
	"MOVE", /* KMETHOD_MOVE */
156
	"OPTIONS", /* KMETHOD_OPTIONS */
157
	"POST", /* KMETHOD_POST */
158
	"PROPFIND", /* KMETHOD_PROPFIND */
159
	"PROPPATCH", /* KMETHOD_PROPPATCH */
160
	"PUT", /* KMETHOD_PUT */
161
	"REPORT", /* KMETHOD_REPORT */
162
	"TRACE", /* KMETHOD_TRACE */
163
	"UNLOCK", /* KMETHOD_UNLOCK */
164
};
165

166
static	const char *const krequs[KREQU__MAX] = {
167
	"HTTP_ACCEPT", /* KREQU_ACCEPT */
168
	"HTTP_ACCEPT_CHARSET", /* KREQU_ACCEPT_CHARSET */
169
	"HTTP_ACCEPT_ENCODING", /* KREQU_ACCEPT_ENCODING */
170
	"HTTP_ACCEPT_LANGUAGE", /* KREQU_ACCEPT_LANGUAGE */
171
	"HTTP_AUTHORIZATION", /* KREQU_AUTHORIZATION */
172
	"HTTP_DEPTH", /* KREQU_DEPTH */
173
	"HTTP_FROM", /* KREQU_FROM */
174
	"HTTP_HOST", /* KREQU_HOST */
175
	"HTTP_IF", /* KREQU_IF */
176
	"HTTP_IF_MODIFIED_SINCE", /* KREQU_IF_MODIFIED_SINCE */
177
	"HTTP_IF_MATCH", /* KREQU_IF_MATCH */
178
	"HTTP_IF_NONE_MATCH", /* KREQU_IF_NONE_MATCH */
179
	"HTTP_IF_RANGE", /* KREQU_IF_RANGE */
180
	"HTTP_IF_UNMODIFIED_SINCE", /* KREQU_IF_UNMODIFIED_SINCE */
181
	"HTTP_MAX_FORWARDS", /* KREQU_MAX_FORWARDS */
182
	"HTTP_PROXY_AUTHORIZATION", /* KREQU_PROXY_AUTHORIZATION */
183
	"HTTP_RANGE", /* KREQU_RANGE */
184
	"HTTP_REFERER", /* KREQU_REFERER */
185
	"HTTP_USER_AGENT", /* KREQU_USER_AGENT */
186
};
187

188
static	const char *const kauths[KAUTH_UNKNOWN] = {
189
	NULL, /* KAUTH_NONE */
190
	"basic", /* KAUTH_BASIC */
191
	"digest", /* KAUTH_DIGEST */
192
	"bearer", /* KAUTH_BEARER */
193
};
194

195
/*
196
 * Parse the type/subtype field out of a content-type.
197
 * The content-type is defined (among other places) in RFC 822, and is
198
 * either the whole string or up until the ';', which marks the
199
 * beginning of the parameters.
200
 */
201
static size_t
202
str2ctype(const struct parms *pp, const char *ctype)
203
{
204
	size_t		 i, sz;
205

206
	if (NULL == ctype) 
207
		return(pp->mimesz);
208

209
	/* Stop at the content-type parameters. */
210
	sz = strcspn(ctype, ";");
211

212
	for (i = 0; i < pp->mimesz; i++)
213
		if (sz == strlen(pp->mimes[i]) &&
214
		    0 == strncasecmp(pp->mimes[i], ctype, sz))
215
			break;
216

217
	return(i);
218
}
219

220
/*
221
 * Given a parsed field "key" with value "val" of size "valsz" and MIME
222
 * information "mime", first try to look it up in the array of
223
 * recognised keys ("pp->keys") and optionally validate.
224
 * Then output the type, parse status (key, type, etc.), and values read
225
 * by the parent input() function.
226
 */
227
static void
228
output(const struct parms *pp, char *key, 
229
	char *val, size_t valsz, struct mime *mime)
230
{
231
	size_t	 	 i;
232
	ptrdiff_t	 diff;
233
	char		*save;
234
	struct kpair	 pair;
235

236
	memset(&pair, 0, sizeof(struct kpair));
237

238
	pair.key = key;
239
	pair.val = save = val;
240
	pair.valsz = valsz;
241
	pair.file = NULL == mime ? NULL : mime->file;
242
	pair.ctype = NULL == mime ? NULL : mime->ctype;
243
	pair.xcode = NULL == mime ? NULL : mime->xcode;
244
	pair.ctypepos = NULL == mime ? pp->mimesz : mime->ctypepos;
245
	pair.type = KPAIR__MAX;
246

247
	/*
248
	 * Look up the key name in our key table.
249
	 * If we find it and it has a validator, then run the validator
250
	 * and record the output.
251
	 * If we fail, reset the type and clear the results.
252
	 * Either way, the keypos parameter is going to be the key
253
	 * identifier or keysz if none is found.
254
	 */
255

256
	for (i = 0; i < pp->keysz; i++) {
257
		if (strcmp(pp->keys[i].name, pair.key)) 
258
			continue;
259
		if (NULL == pp->keys[i].valid) 
260
			break;
261
		if ( ! pp->keys[i].valid(&pair)) {
262
			pair.state = KPAIR_INVALID;
263
			pair.type = KPAIR__MAX;
264
			memset(&pair.parsed, 0, sizeof(union parsed));
265
		} else
266
			pair.state = KPAIR_VALID;
267
		break;
268
	}
269
	pair.keypos = i;
270

271
	fullwrite(pp->fd, &pp->type, sizeof(enum input));
272
	fullwriteword(pp->fd, pair.key);
273
	fullwrite(pp->fd, &pair.valsz, sizeof(size_t));
274
	fullwrite(pp->fd, pair.val, pair.valsz);
275
	fullwrite(pp->fd, &pair.state, sizeof(enum kpairstate));
276
	fullwrite(pp->fd, &pair.type, sizeof(enum kpairtype));
277
	fullwrite(pp->fd, &pair.keypos, sizeof(size_t));
278

279
	if (KPAIR_VALID == pair.state) 
280
		switch (pair.type) {
281
		case (KPAIR_DOUBLE):
282
			fullwrite(pp->fd, 
283
				&pair.parsed.d, sizeof(double));
284
			break;
285
		case (KPAIR_INTEGER):
286
			fullwrite(pp->fd, 
287
				&pair.parsed.i, sizeof(int64_t));
288
			break;
289
		case (KPAIR_STRING):
290
			assert(pair.parsed.s >= pair.val);
291
			assert(pair.parsed.s <= pair.val + pair.valsz);
292
			diff = pair.val - pair.parsed.s;
293
			fullwrite(pp->fd, &diff, sizeof(ptrdiff_t));
294
			break;
295
		default:
296
			break;
297
		}
298

299
	fullwriteword(pp->fd, pair.file);
300
	fullwriteword(pp->fd, pair.ctype);
301
	fullwrite(pp->fd, &pair.ctypepos, sizeof(size_t));
302
	fullwriteword(pp->fd, pair.xcode);
303

304
	/*
305
	 * We can write a new "val" in the validator allocated on the
306
	 * heap: if we do, free it here.
307
	 */
308

309
	if (save != pair.val)
310
		free(pair.val);
311
}
312

313
/*
314
 * Read full stdin request into memory.
315
 * This reads at most "len" bytes and NUL-terminates the results, the
316
 * length of which may be less than "len" and is stored in *szp if not
317
 * NULL.
318
 * Returns the pointer to the data.
319
 * NOTE: we can't use fullread() here because we may not get the total
320
 * number of bytes requested.
321
 * NOTE: "szp" can legit be set to zero.
322
 */
323
static char *
324
scanbuf(size_t len, size_t *szp)
325
{
326
	ssize_t		 ssz;
327
	size_t		 sz;
328
	char		*p;
329
	int		 rc;
330
	struct pollfd	 pfd;
331

332
	pfd.fd = STDIN_FILENO;
333
	pfd.events = POLLIN;
334

335
	/* Allocate the entire buffer here. */
336

337
	if ((p = kxmalloc(len + 1)) == NULL)
338
		_exit(EXIT_FAILURE);
339

340
	/* 
341
	 * Keep reading til we get all the data or the sender stops
342
	 * giving us data---whichever comes first.
343
	 * Use kutil_warn[x] and _exit to avoid flushing buffers.
344
	 */
345

346
	for (sz = 0; sz < len; sz += (size_t)ssz) {
347
		if ((rc = poll(&pfd, 1, INFTIM)) < 0) {
348
			kutil_warn(NULL, NULL, "poll");
349
			_exit(EXIT_FAILURE);
350
		} else if (0 == rc) {
351
			kutil_warnx(NULL, NULL, "poll: timeout!?");
352
			ssz = 0;
353
			continue;
354
		}
355
		
356
		if (!(pfd.revents & POLLIN))
357
			break;
358

359
		if ((ssz = read(STDIN_FILENO, p + sz, len - sz)) < 0) {
360
			kutil_warn(NULL, NULL, "read");
361
			_exit(EXIT_FAILURE);
362
		} else if (ssz == 0)
363
			break;
364
	}
365

366
	if (sz < len)
367
		kutil_warnx(NULL, NULL, "content size mismatch: "
368
			"have %zu while %zu specified", sz, len);
369

370
	/* ALWAYS NUL-terminate. */
371

372
	p[sz] = '\0';
373

374
	if (szp != NULL)
375
		*szp = sz;
376

377
	return p;
378
}
379

380
/*
381
 * Reset a particular mime component.
382
 * We can get duplicates, so reallocate.
383
 */
384
static void
385
mime_reset(char **dst, const char *src)
386
{
387

388
	free(*dst);
389
	if ((*dst = kxstrdup(src)) == NULL)
390
		_exit(EXIT_FAILURE);
391
}
392

393
/*
394
 * Free up all MIME headers.
395
 * We might call this more than once, so make sure that it can be
396
 * invoked again by setting the memory to zero.
397
 */
398
static void
399
mime_free(struct mime *mime)
400
{
401

402
	free(mime->disp);
403
	free(mime->name);
404
	free(mime->file);
405
	free(mime->ctype);
406
	free(mime->xcode);
407
	free(mime->bound);
408
	memset(mime, 0, sizeof(struct mime));
409
}
410

411
/*
412
 * Parse out all MIME headers.
413
 * This is defined by RFC 2045.
414
 * This returns TRUE if we've parsed up to (and including) the last
415
 * empty CRLF line, or FALSE if something has gone wrong (e.g., parse
416
 * error, out of memory).
417
 * If FALSE, parsing should stop immediately.
418
 */
419
static int
420
mime_parse(const struct parms *pp, struct mime *mime, 
421
	char *buf, size_t len, size_t *pos)
422
{
423
	char		*key, *val, *keyend, *end, *start, *line;
424
	enum mimetype	 type;
425
	int	 	 rc = 0;
426

427
	mime_free(mime);
428

429
	while (*pos < len) {
430
		/* Each MIME line ends with a CRLF. */
431

432
		start = &buf[*pos];
433
		end = memmem(start, len - *pos, "\r\n", 2);
434
		if (end == NULL) {
435
			kutil_warnx(NULL, NULL, "RFC error: "
436
				"MIME header line without CRLF");
437
			return 0;
438
		}
439

440
		/* 
441
		 * NUL-terminate to make a nice line.
442
		 * Then re-set our starting position. 
443
		 */
444

445
		*end = '\0';
446
		*pos += (end - start) + 2;
447

448
		/* Empty CRLF line: we're done here! */
449

450
		if (*start == '\0') {
451
			rc = 1;
452
			break;
453
		}
454

455
		/* 
456
		 * Find end of MIME statement name. 
457
		 * The RFCs disagree on white-space before the colon,
458
		 * but as it's allowed in the original RFC 822 and
459
		 * obsolete syntax should be supported, we do so here.
460
		 */
461

462
		key = start;
463
		if ((val = strchr(key, ':')) == NULL) {
464
			kutil_warnx(NULL, NULL, "RFC error: "
465
				"MIME header without colon separator");
466
			return 0;
467
		} else if (key != val) {
468
			keyend = val - 1;
469
			while (keyend >= key && *keyend == ' ')
470
				*keyend-- = '\0';
471
		}
472

473
		*val++ = '\0';
474
		while (*val == ' ')
475
			val++;
476

477
		if (*key == '\0') 
478
			kutil_warnx(NULL, NULL, "RFC "
479
				"warning: empty MIME header name");
480

481
		/* 
482
		 * Set "line" to be at the MIME value subpart, for
483
		 * example, "Content-type: text/plain; charset=us-ascii"
484
		 * would put us at the parts before "charset".
485
		 */
486

487
		line = NULL;
488
		if ((line = strchr(val, ';')) != NULL)
489
			*line++ = '\0';
490

491
		/* 
492
		 * Allow these specific MIME header statements.
493
		 * We'll follow up by parsing specific information from
494
		 * the header values, so remember what we parsed.
495
		 */
496

497
		if (strcasecmp(key, "content-transfer-encoding") == 0) {
498
			mime_reset(&mime->xcode, val);
499
			type = MIMETYPE_TRANSFER_ENCODING;
500
		} else if (strcasecmp(key, "content-disposition") == 0) {
501
			mime_reset(&mime->disp, val);
502
			type = MIMETYPE_DISPOSITION;
503
		} else if (strcasecmp(key, "content-type") == 0) {
504
			mime_reset(&mime->ctype, val);
505
			type = MIMETYPE_TYPE;
506
		} else
507
			type = MIMETYPE_UNKNOWN;
508

509
		/* 
510
		 * Process subpart only for content-type and
511
		 * content-disposition.
512
		 * The rest have no information we want: silently ignore them.
513
		 */
514

515
		if (type != MIMETYPE_TYPE &&
516
		    type != MIMETYPE_DISPOSITION)
517
			continue;
518

519
		while ((key = line) != NULL) {
520
			while (*key == ' ')
521
				key++;
522
			if (*key == '\0')
523
				break;
524

525
			/*
526
			 * It's not clear whether we're allowed to have
527
			 * OWS before the separator, but allow for it
528
			 * anyway.
529
			 */
530

531
			if ((val = strchr(key, '=')) == NULL) {
532
				kutil_warnx(NULL, NULL, "RFC error: "
533
					"MIME header without sub-part "
534
					"separator");
535
				return 0;
536
			} else if (key != val) {
537
				keyend = val - 1;
538
				while (keyend >= key && *keyend == ' ')
539
					*keyend-- = '\0';
540
			} 
541

542
			*val++ = '\0';
543

544
			if (*key == '\0')
545
				kutil_warnx(NULL, NULL, "RFC warning: "
546
					"empty MIME sub-part name");
547

548
			/* Quoted string. */
549

550
			if (*val == '"') {
551
				val++;
552
				line = strchr(val, '"');
553
				if (line == NULL) {
554
					kutil_warnx(NULL, NULL, "RFC "
555
						"error: quoted MIME "
556
						"header sub-part not "
557
						"terminated");
558
					return 0;
559
				}
560
				*line++ = '\0';
561

562
				/* 
563
				 * It's unclear as to whether this is
564
				 * allowed (white-space before the
565
				 * semicolon separator), but let's
566
				 * accommodate for it anyway.
567
				 */
568

569
				while (*line == ' ')
570
					line++;
571
				if (*line == ';')
572
					line++;
573
			} else if ((line = strchr(val, ';')) != NULL)
574
				*line++ = '\0';
575

576
			/* White-listed sub-commands. */
577

578
			if (type == MIMETYPE_DISPOSITION) {
579
				if (strcasecmp(key, "filename") == 0)
580
					mime_reset(&mime->file, val);
581
				else if (strcasecmp(key, "name") == 0)
582
					mime_reset(&mime->name, val);
583
			} else if (type == MIMETYPE_TYPE) {
584
				if (strcasecmp(key, "boundary") == 0)
585
					mime_reset(&mime->bound, val);
586
			}
587
		}
588
	} 
589

590
	mime->ctypepos = str2ctype(pp, mime->ctype);
591

592
	if (!rc)
593
		kutil_warnx(NULL, NULL, "RFC error: unexpected "
594
			"end of file while parsing MIME headers");
595

596
	return rc;
597
}
598

599
/*
600
 * Parse keys and values separated by newlines.
601
 * I'm not aware of any standard that defines this, but the W3
602
 * guidelines for HTML give a rough idea.
603
 * FIXME: deprecate this.
604
 */
605
static void
606
parse_pairs_text(const struct parms *pp, char *p)
607
{
608
	char	*key, *val;
609

610
	kutil_warnx(NULL, NULL, "RFC warning: "
611
		"text/plain encoding is deprecated");
612

613
	while (p != NULL && *p != '\0') {
614
		while (*p == ' ')
615
			p++;
616

617
		/* 
618
		 * Key/value pair.
619
		 * No value is a warning (not processed).
620
		 */
621

622
		key = p;
623
		val = NULL;
624
		if (NULL != (p = strchr(p, '='))) {
625
			*p++ = '\0';
626
			val = p;
627
			if ((p = strstr(val, "\r\n")) != NULL) {
628
				*p = '\0';
629
				p += 2;
630
			}
631
		} else {
632
			if ((p = strstr(key, "\r\n")) != NULL) {
633
				*p = '\0';
634
				p += 2;
635
			}
636
			kutil_warnx(NULL, NULL, "RFC warning: "
637
				"key with no value");
638
			continue;
639
		}
640

641
		if (*key == '\0')
642
			kutil_warnx(NULL, NULL, "RFC warning: "
643
				"zero-length key");
644
		else
645
			output(pp, key, val, strlen(val), NULL);
646
	}
647
}
648

649
/*
650
 * Parse an HTTP message that has a given content-type.
651
 * This happens with, e.g., PUT requests.
652
 * We fake up a "name" for this (it's not really a key-value pair) of an
653
 * empty string, then pass that to the validator and forwarder.
654
 */
655
static void
656
parse_body(const char *ct, const struct parms *pp, char *b, size_t bsz)
657
{
658
	char		 name;
659
	struct mime	 mime;
660

661
	memset(&mime, 0, sizeof(struct mime));
662

663
	if ((mime.ctype = kxstrdup(ct)) == NULL)
664
		_exit(EXIT_FAILURE);
665
	mime.ctypepos = str2ctype(pp, mime.ctype);
666

667
	name = '\0';
668
	output(pp, &name, b, bsz, &mime);
669
	free(mime.ctype);
670
}
671

672
/*
673
 * Parse out key-value pairs from an HTTP cookie.
674
 * These are not URL encoded (at this phase): they're just simple
675
 * key-values "crumbs" with opaque values.
676
 * This is defined by RFC 6265, however, we don't [yet] do the
677
 * quoted-string implementation, nor do we check for accepted
678
 * characters so long as the delimiters aren't used.
679
 */
680
static void
681
parse_pairs(const struct parms *pp, char *p)
682
{
683
	char	*key, *val;
684

685
	while (p != NULL && *p != '\0') {
686
		while (*p == ' ')
687
			p++;
688

689
		/* 
690
		 * Don't allow key-pair without a value.
691
		 * Keys shouldn't be zero-length.
692
		 */
693

694
		key = p;
695
		val = NULL;
696
		if ((p = strchr(p, '=')) != NULL) {
697
			*p++ = '\0';
698
			val = p;
699
			if ((p = strchr(p, ';')) != NULL)
700
				*p++ = '\0';
701
		} else {
702
			if ((p = strchr(key, ';')) != NULL)
703
				p++;
704
			kutil_warnx(NULL, NULL, "RFC error: "
705
				"cookie key pair without value");
706
			continue;
707
		}
708

709
		/* This is sort-of allowed. */
710

711
		if (*key == '\0')
712
			kutil_warnx(NULL, NULL, "RFC warning: "
713
				"cookie zero-length key");
714
		else
715
			output(pp, key, val, strlen(val), NULL);
716
	}
717
}
718

719
/*
720
 * Parse out key-value pairs from an HTTP request variable.
721
 * This is either a POST or GET string.
722
 * This MUST be a non-binary (i.e., NUL-terminated) string!
723
 */
724
static void
725
parse_pairs_urlenc(const struct parms *pp, char *p)
726
{
727
	char	*key, *val;
728

729
	assert(p != NULL);
730

731
	while (*p != '\0') {
732
		while (*p == ' ')
733
			p++;
734

735
		key = p;
736

737
		/* 
738
		 * Look ahead to either '=' or one of the key-value
739
		 * terminators (or the end of the string).
740
		 * If we have the equal sign, then we're a key-value
741
		 * pair; otherwise, we're a standalone key value.
742
		 */
743

744
		p += strcspn(p, "=;&");
745

746
		if (*p == '=') {
747
			*p++ = '\0';
748
			val = p;
749
			p += strcspn(p, ";&");
750
		} else
751
			val = p;
752

753
		if (*p != '\0')
754
			*p++ = '\0';
755

756
		/*
757
		 * Both the key and the value can be URL encoded, so
758
		 * decode those into the character string now.
759
		 * If decoding fails, don't decode the given pair, but
760
		 * instead move on to the next one after logging the
761
		 * failure.
762
		 */
763

764
		if (*key == '\0')
765
			kutil_warnx(NULL, NULL, "RFC warning: "
766
				"zero-length URL-encoded key");
767
		else if (khttp_urldecode_inplace(key) == KCGI_FORM)
768
			kutil_warnx(NULL, NULL, "RFC warning: "
769
				"malformed key URL-encoding");
770
		else if (khttp_urldecode_inplace(val) == KCGI_FORM)
771
			kutil_warnx(NULL, NULL, "RFC warning: "
772
				"malformed value URL-encoding");
773
		else
774
			output(pp, key, val, strlen(val), NULL);
775
	}
776
}
777

778
/*
779
 * This is described by the "multipart-body" BNF part of RFC 2046,
780
 * section 5.1.1.
781
 * We return TRUE if the parse was ok, FALSE if errors occurred (all
782
 * calling parsers should bail too).
783
 */
784
static int
785
parse_multiform(const struct parms *pp, char *name, 
786
	const char *bound, char *buf, size_t len, size_t *pos)
787
{
788
	struct mime	 mime;
789
	size_t		 endpos, bbsz, partsz;
790
	char		*ln, *bb;
791
	int		 rc, first;
792

793
	/* Define our buffer boundary. */
794
	
795
	if ((rc = kxasprintf(&bb, "\r\n--%s", bound)) == -1)
796
		_exit(EXIT_FAILURE);
797

798
	assert(rc > 0);
799
	bbsz = rc;
800
	rc = 0;
801

802
	memset(&mime, 0, sizeof(struct mime));
803

804
	/* Read to the next instance of a buffer boundary. */
805

806
	for (first = 1; *pos < len; first = 0, *pos = endpos) {
807
		/*
808
		 * The (first ? 2 : 0) is because the first prologue
809
		 * boundary will not incur an initial CRLF, so our bb is
810
		 * past the CRLF and two bytes smaller.
811
		 */
812

813
		ln = memmem(&buf[*pos], len - *pos, 
814
			bb + (first ? 2 : 0), 
815
			bbsz - (first ? 2 : 0));
816

817
		if (ln == NULL) {
818
			kutil_warnx(NULL, NULL, "RFC error: "
819
				"EOF when scanning for boundary");
820
			goto out;
821
		}
822

823
		/* 
824
		 * Set "endpos" to point to the beginning of the next
825
		 * multipart component, i.e, the end of the boundary
826
		 * "bb" string.
827
		 * Again, be respectful of whether we should scan after
828
		 * the lack of initial CRLF.
829
		 */
830

831
		endpos = *pos + (ln - &buf[*pos]) + 
832
			bbsz - (first ? 2 : 0);
833

834
		/* Check buffer space. */
835

836
		if (endpos > len - 2) {
837
			kutil_warnx(NULL, NULL, "RFC error: multipart "
838
				"section writes into trailing CRLF");
839
			goto out;
840
		}
841

842
		/* 
843
		 * Terminating boundary has an initial trailing "--".
844
		 * If not terminating, must be followed by a CRLF.
845
		 * If terminating, RFC 1341 says we can ignore whatever
846
		 * comes after the last boundary.
847
		 */
848

849
		if (memcmp(&buf[endpos], "--", 2)) {
850
			while (endpos < len && buf[endpos] == ' ')
851
				endpos++;
852
			if (endpos > len - 2 ||
853
			    memcmp(&buf[endpos], "\r\n", 2)) {
854
				kutil_warnx(NULL, NULL, "RFC error: "
855
					"multipart boundary without "
856
					"CRLF");
857
				goto out;
858
			}
859
			endpos += 2;
860
		} else
861
			endpos = len;
862

863
		/* First section: jump directly to reprocess. */
864

865
		if (first)
866
			continue;
867

868
		/* 
869
		 * Zero-length part.
870
		 * This shouldn't occur, but if it does, it'll screw up
871
		 * the MIME parsing (which requires a blank CRLF before
872
		 * considering itself finished).
873
		 */
874

875
		if ((partsz = ln - &buf[*pos]) == 0) {
876
			kutil_warnx(NULL, NULL, "RFC error: "
877
				"zero-length multipart section");
878
			continue;
879
		}
880

881
		/* We now read our MIME headers, bailing on error. */
882

883
		if (!mime_parse(pp, &mime, buf, *pos + partsz, pos)) {
884
			kutil_warnx(NULL, NULL, "RFC error: "
885
				"nested error parsing MIME headers");
886
			goto out;
887
		}
888

889
		/* 
890
		 * As per RFC 2388, we need a name and disposition. 
891
		 * Note that multipart/mixed bodies will inherit the
892
		 * name of their parent, so the mime.name is ignored.
893
		 */
894

895
		if (mime.name == NULL && name == NULL) {
896
			kutil_warnx(NULL, NULL, 
897
				"RFC error: no MIME name");
898
			continue;
899
		} else if (mime.disp == NULL) {
900
			kutil_warnx(NULL, NULL, 
901
				"RFC error: no MIME disposition");
902
			continue;
903
		}
904

905
		/* 
906
		 * As per RFC 2045, we default to text/plain.
907
		 * We then re-lookup the ctypepos after doing so.
908
		 */
909

910
		if (mime.ctype == NULL) {
911
			mime.ctype = kxstrdup("text/plain");
912
			if (mime.ctype == NULL)
913
				_exit(EXIT_FAILURE);
914
			mime.ctypepos = str2ctype(pp, mime.ctype);
915
		}
916

917
		partsz = ln - &buf[*pos];
918

919
		/* 
920
		 * Multipart sub-handler. 
921
		 * We only recognise the multipart/mixed handler.
922
		 * This will route into our own function, inheriting the
923
		 * current name for content.
924
		 */
925

926
		if (strcasecmp(mime.ctype, "multipart/mixed") == 0) {
927
			if (mime.bound == NULL) {
928
				kutil_warnx(NULL, NULL, "RFC error: "
929
					"no mixed multipart boundary");
930
				goto out;
931
			}
932
			if (!parse_multiform(pp, 
933
			    name != NULL ? name : mime.name, 
934
			    mime.bound, buf, *pos + partsz, pos)) {
935
				kutil_warnx(NULL, NULL, "RFC error: "
936
					"nested error parsing mixed "
937
					"multipart section");
938
				goto out;
939
			}
940
			continue;
941
		}
942

943
		assert(buf[*pos + partsz] == '\r' || 
944
		       buf[*pos + partsz] == '\0');
945

946
		if (buf[*pos + partsz] != '\0')
947
			buf[*pos + partsz] = '\0';
948

949
		/* Assign all of our key-value pair data. */
950

951
		output(pp, name != NULL ? name : mime.name, 
952
			&buf[*pos], partsz, &mime);
953
	}
954

955
	/*
956
	 * According to the specification, we can have transport
957
	 * padding, a CRLF, then the epilogue.
958
	 * But since we don't care about that crap, just pretend that
959
	 * everything's fine and exit.
960
	 */
961

962
	rc = 1;
963
out:
964
	free(bb);
965
	mime_free(&mime);
966
	return rc;
967
}
968

969
/*
970
 * Parse the boundary from a multipart CONTENT_TYPE and pass it to the
971
 * actual parsing engine.
972
 * This doesn't actually handle any part of the MIME specification.
973
 */
974
static void
975
parse_multi(const struct parms *pp, char *line, char *b, size_t bsz)
976
{
977
	char		*cp;
978
	size_t		 len = 0;
979

980
	while (*line == ' ')
981
		line++;
982

983
	if (*line++ != ';') {
984
		kutil_warnx(NULL, NULL, "RFC error: expected "
985
			"semicolon following multipart declaration");
986
		return;
987
	}
988

989
	while (*line == ' ')
990
		line++;
991

992
	/* We absolutely need the boundary marker. */
993

994
	if (strncmp(line, "boundary", 8)) {
995
		kutil_warnx(NULL, NULL, "RFC error: expected "
996
			"boundary following multipart declaration");
997
		return;
998
	}
999

1000
	line += 8;
1001

1002
	while (*line == ' ')
1003
		line++;
1004

1005
	if (*line++ != '=') {
1006
		kutil_warnx(NULL, NULL, "RFC error: expected "
1007
			"key-value for multipart boundary");
1008
		return;
1009
	}
1010

1011
	while (*line == ' ')
1012
		line++;
1013

1014
	/* 
1015
	 * Make sure the line is terminated in the right place.
1016
	 * XXX: if it's not, what we do may not properly follow RFC
1017
	 * 2046, 5.1.1, which specifically lays out the boundary
1018
	 * characters.
1019
	 * We simply jump to the first whitespace.
1020
	 */
1021

1022
	if (*line == '"') {
1023
		if ((cp = strchr(++line, '"')) == NULL) {
1024
			kutil_warnx(NULL, NULL, "RFC error: "
1025
				"unterminated boundary quoted string");
1026
			return;
1027
		}
1028
		*cp = '\0';
1029
	} else
1030
		line[strcspn(line, " ")] = '\0';
1031

1032
	/*
1033
	 * If we have data following the boundary declaration, we simply
1034
	 * ignore it.
1035
	 * The RFC mandates the existence of the boundary, but is silent
1036
	 * as to whether anything can come after it.
1037
	 */
1038

1039
	parse_multiform(pp, NULL, line, b, bsz, &len);
1040
}
1041

1042
/*
1043
 * Output all of the HTTP_xxx headers.
1044
 * This transforms the HTTP_xxx header (CGI form) into HTTP form, which
1045
 * is the second part title-cased, e.g., HTTP_FOO = Foo.
1046
 * Disallow zero-length values as per RFC 3875, 4.1.18.
1047
 */
1048
static void
1049
kworker_child_env(const struct env *env, int fd, size_t envsz)
1050
{
1051
	size_t	 	 i, j, sz, reqs;
1052
	int		 first;
1053
	enum krequ	 requ;
1054
	char		 c;
1055
	const char	*cp;
1056

1057
	for (reqs = i = 0; i < envsz; i++)
1058
		if (strncmp(env[i].key, "HTTP_", 5) == 0 &&
1059
		    env[i].key[5] != '\0')
1060
			reqs++;
1061

1062
	fullwrite(fd, &reqs, sizeof(size_t));
1063

1064
	/*
1065
	 * Process known headers (starting with HTTP_).
1066
	 * We must have non-zero-length keys.
1067
	 */
1068

1069
	for (i = 0; i < envsz; i++) {
1070
		if (strncmp(env[i].key, "HTTP_", 5) || 
1071
		    env[i].key[5] == '\0')
1072
			continue;
1073

1074
		for (requ = 0; requ < KREQU__MAX; requ++)
1075
			if (strcmp(krequs[requ], env[i].key) == 0)
1076
				break;
1077

1078
		fullwrite(fd, &requ, sizeof(enum krequ));
1079

1080
		/*
1081
		 * According to RFC 3875, 4.1.18, HTTP headers are
1082
		 * re-written into CGI environment variables by
1083
		 * uppercasing and converting dashes to underscores.
1084
		 * In this part, we [try to] reverse that so that the
1085
		 * headers are properly identified.
1086
		 * (We also skip the HTTP_ leading part.)
1087
		 */
1088

1089
		sz = env[i].keysz - 5;
1090
		cp = env[i].key + 5;
1091
		fullwrite(fd, &sz, sizeof(size_t));
1092

1093
		for (j = 0, first = 1; j < sz; j++) {
1094
			if (cp[j] == '_') {
1095
				c = '-';
1096
				first = 1;
1097
			} else if (first) {
1098
				c = cp[j];
1099
				first = 0;
1100
			} else
1101
				c = tolower((unsigned char)cp[j]);
1102

1103
			fullwrite(fd, &c, 1);
1104
		}
1105

1106
		fullwrite(fd, &env[i].valsz, sizeof(size_t));
1107
		fullwrite(fd, env[i].val, env[i].valsz);
1108
	}
1109
}
1110

1111
/*
1112
 * Like getenv() but for our env structure.
1113
 */
1114
static char *
1115
kworker_env(struct env *env, size_t envsz, const char *key)
1116
{
1117
	size_t	 i;
1118

1119
	for (i = 0; i < envsz; i++) 
1120
		if (strcmp(env[i].key, key) == 0)
1121
			return env[i].val;
1122
	return NULL;
1123
}
1124

1125
/*
1126
 * Output the method found in our environment.
1127
 * Returns the method.
1128
 * Defaults to KMETHOD_GET, uses KETHOD__MAX if the method was bad.
1129
 */
1130
static enum kmethod
1131
kworker_child_method(struct env *env, int fd, size_t envsz)
1132
{
1133
	enum kmethod	 meth;
1134
	const char	*cp;
1135

1136
	/* RFC 3875, 4.1.12. */
1137
	/* We assume GET if not supplied. */
1138

1139
	meth = KMETHOD_GET;
1140
	if ((cp = kworker_env(env, envsz, "REQUEST_METHOD")) != NULL)
1141
		for (meth = 0; meth < KMETHOD__MAX; meth++)
1142
			if (strcmp(kmethods[meth], cp) == 0)
1143
				break;
1144

1145
	fullwrite(fd, &meth, sizeof(enum kmethod));
1146
	return meth;
1147
}
1148

1149
/*
1150
 * Output the web server's authentication.
1151
 * Defaults to KAUTH_NONE.
1152
 */
1153
static void
1154
kworker_child_auth(struct env *env, int fd, size_t envsz)
1155
{
1156
	enum kauth	 auth = KAUTH_NONE;
1157
	const char	*cp;	
1158

1159
	/* Determine authentication: RFC 3875, 4.1.1. */
1160

1161
	if ((cp = kworker_env(env, envsz, "AUTH_TYPE")) != NULL)
1162
		for (auth = 0; auth < KAUTH_UNKNOWN; auth++) {
1163
			if (kauths[auth] == NULL)
1164
				continue;
1165
			if (strcmp(kauths[auth], cp) == 0)
1166
				break;
1167
		}
1168

1169
	fullwrite(fd, &auth, sizeof(enum kauth));
1170
}
1171

1172
/*
1173
 * Send the raw (i.e., un-webserver-filtered) authorisation to the
1174
 * parent.
1175
 * Most web servers will `handle this for us'.  Ugh.
1176
 */
1177
static int
1178
kworker_child_rawauth(struct env *env, int fd, size_t envsz)
1179
{
1180

1181
	return kworker_auth_child(fd, 
1182
	  	kworker_env(env, envsz, "HTTP_AUTHORIZATION"));
1183
}
1184

1185
/*
1186
 * Send our HTTP scheme (secure or not) to the parent.
1187
 */
1188
static void
1189
kworker_child_scheme(struct env *env, int fd, size_t envsz)
1190
{
1191
	const char	*cp;
1192
	enum kscheme	 scheme;
1193

1194
	/* 
1195
	 * This isn't defined in any RFC.
1196
	 * It seems to be the best way of getting whether we're HTTPS,
1197
	 * as the SERVER_PROTOCOL (RFC 3875, 4.1.16) doesn't reliably
1198
	 * return the scheme.
1199
	 */
1200

1201
	if ((cp = kworker_env(env, envsz, "HTTPS")) == NULL)
1202
		cp = "off";
1203

1204
	scheme = strcasecmp(cp, "on") == 0 ?
1205
		KSCHEME_HTTPS : KSCHEME_HTTP;
1206
	fullwrite(fd, &scheme, sizeof(enum kscheme));
1207
}
1208

1209
/*
1210
 * Send remote address to the parent.
1211
 * This is required by RFC 3875, 4.1.8.
1212
 * Use 127.0.0.1 on protocol violation.
1213
 */
1214
static void
1215
kworker_child_remote(struct env *env, int fd, size_t envsz)
1216
{
1217
	const char	*cp;
1218

1219
	if ((cp = kworker_env(env, envsz, "REMOTE_ADDR")) == NULL) {
1220
		kutil_warnx(NULL, NULL, "RFC warning: "
1221
			"remote address not set");
1222
		cp = "127.0.0.1";
1223
	}
1224

1225
	fullwriteword(fd, cp);
1226
}
1227

1228
/*
1229
 * Parse and send the port to the parent.
1230
 * This is required by RFC 3875, 4.1.15.
1231
 * Use port 80 if not provided or on parse error.
1232
 */
1233
static void
1234
kworker_child_port(struct env *env, int fd, size_t envsz)
1235
{
1236
	uint16_t	 port = 80;
1237
	const char	*cp, *er;
1238

1239
	if ((cp = kworker_env(env, envsz, "SERVER_PORT")) != NULL) {
1240
		port = strtonum(cp, 0, UINT16_MAX, &er);
1241
		if (er != NULL) {
1242
			kutil_warnx(NULL, NULL, "RFC warning: "
1243
				"invalid server port value");
1244
			port = 80;
1245
		}
1246
	} else
1247
		kutil_warnx(NULL, NULL, "RFC warning: "
1248
			"server port not set");
1249

1250
	fullwrite(fd, &port, sizeof(uint16_t));
1251
}
1252

1253
/*
1254
 * Send requested host to the parent.
1255
 * This is required by RFC 7230, 5.4.
1256
 * Use "localhost" if not provided.
1257
 */
1258
static void
1259
kworker_child_httphost(struct env *env, int fd, size_t envsz)
1260
{
1261
	const char	*cp;
1262

1263
	if ((cp = kworker_env(env, envsz, "HTTP_HOST")) == NULL) {
1264
		kutil_warnx(NULL, NULL, "RFC warning: host not set");
1265
		cp = "localhost";
1266
	}
1267

1268
	fullwriteword(fd, cp);
1269
}
1270

1271
/* 
1272
 * Send script name to the parent.
1273
 * This is required by RFC 3875, 4.1.13.
1274
 * Use the empty string on error.
1275
 */
1276
static void
1277
kworker_child_scriptname(struct env *env, int fd, size_t envsz)
1278
{
1279
	const char	*cp;
1280

1281
	if ((cp = kworker_env(env, envsz, "SCRIPT_NAME")) == NULL) {
1282
		kutil_warnx(NULL, NULL, "RFC warning: "
1283
			"script name not set");
1284
		cp = "";
1285
	}
1286

1287
	fullwriteword(fd, cp);
1288
}
1289

1290
/*
1291
 * Parse all path information (subpath, path, etc.) and send to parent.
1292
 */
1293
static void
1294
kworker_child_path(struct env *env, int fd, size_t envsz)
1295
{
1296
	char	*cp, *ep, *sub;
1297
	size_t	 len;
1298

1299
	/*
1300
	 * Parse the first path element (the page we want to access),
1301
	 * subsequent path information, and the file suffix.  We convert
1302
	 * suffix and path element into the respective enum's inline.
1303
	 */
1304

1305
	cp = kworker_env(env, envsz, "PATH_INFO");
1306
	fullwriteword(fd, cp);
1307

1308
	/* This isn't possible in the real world. */
1309

1310
	if (cp != NULL && *cp == '/')
1311
		cp++;
1312

1313
	if (cp != NULL && *cp != '\0') {
1314
		ep = cp + strlen(cp) - 1;
1315
		while (ep > cp && *ep != '/' && *ep != '.')
1316
			ep--;
1317

1318
		/* Start with writing our suffix. */
1319

1320
		if (*ep == '.') {
1321
			*ep++ = '\0';
1322
			fullwriteword(fd, ep);
1323
		} else
1324
			fullwriteword(fd, NULL);
1325

1326
		/* Now find the top-most path part. */
1327

1328
		if ((sub = strchr(cp, '/')) != NULL)
1329
			*sub++ = '\0';
1330

1331
		/* Send the base path. */
1332

1333
		fullwriteword(fd, cp);
1334

1335
		/* Send the path part. */
1336

1337
		fullwriteword(fd, sub);
1338
	} else {
1339
		len = 0;
1340

1341
		/* Suffix, base path, and path part. */
1342

1343
		fullwrite(fd, &len, sizeof(size_t));
1344
		fullwrite(fd, &len, sizeof(size_t));
1345
		fullwrite(fd, &len, sizeof(size_t));
1346
	}
1347
}
1348

1349
/*
1350
 * Construct the body hash component of an HTTP digest hash.
1351
 * See khttpdigest_validatehash(3) for where this is used.
1352
 * See RFC 2617.
1353
 * We only do this if our authorisation requires it!
1354
 */
1355
static void
1356
kworker_child_bodymd5(int fd, const char *b, size_t bsz, int md5)
1357
{
1358
	MD5_CTX		 ctx;
1359
	unsigned char 	 hab[MD5_DIGEST_LENGTH];
1360
	size_t		 sz;
1361

1362
	if (!md5) {
1363
		sz = 0;
1364
		fullwrite(fd, &sz, sizeof(size_t));
1365
		return;
1366
	}
1367

1368
	MD5Init(&ctx);
1369
	MD5Updatec(&ctx, b, bsz);
1370
	MD5Final(hab, &ctx);
1371

1372
	/* This is a binary write! */
1373

1374
	sz = MD5_DIGEST_LENGTH;
1375
	fullwrite(fd, &sz, sizeof(size_t));
1376
	fullwrite(fd, hab, sz);
1377
}
1378

1379
/*
1380
 * Parse and send the body of the request to the parent.
1381
 * This is arguably the most complex part of the system.
1382
 */
1383
static void
1384
kworker_child_body(struct env *env, int fd, size_t envsz,
1385
	struct parms *pp, enum kmethod meth, char *b, 
1386
	size_t bsz, unsigned int debugging, int md5)
1387
{
1388
	size_t		 i, len = 0, sz;
1389
	char		*cp, *bp = b;
1390
	const char	*end;
1391
	int		 wrap;
1392

1393
	/*
1394
	 * The CONTENT_LENGTH must be a valid integer.
1395
	 * Since we're storing into "len", make sure it's in size_t.
1396
	 * If there's an error, it will default to zero.
1397
	 * Note that LLONG_MAX < SIZE_MAX.
1398
	 * RFC 3875, 4.1.2.
1399
	 */
1400

1401
	if ((cp = kworker_env(env, envsz, "CONTENT_LENGTH")) != NULL)
1402
		len = strtonum(cp, 0, LLONG_MAX, NULL);
1403

1404
	/* If zero, remember to print our MD5 value. */
1405

1406
	if (len == 0) {
1407
		kworker_child_bodymd5(fd, "", 0, md5);
1408
		return;
1409
	}
1410

1411
	/* Check FastCGI input lengths. */
1412

1413
	if (bp != NULL && bsz != len)
1414
		kutil_warnx(NULL, NULL, "RFC warning: real (%zu) "
1415
			"and reported (%zu) content lengths differ", 
1416
			bsz, len);
1417

1418
	/*
1419
	 * If a CONTENT_TYPE has been specified (i.e., POST or GET has
1420
	 * been set -- we don't care which), then switch on that type
1421
	 * for parsing out key value pairs.
1422
	 * RFC 3875, 4.1.3.
1423
	 * HTML5, 4.10.
1424
	 * We only support the main three content types.
1425
	 */
1426

1427
	pp->type = IN_FORM;
1428
	cp = kworker_env(env, envsz, "CONTENT_TYPE");
1429

1430
	/* 
1431
	 * If we're CGI, read the request now.
1432
	 * Note that the "bsz" can come out as zero.
1433
	 */
1434

1435
	if (b == NULL)
1436
		b = scanbuf(len, &bsz);
1437

1438
	assert(b != NULL);
1439

1440
	/* If requested, print our MD5 value. */
1441

1442
	kworker_child_bodymd5(fd, b, bsz, md5);
1443

1444
	/*
1445
	 * If we're debugging read bodies, emit the body line by line
1446
	 * (or split at the 80-character mark).
1447
	 */
1448

1449
	if (bsz && (debugging & KREQ_DEBUG_READ_BODY)) {
1450
		i = 0;
1451
		do {
1452
			if ((end = memchr(&b[i], '\n', bsz - i)) == NULL)
1453
				sz = bsz - i;
1454
			else
1455
				sz = (size_t)(end - &b[i]);
1456
			if ((wrap = sz > 80))
1457
				sz = 80;
1458
			kutil_info(NULL, NULL, "%lu-rx: %.*s%s",
1459
				(unsigned long)getpid(), (int)sz, 
1460
				&b[i], wrap ? "..." : "");
1461

1462
			i += wrap ? sz : sz + 1;
1463
		} while (i < bsz);
1464
		kutil_info(NULL, NULL, "%lu-rx: %zu B",
1465
			(unsigned long)getpid(), bsz);
1466
	}
1467

1468
	if (cp != NULL) {
1469
		if (strcasecmp(cp, "application/x-www-form-urlencoded") == 0)
1470
			parse_pairs_urlenc(pp, b);
1471
		else if (strncasecmp(cp, "multipart/form-data", 19) == 0) 
1472
			parse_multi(pp, cp + 19, b, bsz);
1473
		else if (meth == KMETHOD_POST && strcasecmp(cp, "text/plain") == 0)
1474
			parse_pairs_text(pp, b);
1475
		else
1476
			parse_body(cp, pp, b, bsz);
1477
	} else
1478
		parse_body(kmimetypes[KMIME_APP_OCTET_STREAM], pp, b, bsz);
1479

1480
	/* Free CGI parsed buffer (FastCGI is done elsewhere). */
1481

1482
	if (bp == NULL)
1483
		free(b);
1484
}
1485

1486
/*
1487
 * Send query string data to parent.
1488
 * Even POST requests are allowed to have QUERY_STRING elements.
1489
 * Note: both QUERY_STRING and CONTENT_TYPE fields share the same field
1490
 * space.
1491
 */
1492
static void
1493
kworker_child_query(struct env *env, 
1494
	int fd, size_t envsz, struct parms *pp)
1495
{
1496
	char 	*cp;
1497

1498
	pp->type = IN_QUERY;
1499
	if (NULL != (cp = kworker_env(env, envsz, "QUERY_STRING")))
1500
		parse_pairs_urlenc(pp, cp);
1501
}
1502

1503
/*
1504
 * Send cookies to our parent.
1505
 * These use the same syntax as QUERY_STRING elements, but don't share
1506
 * the same namespace (just as a means to differentiate the same names).
1507
 */
1508
static void
1509
kworker_child_cookies(struct env *env, 
1510
	int fd, size_t envsz, struct parms *pp)
1511
{
1512
	char	*cp;
1513

1514
	pp->type = IN_COOKIE;
1515
	if ((cp = kworker_env(env, envsz, "HTTP_COOKIE")) != NULL)
1516
		parse_pairs(pp, cp);
1517
}
1518

1519
/*
1520
 * Terminate the input fields for the parent. 
1521
 */
1522
static void
1523
kworker_child_last(int fd)
1524
{
1525
	enum input last = IN__MAX;
1526

1527
	fullwrite(fd, &last, sizeof(enum input));
1528
}
1529

1530
/*
1531
 * This is the child kcgi process that's going to do the unsafe reading
1532
 * of network data to parse input.
1533
 * When it parses a field, it outputs the key, key size, value, and
1534
 * value size along with the field type.
1535
 * We use the CGI specification in RFC 3875.
1536
 */
1537
enum kcgi_err
1538
kworker_child(int wfd,
1539
	const struct kvalid *keys, size_t keysz, 
1540
	const char *const *mimes, size_t mimesz,
1541
	unsigned int debugging)
1542
{
1543
	struct parms	  pp;
1544
	char		 *cp;
1545
	const char	 *start;
1546
	char		**evp;
1547
	int		  md5;
1548
	enum kmethod	  meth;
1549
	size_t	 	  i;
1550
	extern char	**environ;
1551
	struct env	 *envs = NULL;
1552
	size_t		  envsz;
1553

1554
	pp.fd = wfd;
1555
	pp.keys = keys;
1556
	pp.keysz = keysz;
1557
	pp.mimes = mimes;
1558
	pp.mimesz = mimesz;
1559

1560
	/*
1561
	 * Pull the entire environment into an array.
1562
	 */
1563
	for (envsz = 0, evp = environ; NULL != *evp; evp++) 
1564
		envsz++;
1565

1566
	if (envsz) {
1567
		envs = kxcalloc(envsz, sizeof(struct env));
1568
		if (envs == NULL)
1569
			return KCGI_ENOMEM;
1570
	}
1571

1572
	/* 
1573
	 * Pull all reasonable values from the environment into "envs".
1574
	 * Filter out variables that don't meet RFC 3875, section 4.1.
1575
	 * However, we're a bit more relaxed: we don't let through
1576
	 * zero-length, non-ASCII, control characters, and whitespace.
1577
	 */
1578

1579
	for (i = 0, evp = environ; *evp != NULL; evp++) {
1580
		if ((cp = strchr(*evp, '=')) == NULL || cp == *evp)
1581
			continue;
1582
		for (start = *evp; *start != '='; start++)
1583
			if (!isascii((unsigned char)*start) ||
1584
			    !isgraph((unsigned char)*start))
1585
				break;
1586

1587
		/* 
1588
		 * This means something is seriously wrong, so make sure
1589
		 * that the operator knows.
1590
		 */
1591

1592
		if (*start != '=') {
1593
			kutil_warnx(NULL, NULL, "RFC warning: "
1594
				"bad character in environment pair");
1595
			continue;
1596
		}
1597

1598
		assert(i < envsz);
1599

1600
		if ((envs[i].key = kxstrdup(*evp)) == NULL)
1601
			_exit(EXIT_FAILURE);
1602
		envs[i].val = strchr(envs[i].key, '=');
1603
		*envs[i].val++ = '\0';
1604
		envs[i].keysz = strlen(envs[i].key);
1605
		envs[i].valsz = strlen(envs[i].val);
1606
		i++;
1607
	}
1608

1609
	/* Reset this, accounting for crappy entries. */
1610

1611
	envsz = i;
1612

1613
	/*
1614
	 * Now run a series of transmissions based upon what's in our
1615
	 * environment.
1616
	 */
1617

1618
	kworker_child_env(envs, wfd, envsz);
1619
	meth = kworker_child_method(envs, wfd, envsz);
1620
	kworker_child_auth(envs, wfd, envsz);
1621
	md5 = kworker_child_rawauth(envs, wfd, envsz);
1622
	kworker_child_scheme(envs, wfd, envsz);
1623
	kworker_child_remote(envs, wfd, envsz);
1624
	kworker_child_path(envs, wfd, envsz);
1625
	kworker_child_scriptname(envs, wfd, envsz);
1626
	kworker_child_httphost(envs, wfd, envsz);
1627
	kworker_child_port(envs, wfd, envsz);
1628

1629
	/* And now the message body itself. */
1630

1631
	kworker_child_body(envs, wfd, envsz, 
1632
		&pp, meth, NULL, 0, debugging, md5);
1633
	kworker_child_query(envs, wfd, envsz, &pp);
1634
	kworker_child_cookies(envs, wfd, envsz, &pp);
1635
	kworker_child_last(wfd);
1636

1637
	/* Note: the "val" is from within the key. */
1638

1639
	for (i = 0; i < envsz; i++) 
1640
		free(envs[i].key);
1641
	free(envs);
1642
	return KCGI_OK;
1643
}
1644

1645
/*
1646
 * Reads from the FastCGI control process, kfcgi_control(), are buffered
1647
 * according to what the control process can read from the web server.
1648
 * Here we read ahead til we have enough data for what currently needs
1649
 * to be read.
1650
 * Returns a pointer to the data of size "sz" or NULL if errors occured.
1651
 * If error is KCGI_OK, this *always* returns a buffer.
1652
 * The error is reported in "er".
1653
 */
1654
static char *
1655
kworker_fcgi_read(struct fcgi_buf *b, size_t nsz, enum kcgi_err *er)
1656
{
1657
	void	*pp;
1658
	int	 rc;
1659
	size_t	 sz;
1660

1661
again:
1662
	*er = KCGI_OK;
1663
	if (b->pos + nsz <= b->sz) {
1664
		b->pos += nsz;
1665
		return &b->buf[b->pos - nsz];
1666
	}
1667

1668
	/* Fill up the next frame. */
1669

1670
	rc = fullread(b->fd, &sz, sizeof(size_t), 0, er);
1671
	if (rc <= 0) {
1672
		kutil_warnx(NULL, NULL, "FastCGI: "
1673
			"error reading frame size from control");
1674
		return NULL;
1675
	} else if (sz == 0) {
1676
		kutil_warnx(NULL, NULL, "FastCGI: connection "
1677
			"closed while reading frame size");
1678
		*er = KCGI_HUP;
1679
		return NULL;
1680
	} 
1681

1682
	if ((pp = kxrealloc(b->buf, b->sz + sz)) == NULL) {
1683
		*er = KCGI_ENOMEM;
1684
		return NULL;
1685
	}
1686

1687
	b->buf = pp;
1688
	rc = fullread(b->fd, b->buf + b->sz, sz, 0, er);
1689
	if (rc <= 0) {
1690
		kutil_warnx(NULL, NULL, "FastCGI: error "
1691
			"reading frame data from control");
1692
		return NULL;
1693
	}
1694

1695
	b->sz += sz;
1696
	goto again;
1697
}
1698

1699

1700
/*
1701
 * Read the FastCGI header (see section 8, Types and Contents,
1702
 * FCGI_Header, in the FastCGI Specification v1.0).
1703
 * Return KCGI_OK on success, KCGI_HUP on connection close, KCGI_FORM
1704
 * with FastCGI protocol errors, and a fatal error otherwise.
1705
 */
1706
static enum kcgi_err
1707
kworker_fcgi_header(struct fcgi_buf *b, struct fcgi_hdr *hdr)
1708
{
1709
	enum kcgi_err	 er;
1710
	const char	*cp;
1711
	struct fcgi_hdr	 buf;
1712

1713
	if ((cp = kworker_fcgi_read(b, 8, &er)) == NULL)
1714
		return er;
1715

1716
	memcpy(&buf, cp, 8);
1717

1718
	/* Translate from network-byte order. */
1719

1720
	hdr->version = buf.version;
1721
	hdr->type = buf.type;
1722
	hdr->requestId = ntohs(buf.requestId);
1723
	hdr->contentLength = ntohs(buf.contentLength);
1724
	hdr->paddingLength = buf.paddingLength;
1725

1726
	if (hdr->version == 1)
1727
		return KCGI_OK;
1728

1729
	kutil_warnx(NULL, NULL, "FastCGI: bad header "
1730
		"version: %" PRIu8 " (want 1)", hdr->version);
1731
	return KCGI_FORM;
1732
}
1733

1734
/*
1735
 * Read in the entire header and data for the begin sequence request.
1736
 * This is defined in section 5.1 of the v1.0 specification.
1737
 * Return KCGI_OK on success, KCGI_HUP on connection close, KCGI_FORM
1738
 * with FastCGI protocol errors, and a fatal error otherwise.
1739
 */
1740
static enum kcgi_err
1741
kworker_fcgi_begin(struct fcgi_buf *b, uint16_t *rid)
1742
{
1743
	struct fcgi_hdr	 hdr;
1744
	const struct fcgi_bgn *ptr;
1745
	const char	*buf;
1746
	enum kcgi_err	 er;
1747

1748
	/* Read the header entry. */
1749

1750
	if ((er = kworker_fcgi_header(b, &hdr)) != KCGI_OK)
1751
		return er;
1752

1753
	*rid = hdr.requestId;
1754

1755
	if (hdr.type != FCGI_BEGIN_REQUEST) {
1756
		kutil_warnx(NULL, NULL, "FastCGI: bad type: %" PRIu8 
1757
			" (want %d)", hdr.type, FCGI_BEGIN_REQUEST);
1758
		return KCGI_FORM;
1759
	} 
1760
	
1761
	/* Read the "begin" content and discard padding. */
1762

1763
	buf = kworker_fcgi_read(b, 
1764
		hdr.contentLength + 
1765
		hdr.paddingLength, &er);
1766

1767
	ptr = (const struct fcgi_bgn *)buf;
1768

1769
	if (ptr->flags) {
1770
		kutil_warnx(NULL, NULL, "FastCGI: bad flags: %" PRId8 
1771
			" (want 0)", ptr->flags);
1772
		return KCGI_FORM;
1773
	}
1774

1775
	return KCGI_OK;
1776
}
1777

1778
/*
1779
 * Read in a data stream as defined within section 5.3 of the v1.0
1780
 * specification.
1781
 * We might have multiple stdin buffers for the same data, so always
1782
 * append to the existing NUL-terminated buffer.
1783
 * Return KCGI_OK on success, KCGI_HUP on connection close, KCGI_FORM
1784
 * with FastCGI protocol errors, and a fatal error otherwise.
1785
 */
1786
static enum kcgi_err
1787
kworker_fcgi_stdin(struct fcgi_buf *b, const struct fcgi_hdr *hdr,
1788
	unsigned char **sbp, size_t *ssz)
1789
{
1790
	enum kcgi_err	 er;
1791
	void		*ptr;
1792
	char		*bp;
1793

1794
	/* Read the "begin" content and discard padding. */
1795

1796
	bp = kworker_fcgi_read(b, 
1797
		hdr->contentLength + 
1798
		hdr->paddingLength, &er);
1799

1800
	/* 
1801
	 * Short-circuit: no data to read.
1802
	 * The caller should detect this and stop reading from the
1803
	 * FastCGI connection.
1804
	 */
1805

1806
	if (hdr->contentLength == 0)
1807
		return KCGI_OK;
1808

1809
	/* 
1810
	 * Use another buffer for the stdin.
1811
	 * This is because our buffer (b->buf) consists of FastCGI
1812
	 * frames (data interspersed with control information).
1813
	 * Obviously, we want to extract our data from that.
1814
	 * Make sure it's NUL-terminated!
1815
	 * FIXME: check for addition overflow.
1816
	 */
1817

1818
	ptr = kxrealloc(*sbp, *ssz + hdr->contentLength + 1);
1819
	if (ptr == NULL)
1820
		return KCGI_ENOMEM;
1821

1822
	*sbp = ptr;
1823
	memcpy(*sbp + *ssz, bp, hdr->contentLength);
1824
	(*sbp)[*ssz + hdr->contentLength] = '\0';
1825
	*ssz += hdr->contentLength;
1826
	return KCGI_OK;
1827
}
1828

1829
/*
1830
 * Read out a series of parameters contained within a FastCGI parameter
1831
 * request defined in section 5.2 of the v1.0 specification.
1832
 * Return KCGI_OK on success, KCGI_HUP on connection close, KCGI_FORM
1833
 * with FastCGI protocol errors, and a fatal error otherwise.
1834
 */
1835
static enum kcgi_err
1836
kworker_fcgi_params(struct fcgi_buf *buf, const struct fcgi_hdr *hdr, 
1837
	struct env **envs, size_t *envsz)
1838
{
1839
	size_t	 	 i, remain, pos, keysz, valsz;
1840
	const unsigned char *b;
1841
	enum kcgi_err	 er;
1842
	void		*ptr;
1843

1844
	b = (unsigned char *)kworker_fcgi_read
1845
		(buf, hdr->contentLength + 
1846
		 hdr->paddingLength, &er);
1847

1848
	if (b == NULL)
1849
		return er;
1850

1851
	/*
1852
	 * Loop through the string data that's laid out as a key length
1853
	 * then value length, then key, then value.
1854
	 * There can be arbitrarily many key-values per string.
1855
	 */
1856

1857
	remain = hdr->contentLength;
1858
	pos = 0;
1859

1860
	while (remain > 0) {
1861
		/* First read the lengths. */
1862
		assert(pos < hdr->contentLength);
1863
		if (0 != b[pos] >> 7) {
1864
			if (remain <= 3) {
1865
				kutil_warnx(NULL, NULL, 
1866
					"FastCGI: bad parameter data");
1867
				return 0;
1868
			}
1869
			keysz = ((b[pos] & 0x7f) << 24) + 
1870
				  (b[pos + 1] << 16) + 
1871
				  (b[pos + 2] << 8) + b[pos + 3];
1872
			pos += 4;
1873
			remain -= 4;
1874
		} else {
1875
			keysz = b[pos];
1876
			pos++;
1877
			remain--;
1878
		}
1879

1880
		if (remain < 1) {
1881
			kutil_warnx(NULL, NULL, 
1882
				"FastCGI: bad parameter data");
1883
			return KCGI_FORM;
1884
		}
1885

1886
		assert(pos < hdr->contentLength);
1887
		if (0 != b[pos] >> 7) {
1888
			if (remain <= 3) {
1889
				kutil_warnx(NULL, NULL, 
1890
					"FastCGI: bad parameter data");
1891
				return KCGI_FORM;
1892
			}
1893
			valsz = ((b[pos] & 0x7f) << 24) + 
1894
				  (b[pos + 1] << 16) + 
1895
				  (b[pos + 2] << 8) + b[pos + 3];
1896
			pos += 4;
1897
			remain -= 4;
1898
		} else {
1899
			valsz = b[pos];
1900
			pos++;
1901
			remain--;
1902
		}
1903

1904
		/* Make sure we have room for data. */
1905

1906
		if (pos + keysz + valsz > hdr->contentLength) {
1907
			kutil_warnx(NULL, NULL, 
1908
				"FastCGI: bad parameter data");
1909
			return KCGI_FORM;
1910
		}
1911

1912
		remain -= keysz;
1913
		remain -= valsz;
1914

1915
		/* 
1916
		 * First, make sure that the key is valid.
1917
		 * There's no documented precedent for this, so we
1918
		 * follow CGI's constraints in RFC 3875, sec. 4.1.
1919
		 * If it's not valid, just skip it.
1920
		 */
1921

1922
		for (i = 0; i < keysz; i++)
1923
			if (!isascii((unsigned char)b[pos + i]) ||
1924
			    !isgraph((unsigned char)b[pos + i]))
1925
				break;
1926

1927
		if (keysz == 0) {
1928
			kutil_warnx(NULL, NULL, "FastCGI warning: "
1929
				"empty environment parameter");
1930
			pos += valsz;
1931
			continue;
1932
		} else if (i < keysz) {
1933
			kutil_warnx(NULL, NULL, "RFC warning: bad "
1934
				"character in environment parameters");
1935
			pos += keysz + valsz;
1936
			continue;
1937
		}
1938

1939
		/* Look up the key in our existing keys. */
1940

1941
		for (i = 0; i < *envsz; i++) {
1942
			if ((*envs)[i].keysz != keysz)
1943
				continue;
1944
			if (memcmp((*envs)[i].key, &b[pos], keysz) == 0)
1945
				break;
1946
		}
1947

1948
		/* 
1949
		 * If we don't have the key: expand our table. 
1950
		 * If we do, clear the current value.
1951
		 */
1952

1953
		if (i == *envsz) {
1954
			ptr = kxreallocarray
1955
				(*envs, *envsz + 1, 
1956
				 sizeof(struct env));
1957
			if (ptr == NULL)
1958
				return KCGI_ENOMEM;
1959

1960
			*envs = ptr;
1961
			(*envs)[i].key = kxmalloc(keysz + 1);
1962
			if ((*envs)[i].key == NULL)
1963
				return KCGI_ENOMEM;
1964

1965
			memcpy((*envs)[i].key, &b[pos], keysz);
1966
			(*envs)[i].key[keysz] = '\0';
1967
			(*envs)[i].keysz = keysz;
1968
			(*envsz)++;
1969
		} else
1970
			free((*envs)[i].val);
1971

1972
		pos += keysz;
1973

1974
		/* Copy the value. */
1975

1976
		(*envs)[i].val = kxmalloc(valsz + 1);
1977
		if ((*envs)[i].val == NULL)
1978
			return KCGI_ENOMEM;
1979

1980
		memcpy((*envs)[i].val, &b[pos], valsz);
1981
		(*envs)[i].val[valsz] = '\0';
1982
		(*envs)[i].valsz = valsz;
1983

1984
		pos += valsz;
1985
	}
1986

1987
	return KCGI_OK;
1988
}
1989

1990
/*
1991
 * This is executed by the untrusted child for FastCGI setups.
1992
 * Throughout, we follow the FastCGI specification, version 1.0, 29
1993
 * April 1996.
1994
 */
1995
void
1996
kworker_fcgi_child(int wfd, int work_ctl,
1997
	const struct kvalid *keys, size_t keysz, 
1998
	const char *const *mimes, size_t mimesz,
1999
	unsigned int debugging)
2000
{
2001
	struct parms 	 pp;
2002
	struct fcgi_hdr	 hdr;
2003
	enum kcgi_err	 er;
2004
	unsigned char	*sbuf = NULL;
2005
	struct env	*envs = NULL;
2006
	uint16_t	 rid;
2007
	uint32_t	 cookie = 0;
2008
	size_t		 i, ssz = 0, sz, envsz = 0;
2009
	int		 rc, md5;
2010
	enum kmethod	 meth;
2011
	struct fcgi_buf	 fbuf;
2012

2013
	memset(&fbuf, 0, sizeof(struct fcgi_buf));
2014

2015
	pp.fd = wfd;
2016
	pp.keys = keys;
2017
	pp.keysz = keysz;
2018
	pp.mimes = mimes;
2019
	pp.mimesz = mimesz;
2020

2021
	/*
2022
	 * Loop over all incoming sequences to this particular slave.
2023
	 * Sequences must consist of a single FastCGI session as defined
2024
	 * in the FastCGI version 1.0 reference document.
2025
	 *
2026
	 * If the connection closes out at any point, we receive a
2027
	 * zero-length read from the control socket.
2028
	 * The response to this should be to write an zero error code
2029
	 * back to the control socket, then keep on listening.
2030
	 * Otherwise, if we've read the full message, write a non-zero
2031
	 * error code, then our identifier and cookie, then the rest
2032
	 * goes directly to the parse routines in kworker_parent().
2033
	 */
2034

2035
	for (;;) {
2036
		free(sbuf);
2037
		for (i = 0; i < envsz; i++) {
2038
			free(envs[i].key);
2039
			free(envs[i].val);
2040
		}
2041
		free(envs);
2042
		free(fbuf.buf);
2043

2044
		sbuf = NULL;
2045
		ssz = 0;
2046
		envs = NULL;
2047
		envsz = 0;
2048
		cookie = 0;
2049
		memset(&fbuf, 0, sizeof(struct fcgi_buf));
2050
		fbuf.fd = work_ctl;
2051

2052
		/* 
2053
		 * Begin by reading our magic cookie.
2054
		 * This is emitted by kfcgi_control() at the start of
2055
		 * our sequence.
2056
		 * When we've finished reading data with success, we'll
2057
		 * respond with this value.
2058
		 */
2059

2060
		rc = fullread(fbuf.fd, 
2061
			&cookie, sizeof(uint32_t), 1, &er);
2062
		if (rc < 0) {
2063
			kutil_warnx(NULL, NULL, "FastCGI: "
2064
				"error reading worker cookie");
2065
			break;
2066
		} else if (rc == 0) {
2067
			kutil_warnx(NULL, NULL, "FastCGI: "
2068
				"worker process termination");
2069
			break;
2070
		}
2071

2072
		/* Now start the FastCGI sequence. */
2073

2074
		er = kworker_fcgi_begin(&fbuf, &rid);
2075
		if (er == KCGI_HUP) {
2076
			kutil_warnx(NULL, NULL, "FastCGI: "
2077
				"connection severed at start");
2078
			/* Note: writing error code... */
2079
			rc = 0;
2080
			fullwrite(work_ctl, &rc, sizeof(int));
2081
			continue;
2082
		} else if (er != KCGI_OK) {
2083
			kutil_warnx(NULL, NULL, "FastCGI: "
2084
				"unrecoverable error at start");
2085
			break;
2086
		}
2087

2088
		/*
2089
		 * Now read one or more parameters.
2090
		 * We read them all at once, then do the parsing later
2091
		 * after we've read all of our data.
2092
		 * We read parameters til we no longer have the
2093
		 * FCGI_PARAMS type on the current header.
2094
		 */
2095

2096
		er = KCGI_OK;
2097
		envsz = 0;
2098
		memset(&hdr, 0, sizeof(struct fcgi_hdr));
2099

2100
		while (er == KCGI_OK) {
2101
			er = kworker_fcgi_header(&fbuf, &hdr);
2102
			if (er != KCGI_OK)
2103
				break;
2104
			if (rid != hdr.requestId) {
2105
				kutil_warnx(NULL, NULL, 
2106
					"FastCGI: wrong request ID");
2107
				er = KCGI_FORM;
2108
				break;
2109
			} 
2110
			if (hdr.type != FCGI_PARAMS)
2111
				break;
2112
			er = kworker_fcgi_params
2113
				(&fbuf, &hdr, &envs, &envsz);
2114
		}
2115

2116
		if (er == KCGI_HUP) {
2117
			kutil_warnx(NULL, NULL, "FastCGI: "
2118
				"connection severed at parameters");
2119
			/* Note: writing error code... */
2120
			rc = 0;
2121
			fullwrite(work_ctl, &rc, sizeof(int));
2122
			continue;
2123
		} else if (er != KCGI_OK) {
2124
			kutil_warnx(NULL, NULL, "FastCGI: "
2125
				"unrecoverable error at parameters");
2126
			break;
2127
		} else if (hdr.type != FCGI_STDIN) {
2128
			kutil_warnx(NULL, NULL, "FastCGI: "
2129
				"bad header type");
2130
			er = KCGI_FORM;
2131
			break;
2132
		} else if (rid != hdr.requestId) {
2133
			kutil_warnx(NULL, NULL, "FastCGI: "
2134
				"wrong request ID");
2135
			er = KCGI_FORM;
2136
			break;
2137
		}
2138

2139
		/*
2140
		 * Lastly, we want to process the stdin content.
2141
		 * These will end with a single zero-length record.
2142
		 * Keep looping til we've flushed all input.
2143
		 */
2144

2145
		for (;;) {
2146
			/*
2147
			 * Call this even if we have a zero-length data
2148
			 * payload as specified by contentLength.
2149
			 * This is because there might be padding, and
2150
			 * we want to make sure we've drawn everything
2151
			 * from the socket before exiting.
2152
			 */
2153

2154
			er = kworker_fcgi_stdin
2155
				(&fbuf, &hdr, &sbuf, &ssz);
2156
			if (er != KCGI_OK || hdr.contentLength == 0)
2157
				break;
2158

2159
			/* Now read the next header. */
2160

2161
			er = kworker_fcgi_header(&fbuf, &hdr);
2162
			if (er != KCGI_OK)
2163
				break;
2164
			if (rid != hdr.requestId) {
2165
				kutil_warnx(NULL, NULL, "FastCGI: "
2166
					"wrong FastCGI request ID");
2167
				er = KCGI_FORM;
2168
				break;
2169
			} 
2170

2171
			if (hdr.type == FCGI_STDIN)
2172
				continue;
2173
			kutil_warnx(NULL, NULL, 
2174
				"FastCGI: bad header type");
2175
			er = KCGI_FORM;
2176
			break;
2177
		}
2178

2179
		if (er == KCGI_HUP) {
2180
			kutil_warnx(NULL, NULL, "FastCGI: "
2181
				"connection severed at stdin");
2182
			/* Note: writing error code. */
2183
			rc = 0;
2184
			fullwrite(work_ctl, &rc, sizeof(int));
2185
			continue;
2186
		} else if (er != KCGI_OK) {
2187
			kutil_warnx(NULL, NULL, "FastCGI: "
2188
				"unrecoverable error at stdin");
2189
			break;
2190
		}
2191

2192
		/* 
2193
		 * Notify the control process that we've received all of
2194
		 * our data by giving back the cookie and requestId.
2195
		 * FIXME: merge cookie and rc.
2196
		 */
2197

2198
		rc = 1;
2199
		fullwrite(work_ctl, &rc, sizeof(int));
2200
		fullwrite(work_ctl, &cookie, sizeof(uint32_t));
2201
		fullwrite(work_ctl, &rid, sizeof(uint16_t));
2202

2203
		/* 
2204
		 * Read our last zero-length frame.
2205
		 * This is because kfcgi_control() always ends with an
2206
		 * empty frame, regardless of whether we're in an error
2207
		 * or not.
2208
		 * So if we're this far, we've read the full request,
2209
		 * and we should have an empty frame.
2210
		 */
2211

2212
		rc = fullread(fbuf.fd, &sz, sizeof(size_t), 0, &er);
2213
		if (rc <= 0) {
2214
			kutil_warnx(NULL, NULL, 
2215
				"FastCGI: error reading trailer");
2216
			break;
2217
		} else if (sz != 0) {
2218
			kutil_warnx(NULL, NULL, 
2219
				"FastCGI: trailer not zero-length");
2220
			er = KCGI_FORM;
2221
			break;
2222
		} 
2223

2224
		/* 
2225
		 * Now we can reply to our request.
2226
		 * See kworker_parent().
2227
		 * These are in a very specific order.
2228
		 */
2229

2230
		kworker_child_env(envs, wfd, envsz);
2231
		meth = kworker_child_method(envs, wfd, envsz);
2232
		kworker_child_auth(envs, wfd, envsz);
2233
		md5 = kworker_child_rawauth(envs, wfd, envsz);
2234
		kworker_child_scheme(envs, wfd, envsz);
2235
		kworker_child_remote(envs, wfd, envsz);
2236
		kworker_child_path(envs, wfd, envsz);
2237
		kworker_child_scriptname(envs, wfd, envsz);
2238
		kworker_child_httphost(envs, wfd, envsz);
2239
		kworker_child_port(envs, wfd, envsz);
2240

2241
		/* 
2242
		 * And now the message body itself.
2243
		 * We must either have a NULL message or non-zero
2244
		 * length.
2245
		 */
2246

2247
		assert(ssz == 0 || sbuf != NULL);
2248
		kworker_child_body(envs, wfd, envsz, &pp, 
2249
			meth, (char *)sbuf, ssz, debugging, md5);
2250
		kworker_child_query(envs, wfd, envsz, &pp);
2251
		kworker_child_cookies(envs, wfd, envsz, &pp);
2252
		kworker_child_last(wfd);
2253
	}
2254

2255
	/* The same as what we do at the loop start. */
2256

2257
	free(sbuf);
2258
	for (i = 0; i < envsz; i++) {
2259
		free(envs[i].key);
2260
		free(envs[i].val);
2261
	}
2262
	free(envs);
2263
	free(fbuf.buf);
2264
}
2265

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.