예제 #1
0
void parse_openvpn_status(int unit){
	FILE *fpi, *fpo;
	char buf[512];
	char *token;
	char node[MAXLEN_NODE_NAME];

	sprintf(buf, "/etc/openvpn/server%d/status", unit);
	fpi = fopen(buf, "r");

	sprintf(buf, "/etc/openvpn/server%d/client_status", unit);
	fpo = fopen(buf, "w");

	snprintf(node, sizeof(node), "OpenVPN_Entry%d", unit + SERVER_IF_START);

	if(fpi && fpo) {
		while(!feof(fpi)){
			CLEAR(buf);
			if (!fgets(buf, sizeof(buf), fpi))
				break;
			if(!strncmp(buf, "CLIENT_LIST", 11)) {
				//printf("%s", buf);
				token = strtok(buf, ",");	//CLIENT_LIST
				token = strtok(NULL, ",");	//Common Name
				token = strtok(NULL, ",");	//Real Address
				if(token)
					fprintf(fpo, "%s ", token);
				else
					fprintf(fpo, "NoRealAddress ");

				if(tcapi_match(node, "iface", "tap")
					&& tcapi_match(node, "dhcp", "1")) {
					fprintf(fpo, "VirtualAddressAssignedByDhcp ");
				}
				else {
					token = strtok(NULL, ",");	//Virtual Address
					if(token)
						fprintf(fpo, "%s ", token);
					else
						fprintf(fpo, "NoVirtualAddress ");
				}
				token = strtok(NULL, ",");	//Bytes Received
				token = strtok(NULL, ",");	//Bytes Sent
				token = strtok(NULL, ",");	//Connected Since
				token = strtok(NULL, ",");	//Connected Since (time_t)
				token = strtok(NULL, ",");	//Username, include'\n'
				if(token)
					fprintf(fpo, "%s", token);
				else
					fprintf(fpo, "NoUsername");
			}
		}
		fclose(fpi);
		fclose(fpo);
	}
}
예제 #2
0
void start_pptpd(void)
{
	int ret = 0, manual_dns = 0, pptpd_opt = 0;
	FILE *fp;
	char buf[MAXLEN_TCAPI_MSG];
	char lan_ipaddr[16] = {0};

	int pid = getpid();
	_dprintf("start_pptpd: getpid= %d\n", pid);

	//if(getpid() != 1) {
		//notify_rc("start_pptpd");
		//return;
	//}

	if (!tcapi_match(VPN_DATA, "pptpd_enable", "1")) {
		return;
	}
	// cprintf("stop vpn modules\n");
	// stop_vpn_modules ();

	// Create directory for use by pptpd daemon and its supporting files
	mkdir("/tmp/pptpd", 0744);
	cprintf("open options file\n");
	// Create options file that will be unique to pptpd to avoid interference
	// with pppoe and pptp
	fp = fopen("/tmp/pptpd/options.pptpd", "w");
	fprintf(fp, "logfile /var/log/pptpd-pppd.log\n");
	//fprintf(fp, "debug dump logfd 2 nodetach\n");
	if (tcapi_match(VPN_DATA, "pptpd_radius", "1"))
		fprintf(fp, "plugin radius.so\nplugin radattr.so\n"
			"radius-config-file /tmp/pptpd/radius/radiusclient.conf\n");

	//cprintf("check if wan_wins = zero\n");
	//int nowins = 0;

	//if (nvram_match("wan_wins", "0.0.0.0")) {
		//nvram_set("wan_wins", "");
		//nowins = 1;
	//}
	//if (strlen(nvram_safe_get("wan_wins")) == 0)
		//nowins = 1;

	cprintf("write config\n");
	fprintf(fp, "lock\n"
		"name *\n"
		"proxyarp\n"
//		"ipcp-accept-local\n"
//		"ipcp-accept-remote\n"
		"lcp-echo-failure 10\n"
		"lcp-echo-interval 6\n"
		"deflate 0\n" "auth\n" "-chap\n"
		"nomppe-stateful\n");

	pptpd_opt = tcapi_get_int(VPN_DATA, "pptpd_chap");
	fprintf(fp, "%smschap\n", (pptpd_opt == 0 || pptpd_opt & 1) ? "+" : "-");
	fprintf(fp, "%smschap-v2\n", (pptpd_opt == 0 || pptpd_opt & 2) ? "+" : "-");

	pptpd_opt = tcapi_get_int(VPN_DATA, "pptpd_mppe");
	if (pptpd_opt == 0)
		pptpd_opt = 1 | 4 | 8;
	if (pptpd_opt & (1 | 2 | 4)) {
		fprintf(fp, "%s", (pptpd_opt & 8) ? "" : "require-mppe\n");
  		fprintf(fp, "%smppe-128\n", (pptpd_opt & 1) ? "require-" : "no");
  		//fprintf(fp, "%smppe-56\n", (pptpd_opt & 2) ? "require-" : "no");
  		fprintf(fp, "%smppe-40\n", (pptpd_opt & 4) ? "require-" : "no");
	} else
  		fprintf(fp, "nomppe nomppc\n");

	fprintf(fp, "ms-ignore-domain\n"
		"chap-secrets /tmp/pptpd/chap-secrets\n"
		"ip-up-script /tmp/pptpd/ip-up\n"
		"ip-down-script /tmp/pptpd/ip-down\n"
		"mtu %d\n" "mru %d\n",
		tcapi_get_int(VPN_DATA, "pptpd_mtu"),
		tcapi_get_int(VPN_DATA, "pptpd_mru"));

	//WINS Server
	//if (!nowins) {
		//fprintf(fp, "ms-wins %s\n", nvram_safe_get("wan_wins"));
	//}
	memset(buf, 0, sizeof(buf));
	tcapi_get(VPN_DATA, "pptpd_wins1", buf);
	if(strlen(buf)) {
		fprintf(fp, "ms-wins %s\n", buf);
	}
	memset(buf, 0, sizeof(buf));
	tcapi_get(VPN_DATA, "pptpd_wins2", buf);
	if(strlen(buf)) {
		fprintf(fp, "ms-wins %s\n", buf);
	}
	//DNS Server
	memset(buf, 0, sizeof(buf));
	tcapi_get(VPN_DATA, "pptpd_dns1", buf);
	if(strlen(buf)) {
		fprintf(fp, "ms-dns %s\n", buf);
		manual_dns=1;
	}
	memset(buf, 0, sizeof(buf));
	tcapi_get(VPN_DATA, "pptpd_dns2", buf);
	if(strlen(buf)) {
		fprintf(fp, "ms-dns %s\n", buf);
		manual_dns=1;
	}
	tcapi_get("Lan_Entry0", "IP", lan_ipaddr);
	if(!manual_dns && strcmp(lan_ipaddr, ""))
		fprintf(fp, "ms-dns %s\n", lan_ipaddr);

	// force ppp interface starting from 20
	fprintf(fp, "minunit 20\n");

	// Following is all crude and need to be revisited once testing confirms
	// that it does work
	// Should be enough for testing..
	if (tcapi_match(VPN_DATA, "pptpd_radius", "1")) {
		char pptpd_radserver[128] = {0};
		char pptpd_radpass[128] = {0};
		char pptpd_radport[128] = {0};
		char pptpd_acctport[128] = {0};

		if (tcapi_get(VPN_DATA, "pptpd_radserver", pptpd_radserver) == TCAPI_PROCESS_OK
			&& tcapi_get(VPN_DATA, "pptpd_radpass", pptpd_radpass) == TCAPI_PROCESS_OK) {

			fclose(fp);

			mkdir("/tmp/pptpd/radius", 0744);

			if (tcapi_get(VPN_DATA, "pptpd_radport", pptpd_radport) != TCAPI_PROCESS_OK)
				strcpy(pptpd_radport, "radius");

			fp = fopen("/tmp/pptpd/radius/radiusclient.conf", "w");
			fprintf(fp, "auth_order radius\n"
				"login_tries 4\n"
				"login_timeout 60\n"
				"radius_timeout 10\n"
				"nologin /etc/nologin\n"
				"servers /tmp/pptpd/radius/servers\n"
				"dictionary /etc/dictionary\n"
				"seqfile /var/run/radius.seq\n"
				"mapfile /etc/port-id-map\n"
				"radius_retries 3\n"
				"authserver %s:%s\n",
				pptpd_radserver, pptpd_radport);

			if (tcapi_get(VPN_DATA, "pptpd_acctport", pptpd_acctport) != TCAPI_PROCESS_OK)
				strcpy(pptpd_acctport, "radacct");

			fprintf(fp, "acctserver %s:%s\n", pptpd_radserver, pptpd_acctport);
			fclose(fp);

			fp = fopen("/tmp/pptpd/radius/servers", "w");
			fprintf(fp, "%s\t%s\n", pptpd_radserver, pptpd_radpass);
			fclose(fp);

		} else
			fclose(fp);
	} else
		fclose(fp);

	// Create pptpd.conf options file for pptpd daemon
	fp = fopen("/tmp/pptpd/pptpd.conf", "w");
	memset(buf, 0, sizeof(buf));
	fprintf(fp, "bcrelay %s\n", tcapi_get_string(VPN_DATA, "pptpd_broadcast", buf));
	memset(buf, 0, sizeof(buf));
	fprintf(fp, "localip %s\n"
		"remoteip %s\n", lan_ipaddr,
		tcapi_get_string(VPN_DATA, "pptpd_clients", buf));
	fclose(fp);

	// Create ip-up and ip-down scripts that are unique to pptpd to avoid
	// interference with pppoe and pptp
	/*
	 * adjust for tunneling overhead (mtu - 40 byte IP - 108 byte tunnel
	 * overhead)
	 */
	//if (nvram_match("mtu_enable", "1"))
		//mss = atoi(nvram_safe_get("wan_mtu")) - 40 - 108;
	//else
		//mss = 1500 - 40 - 108;
	char bcast[32];

	strcpy(bcast, lan_ipaddr);
	memset(buf, 0, sizeof(buf));
	get_broadcast(bcast, tcapi_get_string("Lan_Entry0", "netmask", buf));

	memset(buf, 0, sizeof(buf));
	tcapi_get(VPN_DATA, "pptpd_ipup_script", buf);
	fp = fopen("/tmp/pptpd/ip-up", "w");
	fprintf(fp, "#!/bin/sh\n" "startservice set_routes\n"	// reinitialize
		"echo $PPPD_PID $1 $5 $6 $PEERNAME >> /tmp/pptp_connected\n"
		"iptables -I FORWARD -i $1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n"
		"iptables -I INPUT -i $1 -j ACCEPT\n" "iptables -I FORWARD -i $1 -j ACCEPT\n"
		"iptables -t nat -I PREROUTING -i $1 -p udp -m udp --sport 9 -j DNAT --to-destination %s "	// rule for wake on lan over pptp tunnel
		"%s\n", bcast, buf);
	fclose(fp);
	memset(buf, 0, sizeof(buf));
	tcapi_get(VPN_DATA, "pptpd_ipdown_script", buf);
	fp = fopen("/tmp/pptpd/ip-down", "w");
	fprintf(fp, "#!/bin/sh\n" "grep -v $1  /tmp/pptp_connected > /tmp/pptp_connected.new\n"
		"mv /tmp/pptp_connected.new /tmp/pptp_connected\n"
		"iptables -D FORWARD -i $1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n"
		"iptables -D INPUT -i $1 -j ACCEPT\n"
		"iptables -D FORWARD -i $1 -j ACCEPT\n"
		"iptables -t nat -D PREROUTING -i $1 -p udp -m udp --sport 9 -j DNAT --to-destination %s "	// rule for wake on lan over pptp tunnel
		"%s\n", bcast, buf);
	fclose(fp);
	chmod("/tmp/pptpd/ip-up", 0744);
	chmod("/tmp/pptpd/ip-down", 0744);

	// Exctract chap-secrets from nvram
	write_chap_secret("/tmp/pptpd/chap-secrets");

	chmod("/tmp/pptpd/chap-secrets", 0600);

	// Execute pptpd daemon
	ret =
	    eval("pptpd", "-c", "/tmp/pptpd/pptpd.conf", "-o",
		 "/tmp/pptpd/options.pptpd");

	_dprintf("start_pptpd: ret= %d\n", ret);
	//dd_syslog(LOG_INFO, "pptpd : pptp daemon successfully started\n");
	return;
}
예제 #3
0
static int
add_option (char *p[], int line, int unit)
{
	char buf[32] = {0};
	FILE *fp;
	char file_path[128] ={0};
	char node[MAXLEN_NODE_NAME];

	snprintf(node, sizeof(node), "OpenVPN_Entry%d", unit + CLIENT_IF_START);

	if  (streq (p[0], "dev") && p[1])
	{
		if(!strncmp(p[1], "tun", 3))
			tcapi_set(node, "iface", "tun");
		else if(!strncmp(p[1], "tap", 3))
			tcapi_set(node, "iface", "tap");
	}
	else if  (streq (p[0], "proto") && p[1])
	{
		tcapi_set(node, "proto", p[1]);
	}
	else if  (streq (p[0], "remote") && p[1])
	{
		tcapi_set(node, "addr", p[1]);

		if(p[2])
			tcapi_set(node, "port", p[2]);
		else
			tcapi_set(node, "port", "1194");
	}
	else if (streq (p[0], "resolv-retry") && p[1])
	{
		if (streq (p[1], "infinite"))
			tcapi_set(node, "retry", "-1");
		else
			tcapi_set(node, "retry", p[1]);
	}
	else if (streq (p[0], "comp-lzo"))
	{
		sprintf(buf, "vpn_client%d_comp", unit);
		if(p[1])
			tcapi_set(node, "comp", p[1]);
		else
			tcapi_set(node, "comp", "adaptive");
	}
	else if (streq (p[0], "cipher") && p[1])
	{
		tcapi_set(node, "cipher", p[1]);
	}
	else if (streq (p[0], "verb") && p[1])
	{
		tcapi_set(node, "loglevel", p[1]);
	}
	else if  (streq (p[0], "ca") && p[1])
	{
		tcapi_set(node, "crypt", "tls");
		if (streq (p[1], INLINE_FILE_TAG) && p[2])
		{
			sprintf(buf, "vpn_crt_client%d_ca", unit);
#if defined(TCSUPPORT_ADD_JFFS) || defined(TCSUPPORT_SQUASHFS_ADD_YAFFS)
			snprintf(file_path, sizeof(file_path) -1, "%s/%s", OVPN_FS_PATH, buf);
			fp = fopen(file_path, "w");
			if(fp) {
				fprintf(fp, "%s", strstr(p[2], "-----BEGIN"));
				fclose(fp);
			}
			else {
				_dprintf("write %s file to %s failed\n", buf, OVPN_FS_PATH);
				logmessage ("OVPN", "Write CA to filesystem failed");
				return -1;
			}
#else
			tcapi_set(node, buf, strstr(p[2], "-----BEGIN"));
#endif
		}
		else
		{
			return VPN_UPLOAD_NEED_CA_CERT;
		}
	}
	else if  (streq (p[0], "cert") && p[1])
	{
		if (streq (p[1], INLINE_FILE_TAG) && p[2])
		{
			sprintf(buf, "vpn_crt_client%d_crt", unit);
#if defined(TCSUPPORT_ADD_JFFS) || defined(TCSUPPORT_SQUASHFS_ADD_YAFFS)
			snprintf(file_path, sizeof(file_path) -1, "%s/%s", OVPN_FS_PATH, buf);
			fp = fopen(file_path, "w");
			if(fp) {
				fprintf(fp, "%s", strstr(p[2], "-----BEGIN"));
				fclose(fp);
			}
			else {
				_dprintf("write %s file to %s failed\n", buf, OVPN_FS_PATH);
				logmessage ("OVPN", "Write Certificate to filesystem failed");
				return -1;
			}
#else
			tcapi_set(node, buf, strstr(p[2], "-----BEGIN"));
#endif
		}
		else
		{
			return VPN_UPLOAD_NEED_CERT;
		}
	}
	else if  (streq (p[0], "key") && p[1])
	{
		if (streq (p[1], INLINE_FILE_TAG) && p[2])
		{
			sprintf(buf, "vpn_crt_client%d_key", unit);
#if defined(TCSUPPORT_ADD_JFFS) || defined(TCSUPPORT_SQUASHFS_ADD_YAFFS)
			snprintf(file_path, sizeof(file_path) -1, "%s/%s", OVPN_FS_PATH, buf);
			fp = fopen(file_path, "w");
			if(fp) {
				fprintf(fp, "%s", strstr(p[2], "-----BEGIN"));
				fclose(fp);
			}
			else {
				_dprintf("write %s file to %s failed\n", buf, OVPN_FS_PATH);
				logmessage ("OVPN", "Write key to filesystem failed");
				return -1;
			}
#else
			tcapi_set(node, buf, strstr(p[2], "-----BEGIN"));
#endif
		}
		else
		{
			return VPN_UPLOAD_NEED_KEY;
		}
	}
	else if (streq (p[0], "tls-auth") && p[1])
	{
		if (streq (p[1], INLINE_FILE_TAG) && p[2])
		{
			sprintf(buf, "vpn_crt_client%d_static", unit);
#if defined(TCSUPPORT_ADD_JFFS) || defined(TCSUPPORT_SQUASHFS_ADD_YAFFS)
			snprintf(file_path, sizeof(file_path) -1, "%s/%s", OVPN_FS_PATH, buf);
			fp = fopen(file_path, "w");
			if(fp) {
				fprintf(fp, "%s", strstr(p[2], "-----BEGIN"));
				fclose(fp);
			}
			else {
				_dprintf("write %s file to %s failed\n", buf, OVPN_FS_PATH);
				logmessage ("OVPN", "Write static-key to filesystem failed");
				return -1;
			}
#else
			tcapi_set(node, buf, strstr(p[2], "-----BEGIN"));
#endif
			//key-direction
			sprintf(buf, "vpn_crt_client%d_hmac", unit);
			if(tcapi_match(node, "hmac", "-1"))	//default, disable
				tcapi_set(node, "hmac", "2");	//openvpn default value: KEY_DIRECTION_BIDIRECTIONAL
		}
		else
		{
			if(p[2]) {
				tcapi_set(node, "hmac", p[2]);
			}
			return VPN_UPLOAD_NEED_STATIC;
		}
	}
	else if (streq (p[0], "secret") && p[1])
	{
		tcapi_set(node, "crypt", "secret");
		if (streq (p[1], INLINE_FILE_TAG) && p[2])
		{
			sprintf(buf, "vpn_crt_client%d_static", unit);
#if defined(TCSUPPORT_ADD_JFFS) || defined(TCSUPPORT_SQUASHFS_ADD_YAFFS)
			snprintf(file_path, sizeof(file_path) -1, "%s/%s", OVPN_FS_PATH, buf);
			fp = fopen(file_path, "w");
			if(fp) {
				fprintf(fp, "%s", strstr(p[2], "-----BEGIN"));
				fclose(fp);
			}
			else {
				_dprintf("write %s file to %s failed\n", buf, OVPN_FS_PATH);
				logmessage ("OVPN", "Write static-key to filesystem failed");
				return -1;
			}
#else
			tcapi_set(node, buf, strstr(p[2], "-----BEGIN"));
#endif
		}
		else
		{
			return VPN_UPLOAD_NEED_STATIC;
		}
	}
	else if (streq (p[0], "auth-user-pass"))
	{
		tcapi_set(node, "userauth", "1");
	}
	else if (streq (p[0], "tls-remote") && p[1])
	{
		tcapi_set(node, "tlsremote", "1");
		tcapi_set(node, "common_name", p[1]);
	}
	else if (streq (p[0], "key-direction") && p[1])
	{
		tcapi_set(node, "hmac", p[1]);
	}
	else if (streq (p[0], "crl-verify") && p[1])
	{
		if (p[2] && streq(p[2], "dir"))
			;//TODO: not support?
		return VPN_UPLOAD_NEED_CRL;
	}
	else
	{
		if ( streq (p[0], "client")
			|| streq (p[0], "nobind")
			|| streq (p[0], "persist-key")
			|| streq (p[0], "persist-tun")
		) {
			;//ignore
		}
		else {
			add_custom(unit, p);
		}
	}
	return 0;
}
예제 #4
0
파일: read.c 프로젝트: owl129/asuswrt-rt
int read_header(request * req)
{
	int bytes, buf_bytes_left;
	char *check, *buffer;
	char *pstr;
	char str_lang[6];
	char str_type[4] = {0};
	int	nIndex = 1;
	char ttc[16] = {0};

    check = req->client_stream + req->parse_pos;
    buffer = req->client_stream;
    bytes = req->client_stream_pos;

#ifdef VERY_FASCIST_LOGGING
    if (check < (buffer + bytes)) {
        buffer[bytes] = '\0';
        log_error_time();
        fprintf(stderr, "1) %s:%d - Parsing headers (\"%s\")\n",
                __FILE__, __LINE__, check);
    }
#endif

	tcapi_get("SysInfo_Entry", "TerritoryCode", ttc);

	/* Paul add 2013/3/7, for retrieve Language type from HTTP header */
	tcapi_get("LanguageSwitch_Entry", "Type", str_type);
	if(strlen(str_type))
		nIndex = atoi(str_type);

	if(nIndex == 0) /* Language never been set before, start checking */
	{
		tcapi_get("WebCurSet_Entry", "detected_lang_type", str_type);
		if(strlen(str_type))
			nIndex = atoi(str_type);

		if(nIndex == 0) { // Language never been detect before, start checking
			memset(str_lang, 0, sizeof(str_lang));
			if(pstr = strstr(check,"Accept-Language:"))
			{
				strncpy (str_lang, &check[pstr-check+17], 6);
				str_lang[5] = '\0';

				int i, len = strlen(str_lang);
				int lang_type = 0;

				for(i=0; i<len; ++i)
				{
					if(isupper(str_lang[i])){
						str_lang[i] = tolower(str_lang[i]);
					}
				}

				//choose proper language type
				lang_type = getLangType(ttc, str_lang);
				snprintf(str_type, sizeof(str_type), "%d", lang_type);
				tcapi_set("WebCurSet_Entry", "detected_lang_type", str_type);

				initandparserfile();
				if(lang_type == LANG_TYPE_CZ || lang_type == LANG_TYPE_DE)
				{
					int flag = 0;
					if(tcapi_match("SysInfo_Entry", "x_Setting", "0")
						&& tcapi_match("Adsl_Entry", "ANNEXTYPEA", "ANNEX A/I/J/L/M")
						&& tcapi_match("Info_Adsl", "lineState", "down")
					){
						tcapi_set("Adsl_Entry", "ANNEXTYPEA", "ANNEX B/J/M");
						flag = 1;
					}
				#ifdef TCSUPPORT_WAN_PTM
					if(lang_type == LANG_TYPE_DE) {
						if(tcapi_match("Adsl_Entry", "vdsl_profile", "0"))
						{
							tcapi_set("Adsl_Entry", "vdsl_profile", "1");
							flag = 1;
						}
					}
				#endif
					if(flag)
						tcapi_commit("Adsl_Entry");
				}
			}
		}
	}

    while (check < (buffer + bytes)) {
        switch (req->status) {
        case READ_HEADER:
            if (*check == '\r') {
                req->status = ONE_CR;
                req->header_end = check;
            } else if (*check == '\n') {
                req->status = ONE_LF;
                req->header_end = check;
            }
            break;

        case ONE_CR:
            if (*check == '\n')
                req->status = ONE_LF;
            else if (*check != '\r')
                req->status = READ_HEADER;
            break;

        case ONE_LF:
            /* if here, we've found the end (for sure) of a header */
            if (*check == '\r') /* could be end o headers */
                req->status = TWO_CR;
            else if (*check == '\n')
                req->status = BODY_READ;
            else
                req->status = READ_HEADER;
            break;

        case TWO_CR:
            if (*check == '\n')
                req->status = BODY_READ;
            else if (*check != '\r')
                req->status = READ_HEADER;
            break;

        default:
            break;
        }
#if 0
#ifdef VERY_FASCIST_LOGGING
        log_error_time();
        fprintf(stderr, "status, check: %d, %d\n", req->status, *check);
#endif
#endif
        req->parse_pos++;       /* update parse position */
        check++;

        if (req->status == ONE_LF) {
            *req->header_end = '\0';

            /* terminate string that begins at req->header_line */

            if (req->logline) {
                if (process_option_line(req) == 0) {
                    return 0;
                }
            } else {
                if (process_logline(req) == 0)
                    return 0;
                if (req->simple)
                    return process_header_end(req);
            }
            /* set header_line to point to beginning of new header */
            req->header_line = check;
        } else if (req->status == BODY_READ) {
#ifdef VERY_FASCIST_LOGGING
            int retval;
            log_error_time();
            fprintf(stderr, "%s:%d -- got to body read.\n",
                    __FILE__, __LINE__);
            retval = process_header_end(req);
#else
            int retval = process_header_end(req);
#endif
            /* process_header_end inits non-POST cgi's */

            if (retval && req->method == M_POST) {
                /* for body_{read,write}, set header_line to start of data,
                   and header_end to end of data */
                req->header_line = check;
                req->header_end =
                    req->client_stream + req->client_stream_pos;

                req->status = BODY_WRITE;
                /* so write it */
                /* have to write first, or read will be confused
                 * because of the special case where the
                 * filesize is less than we have already read.
                 */

                /*

                   As quoted from RFC1945:

                   A valid Content-Length is required on all HTTP/1.0 POST requests. An
                   HTTP/1.0 server should respond with a 400 (bad request) message if it
                   cannot determine the length of the request message's content.

                 */

                if (req->content_length) {
                    int content_length;

                    content_length = boa_atoi(req->content_length);
#if 0	//Content-Length is required but don't limit to larger then zero. Sam, 2013/7/3
                    /* Is a content-length of 0 legal? */
                    if (content_length <= 0) {
                        log_error_time();
                        fprintf(stderr, "Invalid Content-Length [%s] on POST!\n",
                                req->content_length);
                        send_r_bad_request(req);
                        return 0;
                    }
#endif
                    if (single_post_limit && content_length > single_post_limit) {
                        log_error_time();
                        fprintf(stderr, "Content-Length [%d] > SinglePostLimit [%d] on POST!\n",
                                content_length, single_post_limit);
                        send_r_bad_request(req);
                        return 0;
                    }
                    req->filesize = content_length;
                    req->filepos = 0;
                    if (req->header_end - req->header_line > req->filesize) {
                        req->header_end = req->header_line + req->filesize;
                    }
                } else {
                    log_error_time();
                    fprintf(stderr, "Unknown Content-Length POST!\n");
                    send_r_bad_request(req);
                    return 0;
                }
            }                   /* either process_header_end failed or req->method != POST */
            return retval;      /* 0 - close it done, 1 - keep on ready */
        }                       /* req->status == BODY_READ */
    }                           /* done processing available buffer */

#ifdef VERY_FASCIST_LOGGING
    log_error_time();
    fprintf(stderr, "%s:%d - Done processing buffer.  Status: %d\n",
            __FILE__, __LINE__, req->status);
#endif

    if (req->status < BODY_READ) {
        /* only reached if request is split across more than one packet */

        buf_bytes_left = CLIENT_STREAM_SIZE - req->client_stream_pos;
        if (buf_bytes_left < 1) {
            log_error_time();
            fputs("buffer overrun - read.c, read_header - closing\n",
                  stderr);
            req->status = DEAD;
            return 0;
        }

#if defined(TCSUPPORT_WEBSERVER_SSL)
	if(req->ssl == NULL)
#endif
	{
        bytes = read(req->fd, buffer + req->client_stream_pos, buf_bytes_left);
	}
#if defined(TCSUPPORT_WEBSERVER_SSL)
	else{
		bytes = boa_sslRead(req->ssl, buffer + req->client_stream_pos, buf_bytes_left);
	}
#endif 
        if (bytes < 0) {
            if (errno == EINTR)
                return 1;
            if (errno == EAGAIN || errno == EWOULDBLOCK) /* request blocked */
                return -1;
            /*
               else if (errno == EBADF || errno == EPIPE) {

               req->status = DEAD;
               return 0;
            */
               
#if 0		//lee 9-25
            log_error_doc(req);
            perror("header read");            /* don't need to save errno because log_error_doc does */
#endif
			return 0;
        } else if (bytes == 0) {
            /*
               log_error_time();
               fputs("unexpected end of headers\n", stderr);
             */
            return 0;
        }

        /* bytes is positive */
        req->client_stream_pos += bytes;

#ifdef FASCIST_LOGGING1
        log_error_time();
        req->client_stream[req->client_stream_pos] = '\0';
        fprintf(stderr, "%s:%d -- We read %d bytes: \"%s\"\n",
                __FILE__, __LINE__, bytes,
#ifdef VERY_FASCIST_LOGGING2
                req->client_stream + req->client_stream_pos - bytes);
#else
                "");
#endif
#endif

        return 1;
    }