Example #1
0
static int
openvpn_create_client_conf(const char *conf_file, int is_tun)
{
	FILE *fp;
	int i, i_prot, i_auth, i_atls;

	i_auth = nvram_get_int("vpnc_ov_auth");
	i_atls = nvram_get_int("vpnc_ov_atls");

	for (i=0; i<4; i++) {
		if (i_auth == 1 && (i == 1 || i == 2))
			continue;
		if (!i_atls && (i == 3))
			continue;
		if (!openvpn_check_key(openvpn_client_keys[i], 0))
			return 1;
	}

	i_prot = nvram_get_int("vpnc_ov_prot");

	fp = fopen(conf_file, "w+");
	if (fp) {
		fprintf(fp, "client\n");
		if (i_prot > 0)
			fprintf(fp, "proto %s\n", "tcp-client");
		else
			fprintf(fp, "proto %s\n", "udp");
		
		fprintf(fp, "remote %s %d\n", nvram_safe_get("vpnc_peer"), nvram_safe_get_int("vpnc_ov_port", 1194, 1, 65535));
		fprintf(fp, "resolv-retry %s\n", "infinite");
		fprintf(fp, "nobind\n");
		fprintf(fp, "dev %s\n", (is_tun) ? IFNAME_CLIENT_TUN : IFNAME_CLIENT_TAP);
		
		fprintf(fp, "ca %s/%s\n", CLIENT_CERT_DIR, openvpn_client_keys[0]);
		if (i_auth == 0) {
			fprintf(fp, "cert %s/%s\n", CLIENT_CERT_DIR, openvpn_client_keys[1]);
			fprintf(fp, "key %s/%s\n", CLIENT_CERT_DIR, openvpn_client_keys[2]);
		}
		
		if (i_atls)
			fprintf(fp, "tls-auth %s/%s %d\n", CLIENT_CERT_DIR, openvpn_client_keys[3], 1);
		
		openvpn_add_auth(fp, nvram_get_int("vpnc_ov_mdig"));
		openvpn_add_cipher(fp, nvram_get_int("vpnc_ov_ciph"));
		openvpn_add_lzo(fp, nvram_get_int("vpnc_ov_clzo"), 0);
		
		if (i_auth == 1) {
			fprintf(fp, "auth-user-pass %s\n", "secret");
			openvpn_create_client_secret("secret");
		}
		
		if (nvram_match("vpnc_dgw", "1"))
			fprintf(fp, "redirect-gateway def1 bypass-dhcp\n");
		
		fprintf(fp, "persist-key\n");
		fprintf(fp, "script-security %d\n", 2);
		fprintf(fp, "writepid %s\n", CLIENT_PID_FILE);
		
		fprintf(fp, "up %s\n",  SCRIPT_OVPN_CLIENT);
		fprintf(fp, "down %s\n",  SCRIPT_OVPN_CLIENT);
		
		fprintf(fp, "\n### User params:\n");
		
		load_user_config(fp, CLIENT_CERT_DIR, "client.conf", forbidden_list);
		
		fclose(fp);
		
		chmod(conf_file, 0644);
		
		return 0;
	}

	return 1;
}
Example #2
0
static int
openvpn_create_server_conf(const char *conf_file, int is_tun)
{
	FILE *fp;
	int i, i_prot, i_atls, i_rdgw, i_dhcp, i_items, i_cli0, i_cli1;
	unsigned int laddr, lmask, lsnet;
	struct in_addr pool_in;
	char pooll[32], pool1[32], pool2[32];
	char *lanip, *lannm, *wins, *dns1, *dns2;

	i_atls = nvram_get_int("vpns_ov_atls");

	for (i=0; i<5; i++) {
		if (!i_atls && (i == 4))
			continue;
		if (!openvpn_check_key(openvpn_server_keys[i], 1))
			return 1;
	}

	i_prot = nvram_get_int("vpns_ov_prot");
	i_rdgw = nvram_get_int("vpns_ov_rdgw");
	i_cli0 = nvram_safe_get_int("vpns_cli0", 245, 1, 254);
	i_cli1 = nvram_safe_get_int("vpns_cli1", 254, 2, 254);

	i_dhcp = is_dhcpd_enabled(0);

	lanip = nvram_safe_get("lan_ipaddr");
	lannm = nvram_safe_get("lan_netmask");

	laddr = ntohl(inet_addr(lanip));
	lmask = ntohl(inet_addr(lannm));
	lsnet = (~lmask) - 1;

	if (i_cli0 > (int)lsnet) i_cli0 = (int)lsnet;
	if (i_cli1 > (int)lsnet) i_cli1 = (int)lsnet;
	if (i_cli1 < i_cli0) i_cli1 = i_cli0;

	pool_in.s_addr = htonl(laddr & lmask);
	strcpy(pooll, inet_ntoa(pool_in));
	pool_in.s_addr = htonl((laddr & lmask) | (unsigned int)i_cli0);
	strcpy(pool1, inet_ntoa(pool_in));
	pool_in.s_addr = htonl((laddr & lmask) | (unsigned int)i_cli1);
	strcpy(pool2, inet_ntoa(pool_in));

	fp = fopen(conf_file, "w+");
	if (fp) {
		if (i_prot > 0)
			fprintf(fp, "proto %s\n", "tcp-server");
		else
			fprintf(fp, "proto %s\n", "udp");
		fprintf(fp, "port %d\n", nvram_safe_get_int("vpns_ov_port", 1194, 1, 65535));
		
		if (is_tun) {
			char *vnet, *vmsk;
			
			vnet = nvram_safe_get("vpns_vnet");
			vmsk = VPN_SERVER_SUBNET_MASK;
			laddr = ntohl(inet_addr(vnet));
			lmask = ntohl(inet_addr(vmsk));
			pool_in.s_addr = htonl(laddr & lmask);
			
			fprintf(fp, "dev %s\n", IFNAME_SERVER_TUN);
			fprintf(fp, "topology %s\n", "subnet");
			fprintf(fp, "server %s %s\n", inet_ntoa(pool_in), vmsk);
			fprintf(fp, "client-config-dir %s\n", "ccd");
			openvpn_create_server_acl(fp, "ccd");
			fprintf(fp, "push \"route %s %s\"\n", pooll, lannm);
		} else {
			fprintf(fp, "dev %s\n", IFNAME_SERVER_TAP);
			fprintf(fp, "server-bridge %s %s %s %s\n", lanip, lannm, pool1, pool2);
		}
		
		openvpn_add_auth(fp, nvram_get_int("vpns_ov_mdig"));
		openvpn_add_cipher(fp, nvram_get_int("vpns_ov_ciph"));
		openvpn_add_lzo(fp, nvram_get_int("vpns_ov_clzo"), 1);
		
		i_items = 0;
		if (i_rdgw) {
			fprintf(fp, "push \"redirect-gateway def1 %s\"\n", "bypass-dhcp");
			if (i_dhcp) {
				dns1 = nvram_safe_get("dhcp_dns1_x");
				dns2 = nvram_safe_get("dhcp_dns2_x");
				if (is_valid_ipv4(dns1) && (strcmp(dns1, lanip))) {
					i_items++;
					fprintf(fp, "push \"dhcp-option %s %s\"\n", "DNS", dns1);
				}
				if (is_valid_ipv4(dns2) && (strcmp(dns2, lanip)) && (strcmp(dns2, dns1))) {
					i_items++;
					fprintf(fp, "push \"dhcp-option %s %s\"\n", "DNS", dns2);
				}
			}
			
			if (i_items < 2)
				fprintf(fp, "push \"dhcp-option %s %s\"\n", "DNS", lanip);
		}
		
		i_items = 0;
		if (i_dhcp) {
			wins = nvram_safe_get("dhcp_wins_x");
			if (is_valid_ipv4(wins)) {
				i_items++;
				fprintf(fp, "push \"dhcp-option %s %s\"\n", "WINS", wins);
			}
		}
		
#if defined(APP_SMBD) || defined(APP_NMBD)
		if ((i_items < 1) && nvram_get_int("wins_enable"))
			fprintf(fp, "push \"dhcp-option %s %s\"\n", "WINS", lanip);
#endif
		
		fprintf(fp, "ca %s/%s\n", SERVER_CERT_DIR, openvpn_server_keys[0]);
		fprintf(fp, "dh %s/%s\n", SERVER_CERT_DIR, openvpn_server_keys[1]);
		fprintf(fp, "cert %s/%s\n", SERVER_CERT_DIR, openvpn_server_keys[2]);
		fprintf(fp, "key %s/%s\n", SERVER_CERT_DIR, openvpn_server_keys[3]);
		
		if (i_atls)
			fprintf(fp, "tls-auth %s/%s %d\n", SERVER_CERT_DIR, openvpn_server_keys[4], 0);
		
		fprintf(fp, "persist-key\n");
		fprintf(fp, "persist-tun\n");
		fprintf(fp, "user %s\n", SYS_USER_NOBODY);
		fprintf(fp, "group %s\n", SYS_GROUP_NOGROUP);
		fprintf(fp, "script-security %d\n", 2);
		fprintf(fp, "tmp-dir %s\n", COMMON_TEMP_DIR);
		fprintf(fp, "writepid %s\n", SERVER_PID_FILE);
		
		fprintf(fp, "client-connect %s\n", SCRIPT_OVPN_SERVER);
		fprintf(fp, "client-disconnect %s\n", SCRIPT_OVPN_SERVER);
		
		fprintf(fp, "\n### User params:\n");
		
		load_user_config(fp, SERVER_CERT_DIR, "server.conf", forbidden_list);
		
		fclose(fp);
		
		chmod(conf_file, 0644);
		
		return 0;
	}

	return 1;
}
Example #3
0
/* Serve the client that connected to the webserver
 */
static int serve_client(t_session *session) {
	int result, length, auth_result;
	char *qmark, chr, *header;
	t_host *host_record;
	t_access access;
	t_deny_body *deny_body;
	t_req_method request_method;
	t_ip_addr ip_addr;
#ifdef ENABLE_XSLT
	char *xslt_file;
#endif
#ifdef ENABLE_TOOLKIT
	int i;
	t_toolkit_options toolkit_options;
#endif
#ifdef ENABLE_RPROXY
	t_rproxy *rproxy;
#endif

#ifdef ENABLE_DEBUG
	session->current_task = "fetch & parse request";
#endif

	if ((result = fetch_request(session)) != 200) {
		session->request_method = GET;
		return result;
	} else if ((result = parse_request(session, session->header_length + session->content_length)) != 200) {
		session->request_method = GET;
		return result;
	}

#ifdef ENABLE_DEBUG
	session->current_task = "serve client";
#endif

	session->time = time(NULL);

	/* Hide reverse proxies
	 */
	if (in_iplist(session->config->hide_proxy, &(session->ip_address))) {
		if (last_forwarded_ip(session->http_headers, &ip_addr) == 0) {
			if (reposition_client(session, &ip_addr) != -1) {
				copy_ip(&(session->ip_address), &ip_addr);
			}
		}
	}

	/* SSH tunneling
	 */
#ifdef ENABLE_RPROXY
	if (session->request_method == CONNECT) {
		if (in_iplist(session->config->tunnel_ssh, &(session->ip_address)) == false) {
			return 405;
		}

#ifdef ENABLE_SSL
		if (session->binding->use_ssl) {
			return 405;
		}
#endif

		if (strcmp(session->request_uri, "localhost:22") != 0) {
			if (strcmp(session->request_uri, "127.0.0.1:22") != 0) {
				if (strcmp(session->request_uri, "::1.22") != 0) {
					return 403;
				}
			}
		}

		log_system(session, "SSH tunnel requested");
		if (tunnel_ssh_connection(session->client_socket) != 0) {
			log_system(session, "SSH tunnel failed");
		} else {
			log_system(session, "SSH tunnel terminated");
		}

		session->keep_alive = false;

		return 200;
	}
#endif

	/* Find host record
	 */
	if (session->hostname != NULL) {
		if (remove_port_from_hostname(session) == -1) {
			log_error(session, "error removing port from hostname");
			return 500;
		}

		if ((host_record = get_hostrecord(session->config->first_host, session->hostname, session->binding)) != NULL) {
			session->host = host_record;
#ifdef ENABLE_TOMAHAWK
			session->last_host = host_record;
#endif
		}
	}
	session->host->access_time = session->time;

#ifdef ENABLE_SSL
	/* SSL client authentication
	 */
	if (session->binding->use_ssl) {
		if ((session->host->ca_certificate != NULL) && (ssl_has_peer_cert(&(session->ssl_context)) == false)) {
			log_error(session, "Missing client SSL certificate");
			return 440;
		}
	}
#endif

	/* Enforce usage of first hostname
	 */
	if (session->host->enforce_first_hostname && (session->hostname != NULL)) {
		if (**(session->host->hostname.item) != '*') {
			if (strcmp(session->hostname, *(session->host->hostname.item)) != 0) {
				session->cause_of_301 = enforce_first_hostname;
				return 301;
			}
		}
	}

	/* Enforce usage of SSL
	 */
#ifdef ENABLE_SSL
	if (session->host->require_ssl && (session->binding->use_ssl == false)) {
		if ((qmark = strchr(session->uri, '?')) != NULL) {
			*qmark = '\0';
			session->vars = qmark + 1;
			session->uri_len = strlen(session->uri);
		}
		session->cause_of_301 = require_ssl;
		return 301;
	}
#endif

	/* Deny matching bodies
	 */
	if (session->body != NULL) {
		chr = *(session->body + session->content_length);
		*(session->body + session->content_length) = '\0';

		deny_body = session->host->deny_body;
		while (deny_body != NULL) {
			if (strpcmp(session->body, &(deny_body->pattern)) == 0) {
				if ((session->config->ban_on_denied_body > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) {
					ban_ip(&(session->ip_address), session->config->ban_on_denied_body, session->config->kick_on_ban);
					log_system(session, "Client banned because of denied body");
#ifdef ENABLE_MONITOR
					if (session->config->monitor_enabled) {
						monitor_count_ban(session);
					}
#endif
				}

				log_exploit_attempt(session, "denied body", session->body);
#ifdef ENABLE_TOMAHAWK
				increment_counter(COUNTER_EXPLOIT);
#endif
#ifdef ENABLE_MONITOR
				if (session->config->monitor_enabled) {
					monitor_count_exploit(session);
					monitor_event("Request body denied for %s", session->host->hostname.item[0]);
				}
#endif

				*(session->body + session->content_length) = chr;

				return 403;
			}
			deny_body = deny_body->next;
		}

		*(session->body + session->content_length) = chr;
	}

	/* Websocket
	 */
	if (session->request_method == GET) {
		if ((header = get_http_header("Connection:", session->http_headers)) != NULL) {
			if (strcasestr(header, "upgrade") != NULL) {
				if ((header = get_http_header("Upgrade:", session->http_headers)) != NULL) {
					if (strcasecmp(header, "websocket") == 0) {
						switch (access = allow_client(session)) {
							case deny:
								log_error(session, fb_accesslist);
								return 403;
							case allow:
								break;
							case pwd:
							case unspecified:
								if ((auth_result = http_authentication_result(session, access == unspecified)) != 200) {
									return auth_result;
								}
						}

						session->keep_alive = false;
						if (forward_to_websocket(session) == -1) {
							return 500;
						}

						return 200;
					}
				}
			}
		}
	}

#ifdef ENABLE_RPROXY
	/* Reverse proxy
	 */
	rproxy = session->host->rproxy;
	while (rproxy != NULL) {
		if (rproxy_match(rproxy, session->request_uri)) {
			if (rproxy_loop_detected(session->http_headers)) {
				return 508;
			}

			if ((qmark = strchr(session->uri, '?')) != NULL) {
				*qmark = '\0';
				session->vars = qmark + 1;
			}

			if (validate_url(session) == false) {
				return -1;
			}

			if ((session->vars != NULL) && (session->host->secure_url)) {
				if (forbidden_chars_present(session->vars)) {
					log_error(session, "URL contains forbidden characters");
					return 403;
				}
			}

			if (duplicate_host(session) == false) {
				log_error(session, "duplicate_host() error");
				return 500;
			}

			if ((result = uri_to_path(session)) != 200) {
				return result;
			}

			if (session->host->ignore_dot_hiawatha == false) {
				if (load_user_config(session) == -1) {
					return 500;
				}
			}

			if ((result = copy_directory_settings(session)) != 200) {
				return result;
			}

			switch (access = allow_client(session)) {
				case deny:
					log_error(session, fb_accesslist);
					return 403;
				case allow:
					break;
				case pwd:
				case unspecified:
					if ((auth_result = http_authentication_result(session, access == unspecified)) != 200) {
						return auth_result;
					}
			}

			/* Prevent SQL injection
			 */
			if (session->host->prevent_sqli) {
				result = prevent_sqli(session);
				if (result == 1) {
					session->error_cause = ec_SQL_INJECTION;
				}
				if (result != 0) {
					return -1;
				}
			}

			/* Prevent Cross-site Scripting
			 */
			if (session->host->prevent_xss != p_no) {
				if (prevent_xss(session) > 0) {
					if (session->host->prevent_xss == p_block) {
						session->error_cause = ec_XSS;
						return -1;
					}
				}
			}

			/* Prevent Cross-site Request Forgery
			 */
			if (session->host->prevent_csrf != p_no) {
				if (prevent_csrf(session) > 0) {
					if (session->host->prevent_csrf == p_block) {
						session->error_cause = ec_CSRF;
						return -1;
					}
				}
			}

			return proxy_request(session, rproxy);
		}

		rproxy = rproxy->next;
	}
#endif

	/* Actions based on request method
	 */
	switch (session->request_method) {
		case TRACE:
			if (session->binding->enable_trace == false) {
				return 501;
			}
			return handle_trace_request(session);
		case PUT:
		case DELETE:
			if ((session->binding->enable_alter == false) && (session->host->webdav_app == false)) {
				return 501;
			}
			break;
		case unknown:
			return 400;
		case unsupported:
			if (session->host->webdav_app == false) {
				return 501;
			}
			break;
		default:
			break;
	}

	if (duplicate_host(session) == false) {
		log_error(session, "duplicate_host() error");
		return 500;
	}

#ifdef ENABLE_TOOLKIT
	if (session->host->ignore_dot_hiawatha == false) {
		if (load_user_root_config(session) == -1) {
			return 500;
		}
	}

	/* URL toolkit
	 */
	init_toolkit_options(&toolkit_options);
	toolkit_options.method = session->method;
	toolkit_options.website_root = session->host->website_root;
	toolkit_options.url_toolkit = session->config->url_toolkit;
	toolkit_options.allow_dot_files = session->host->allow_dot_files;
	toolkit_options.http_headers = session->http_headers;
#ifdef ENABLE_SSL
	toolkit_options.use_ssl = session->binding->use_ssl;
#endif

	if (((session->request_method != PUT) && (session->request_method != DELETE)) || session->host->webdav_app) {
		for (i = 0; i < session->host->toolkit_rules.size; i++) {
			if ((result = use_toolkit(session->uri, session->host->toolkit_rules.item[i], &toolkit_options)) == UT_ERROR) {
				return 500;
			}

			if ((toolkit_options.ban > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) {
				ban_ip(&(session->ip_address), toolkit_options.ban, session->config->kick_on_ban);
				log_system(session, "Client banned because of URL match in UrlToolkit rule");
#ifdef ENABLE_MONITOR
				if (session->config->monitor_enabled) {
					monitor_count_ban(session);
				}
#endif
				return 403;
			}

			session->toolkit_fastcgi = toolkit_options.fastcgi_server;
			if (toolkit_options.new_url != NULL) {
				if (register_tempdata(&(session->tempdata), toolkit_options.new_url, tc_data) == -1) {
					free(toolkit_options.new_url);
					log_error(session, "error registering temporary data");
					return 500;
				}
				session->uri = toolkit_options.new_url;
			}

			if (result == UT_REDIRECT) {
				if ((session->location = strdup(toolkit_options.new_url)) == NULL) {
					return -1;
				}
				session->cause_of_301 = location;
				return 301;
			}

			if (result == UT_DENY_ACCESS) {
				log_error(session, "access denied via URL toolkit rule");
				return 403;
			}

			if (toolkit_options.expire > -1) {
				session->expires = toolkit_options.expire;
				session->caco_private = toolkit_options.caco_private;
			}
		}
	}
#endif

	/* Find GET data
	 */
	if ((qmark = strchr(session->uri, '?')) != NULL) {
		*qmark = '\0';
		session->vars = qmark + 1;
	}

	url_decode(session->uri);
	session->uri_len = strlen(session->uri);

	if ((session->vars != NULL) && (session->host->secure_url)) {
		if (forbidden_chars_present(session->vars)) {
			log_error(session, "URL contains forbidden characters");
			return 403;
		}
	}

	if (validate_url(session) == false) {
		return -1;
	}

	if ((result = uri_to_path(session)) != 200) {
		return result;
	}

	/* Load configfile from directories
	 */
	if (session->host->ignore_dot_hiawatha == false) {
		if (load_user_config(session) == -1) {
			return 500;
		}
	}

	if ((result = copy_directory_settings(session)) != 200) {
		return result;
	}

	switch (access = allow_client(session)) {
		case deny:
			log_error(session, fb_accesslist);
			return 403;
		case allow:
			break;
		case pwd:
		case unspecified:
			if ((auth_result = http_authentication_result(session, access == unspecified)) != 200) {
				return auth_result;
			}
	}

	switch (is_directory(session->file_on_disk)) {
		case error:
			return 500;
		case yes:
			session->uri_is_dir = true;
			break;
		case no:
			if (((session->request_method != PUT) || session->host->webdav_app) && (session->host->enable_path_info)) {
				if ((result = get_path_info(session)) != 200) {
					return result;
				}
			}
			break;
		case no_access:
			log_error(session, fb_filesystem);
			return 403;
		case not_found:
			if (session->request_method == DELETE) {
				return 404;
			}
	}

#ifdef ENABLE_TOOLKIT
	if ((session->toolkit_fastcgi == NULL) && session->uri_is_dir) {
#else
	if (session->uri_is_dir) {
#endif
		length = strlen(session->file_on_disk);
		if (*(session->file_on_disk + length - 1) == '/') {
			strcpy(session->file_on_disk + length, session->host->start_file);
		} else {
			return 301;
		}
	}

	if (get_target_extension(session) == -1) {
		log_error(session, "error getting extension");
		return 500;
	}

	if (((session->request_method != PUT) && (session->request_method != DELETE)) || session->host->webdav_app) {
		check_target_is_cgi(session);
	}

	/* Handle request based on request method
	 */
	request_method = session->request_method;
	if (session->host->webdav_app) {
		if ((request_method == PUT) || (request_method == DELETE)) {
			request_method = POST;
		}
	}

	switch (request_method) {
		case GET:
		case HEAD:
			if (session->cgi_type != no_cgi) {
				session->body = NULL;
				result = execute_cgi(session);
#ifdef ENABLE_XSLT
			} else if ((xslt_file = find_xslt_file(session)) != NULL) {
				result = handle_xml_file(session, xslt_file);
				free(xslt_file);
#endif
			} else {
				result = send_file(session);
			}
			if (result == 404) {
#ifdef ENABLE_XSLT
				if ((session->host->show_index != NULL) && (session->uri[session->uri_len - 1] == '/')) {
					result = show_index(session);
				}
#endif
#ifdef ENABLE_MONITOR
			} else if (session->config->monitor_enabled) {
				if ((result == 200) && (session->host->monitor_host)) {
					unlink(session->file_on_disk);
				}
#endif
			}

			if ((session->request_method == GET) && (session->cgi_type == no_cgi) && (session->directory != NULL)) {
				if (session->directory->run_on_download != NULL) {
					run_program(session, session->directory->run_on_download, result);
				}
			}
			break;
		case POST:
		case unsupported:
			if (session->cgi_type != no_cgi) {
				result = execute_cgi(session);
#ifdef ENABLE_XSLT
			} else if ((xslt_file = find_xslt_file(session)) != NULL) {
				result = handle_xml_file(session, xslt_file);
				free(xslt_file);
#endif
			} else {
				result = 405;
			}
			break;
		case PUT:
			result = handle_put_request(session);
			if (((result == 201) || (result == 204)) && (session->host->run_on_alter != NULL)) {
				run_program(session, session->host->run_on_alter, result);
			}
			break;
		case DELETE:
			result = handle_delete_request(session);
			if ((result == 204) && (session->host->run_on_alter != NULL)) {
				run_program(session, session->host->run_on_alter, result);
			}
			break;
		case WHEN:
			send_code(session);
			break;
		default:
			result = 400;
	}

	return result;
}

/* Handle timeout upon sending request
 */
static void handle_timeout(t_session *session) {
	if ((session->config->ban_on_timeout > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) {
		ban_ip(&(session->ip_address), session->config->ban_on_timeout, session->config->kick_on_ban);
		log_system(session, "Client banned because of connection timeout");
#ifdef ENABLE_MONITOR
		if (session->config->monitor_enabled) {
			monitor_count_ban(session);
		}
#endif
	} else {
		log_system(session, "Timeout while waiting for first request");
	}
}

/* Request has been handled, handle the return code.
 */
static void handle_request_result(t_session *session, int result) {
	char *hostname;

#ifdef ENABLE_DEBUG
	session->current_task = "handle request result";
#endif

	if (result == -1) switch (session->error_cause) {
		case ec_MAX_REQUESTSIZE:
			log_system(session, "Maximum request size reached");
			session->return_code = 413;
			send_code(session);
			if ((session->config->ban_on_max_request_size > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) {
				ban_ip(&(session->ip_address), session->config->ban_on_max_request_size, session->config->kick_on_ban);
				log_system(session, "Client banned because of sending a too large request");
#ifdef ENABLE_MONITOR
				if (session->config->monitor_enabled) {
					monitor_count_ban(session);
				}
#endif
			}
			break;
		case ec_TIMEOUT:
			if (session->kept_alive == 0) {
				session->return_code = 408;
				send_code(session);
				handle_timeout(session);
			}
			break;
		case ec_CLIENT_DISCONNECTED:
			if (session->kept_alive == 0) {
				log_system(session, "Silent client disconnected");
			}
			break;
		case ec_SOCKET_READ_ERROR:
			if (errno != ECONNRESET) {
				log_system(session, "Error while reading request");
			}
			break;
		case ec_SOCKET_WRITE_ERROR:
			log_request(session);
			break;
		case ec_FORCE_QUIT:
			log_system(session, "Client kicked");
			break;
		case ec_SQL_INJECTION:
			if ((session->config->ban_on_sqli > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) {
				ban_ip(&(session->ip_address), session->config->ban_on_sqli, session->config->kick_on_ban);
				hostname = (session->hostname != NULL) ? session->hostname : unknown_host;
				log_system(session, "Client banned because of SQL injection on %s", hostname);
#ifdef ENABLE_MONITOR
				if (session->config->monitor_enabled) {
					monitor_count_ban(session);
				}
#endif
			}
			session->return_code = 441;
			send_code(session);
			log_request(session);
			break;
		case ec_XSS:
			session->return_code = 442;
			send_code(session);
			log_request(session);
			break;
		case ec_CSRF:
			session->return_code = 443;
			send_code(session);
			log_request(session);
			break;
		case ec_INVALID_URL:
			if ((session->config->ban_on_invalid_url > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) {
				ban_ip(&(session->ip_address), session->config->ban_on_invalid_url, session->config->kick_on_ban);
				hostname = (session->hostname != NULL) ? session->hostname : unknown_host;
				log_system(session, "Client banned because of invalid URL on %s", hostname);
#ifdef ENABLE_MONITOR
				if (session->config->monitor_enabled) {
					monitor_count_ban(session);
				}
#endif
			}
			send_code(session);
			break;
		default:
			if (session->data_sent == false) {
				session->return_code = 500;
				if (send_code(session) == -1) {
					session->keep_alive = false;
				}
			}
	} else switch (result) {
		case 200:
			break;
		case 201:
		case 204:
		case 304:
		case 412:
			if (session->data_sent == false) {
				session->return_code = result;
				if (send_header(session) == -1) {
					session->keep_alive = false;
				} else if (send_buffer(session, "Content-Length: 0\r\n\r\n", 21) == -1) {
					session->keep_alive = false;
				}
			}
			break;
		case 411:
		case 413:
			session->keep_alive = false;
			if (session->data_sent == false) {
				session->return_code = result;
				if (send_header(session) == -1) {
					session->keep_alive = false;
				} else if (send_buffer(session, "Content-Length: 0\r\n\r\n", 21) == -1) {
					session->keep_alive = false;
				}
			}
			break;
		case 400:
			log_garbage(session);
			if (session->data_sent == false) {
				session->return_code = 400;
				if (send_code(session) == -1) {
					session->keep_alive = false;
				}
			}
			if ((session->config->ban_on_garbage > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) {
				ban_ip(&(session->ip_address), session->config->ban_on_garbage, session->config->kick_on_ban);
				log_system(session, "Client banned because of sending garbage");
#ifdef ENABLE_MONITOR
				if (session->config->monitor_enabled) {
					monitor_count_ban(session);
				}
#endif
			}
#ifdef ENABLE_MONITOR
			if (session->config->monitor_enabled) {
				monitor_count_bad_request(session);
			}
#endif
			break;
		case 401:
		case 403:
		case 404:
		case 501:
		case 503:
			if (session->data_sent == false) {
				switch (handle_error(session, result)) {
					case -1:
						session->keep_alive = false;
						break;
					case 200:
						break;
					default:
						if (session->data_sent == false) {
							session->return_code = result;
							if (send_code(session) == -1) {
								session->keep_alive = false;
							}
						}
				}
			}
			break;
		case 500:
			session->keep_alive = false;
		default:
			if (session->data_sent == false) {
				session->return_code = result;
				send_code(session);
			}
	}

	if ((result > 0) && (result != 400)) {
		log_request(session);
	} else {
		session->keep_alive = false;
	}
}
Example #4
0
static void
inner_main (void *closure, int argc, char **argv)
{
    SCM main_mod;
    char* fn;
    GError *error = NULL;

    scm_c_eval_string("(debug-set! stack 200000)");

    main_mod = scm_c_resolve_module("gnucash main");
    scm_set_current_module(main_mod);

    load_gnucash_modules();

    /* Load the config before starting up the gui. This insures that
     * custom reports have been read into memory before the Reports
     * menu is created. */
    load_system_config();
    load_user_config();

    /* Setting-up the report menu must come after the module
       loading but before the gui initialization. */
    scm_c_use_module("gnucash report report-gnome");
    scm_c_eval_string("(gnc:report-menu-setup)");

    /* TODO: After some more guile-extraction, this should happen even
       before booting guile.  */
    gnc_main_gui_init();

    gnc_hook_add_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit, NULL);

    scm_c_eval_string("(gnc:main)");

    /* Install Price Quote Sources */
    gnc_update_splash_screen(_("Checking Finance::Quote..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
    scm_c_use_module("gnucash price-quotes");
    scm_c_eval_string("(gnc:price-quotes-install-sources)");

    gnc_hook_run(HOOK_STARTUP, NULL);

    if (!nofile && (fn = get_file_to_load()))
    {
        gnc_update_splash_screen(_("Loading data..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
        gnc_file_open_file(fn);
        g_free(fn);
    }
    else if (gnc_gconf_get_bool("dialogs/new_user", "first_startup", &error)
             && !error)
    {
        gnc_destroy_splash_screen();
        gnc_ui_new_user_dialog();
    }

    gnc_destroy_splash_screen();

    gnc_main_window_show_all_windows();

    gnc_hook_run(HOOK_UI_POST_STARTUP, NULL);
    gnc_ui_start_event_loop();
    gnc_hook_remove_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit);

    gnc_shutdown(0);
    return;
}
Example #5
0
static int
openvpn_create_client_conf(const char *conf_file, int is_tun)
{
    FILE *fp;
    int i, i_prot, i_prot_ori, i_auth, i_atls;
    const char *p_peer, *p_prot;

    i_auth = nvram_get_int("vpnc_ov_auth");
    i_atls = nvram_get_int("vpnc_ov_atls");

    for (i=0; i<4; i++) {
        if (i_auth == 1 && (i == 1 || i == 2))
            continue;
        if (!i_atls && (i == 3))
            continue;
        if (!openvpn_check_key(openvpn_client_keys[i], 0))
            return 1;
    }

    i_prot = nvram_get_int("vpnc_ov_prot");
    i_prot_ori = i_prot;
    if (i_prot > 1 && get_ipv6_type() == IPV6_DISABLED)
        i_prot &= 1;

    p_peer = nvram_safe_get("vpnc_peer");

    /* note: upcoming openvpn 2.4 will need direct set udp4/tcp4-client for ipv4 only */
#if defined (USE_IPV6)
    /* check peer address is direct ipv4/ipv6 */
    if (i_prot > 1 && is_valid_ipv4(p_peer))
        i_prot &= 1;
    else if (i_prot < 2 && is_valid_ipv6(p_peer))
        i_prot += 2;

    if (i_prot == 3)
        p_prot = "tcp6-client";
    else if (i_prot == 2)
        p_prot = "udp6";
    else
#endif
        if (i_prot == 1)
            p_prot = "tcp-client";
        else
            p_prot = "udp";

    /* fixup ipv4/ipv6 mismatch */
    if (i_prot != i_prot_ori)
        nvram_set_int("vpnc_ov_prot", i_prot);

    fp = fopen(conf_file, "w+");
    if (!fp)
        return 1;

    fprintf(fp, "client\n");
    fprintf(fp, "proto %s\n", p_prot);
    fprintf(fp, "remote %s %d\n", p_peer, nvram_safe_get_int("vpnc_ov_port", 1194, 1, 65535));
    fprintf(fp, "resolv-retry %s\n", "infinite");
    fprintf(fp, "nobind\n");

    fprintf(fp, "dev %s\n", (is_tun) ? IFNAME_CLIENT_TUN : IFNAME_CLIENT_TAP);

    fprintf(fp, "ca %s/%s\n", CLIENT_CERT_DIR, openvpn_client_keys[0]);
    if (i_auth == 0) {
        fprintf(fp, "cert %s/%s\n", CLIENT_CERT_DIR, openvpn_client_keys[1]);
        fprintf(fp, "key %s/%s\n", CLIENT_CERT_DIR, openvpn_client_keys[2]);
    }

    if (i_atls)
        fprintf(fp, "tls-auth %s/%s %d\n", CLIENT_CERT_DIR, openvpn_client_keys[3], 1);

    openvpn_add_auth(fp, nvram_get_int("vpnc_ov_mdig"));
    openvpn_add_cipher(fp, nvram_get_int("vpnc_ov_ciph"));
    openvpn_add_lzo(fp, nvram_get_int("vpnc_ov_clzo"), 0);

    if (i_auth == 1) {
        fprintf(fp, "auth-user-pass %s\n", "secret");
        openvpn_create_client_secret("secret");
    }

    if (nvram_match("vpnc_dgw", "1"))
        fprintf(fp, "redirect-gateway def1 bypass-dhcp\n");

    fprintf(fp, "persist-key\n");
    fprintf(fp, "script-security %d\n", 2);
    fprintf(fp, "writepid %s\n", CLIENT_PID_FILE);

    fprintf(fp, "up %s\n",  SCRIPT_OVPN_CLIENT);
    fprintf(fp, "down %s\n",  SCRIPT_OVPN_CLIENT);

    fprintf(fp, "\n### User params:\n");

    load_user_config(fp, CLIENT_CERT_DIR, "client.conf", forbidden_list);

    fclose(fp);

    chmod(conf_file, 0644);

    return 0;
}
Example #6
0
static int
openvpn_create_server_conf(const char *conf_file, int is_tun)
{
    FILE *fp;
    int i, i_prot, i_prot_ori, i_atls, i_rdgw, i_dhcp, i_items;
    unsigned int laddr, lmask;
    char *lanip, *lannm, *wins, *dns1, *dns2;
    const char *p_prot;
    struct in_addr pool_in;

    i_atls = nvram_get_int("vpns_ov_atls");

    for (i=0; i<5; i++) {
        if (!i_atls && (i == 4))
            continue;
        if (!openvpn_check_key(openvpn_server_keys[i], 1))
            return 1;
    }

    i_prot = nvram_get_int("vpns_ov_prot");
    i_rdgw = nvram_get_int("vpns_ov_rdgw");

    i_dhcp = is_dhcpd_enabled(0);

    lanip = nvram_safe_get("lan_ipaddr");
    lannm = nvram_safe_get("lan_netmask");

    laddr = ntohl(inet_addr(lanip));
    lmask = ntohl(inet_addr(lannm));

    i_prot_ori = i_prot;
    if (i_prot > 1 && get_ipv6_type() == IPV6_DISABLED)
        i_prot &= 1;

    /* note: upcoming openvpn 2.4 will need direct set udp4/tcp4-server for ipv4 only */
#if defined (USE_IPV6)
    if (i_prot == 3)
        p_prot = "tcp6-server";
    else if (i_prot == 2)
        p_prot = "udp6";
    else
#endif
        if (i_prot == 1)
            p_prot = "tcp-server";
        else
            p_prot = "udp";

    /* fixup ipv4/ipv6 mismatch */
    if (i_prot != i_prot_ori)
        nvram_set_int("vpns_ov_prot", i_prot);

    fp = fopen(conf_file, "w+");
    if (!fp)
        return 1;

    fprintf(fp, "proto %s\n", p_prot);
    fprintf(fp, "port %d\n", nvram_safe_get_int("vpns_ov_port", 1194, 1, 65535));

    if (is_tun) {
        unsigned int vnet, vmsk;

        vnet = ntohl(inet_addr(nvram_safe_get("vpns_vnet")));
        vmsk = ntohl(inet_addr(VPN_SERVER_SUBNET_MASK));
        pool_in.s_addr = htonl(vnet & vmsk);

        fprintf(fp, "dev %s\n", IFNAME_SERVER_TUN);
        fprintf(fp, "topology %s\n", "subnet");
        fprintf(fp, "server %s %s\n", inet_ntoa(pool_in), VPN_SERVER_SUBNET_MASK);
        fprintf(fp, "client-config-dir %s\n", "ccd");

        openvpn_create_server_acl(fp, "ccd", vnet, vmsk);

        pool_in.s_addr = htonl(laddr & lmask);
        fprintf(fp, "push \"route %s %s\"\n", inet_ntoa(pool_in), lannm);
    } else {
        char sp_b[INET_ADDRSTRLEN], sp_e[INET_ADDRSTRLEN];
        unsigned int vp_b, vp_e, lnet;

        lnet = ~(lmask) - 1;
        vp_b = (unsigned int)nvram_safe_get_int("vpns_cli0", 245, 1, 254);
        vp_e = (unsigned int)nvram_safe_get_int("vpns_cli1", 254, 2, 254);
        if (vp_b > lnet)
            vp_b = lnet;
        if (vp_e > lnet)
            vp_e = lnet;
        if (vp_e < vp_b)
            vp_e = vp_b;

        pool_in.s_addr = htonl((laddr & lmask) | vp_b);
        strcpy(sp_b, inet_ntoa(pool_in));

        pool_in.s_addr = htonl((laddr & lmask) | vp_e);
        strcpy(sp_e, inet_ntoa(pool_in));

        fprintf(fp, "dev %s\n", IFNAME_SERVER_TAP);
        fprintf(fp, "server-bridge %s %s %s %s\n", lanip, lannm, sp_b, sp_e);
    }

    openvpn_add_auth(fp, nvram_get_int("vpns_ov_mdig"));
    openvpn_add_cipher(fp, nvram_get_int("vpns_ov_ciph"));
    openvpn_add_lzo(fp, nvram_get_int("vpns_ov_clzo"), 1);

    i_items = 0;
    if (i_rdgw) {
        fprintf(fp, "push \"redirect-gateway def1 %s\"\n", "bypass-dhcp");

        if (i_dhcp) {
            dns1 = nvram_safe_get("dhcp_dns1_x");
            dns2 = nvram_safe_get("dhcp_dns2_x");
            if (is_valid_ipv4(dns1)) {
                i_items++;
                fprintf(fp, "push \"dhcp-option %s %s\"\n", "DNS", dns1);
            }
            if (is_valid_ipv4(dns2) && strcmp(dns2, dns1)) {
                i_items++;
                fprintf(fp, "push \"dhcp-option %s %s\"\n", "DNS", dns2);
            }
        }

        if (i_items < 1)
            fprintf(fp, "push \"dhcp-option %s %s\"\n", "DNS", lanip);
    }

    i_items = 0;
    if (i_dhcp) {
        wins = nvram_safe_get("dhcp_wins_x");
        if (is_valid_ipv4(wins)) {
            i_items++;
            fprintf(fp, "push \"dhcp-option %s %s\"\n", "WINS", wins);
        }
    }

#if defined(APP_SMBD) || defined(APP_NMBD)
    if ((i_items < 1) && nvram_get_int("wins_enable"))
        fprintf(fp, "push \"dhcp-option %s %s\"\n", "WINS", lanip);
#endif

    fprintf(fp, "ca %s/%s\n", SERVER_CERT_DIR, openvpn_server_keys[0]);
    fprintf(fp, "dh %s/%s\n", SERVER_CERT_DIR, openvpn_server_keys[1]);
    fprintf(fp, "cert %s/%s\n", SERVER_CERT_DIR, openvpn_server_keys[2]);
    fprintf(fp, "key %s/%s\n", SERVER_CERT_DIR, openvpn_server_keys[3]);

    if (i_atls)
        fprintf(fp, "tls-auth %s/%s %d\n", SERVER_CERT_DIR, openvpn_server_keys[4], 0);

    fprintf(fp, "persist-key\n");
    fprintf(fp, "persist-tun\n");
    fprintf(fp, "user %s\n", SYS_USER_NOBODY);
    fprintf(fp, "group %s\n", SYS_GROUP_NOGROUP);
    fprintf(fp, "script-security %d\n", 2);
    fprintf(fp, "tmp-dir %s\n", COMMON_TEMP_DIR);
    fprintf(fp, "writepid %s\n", SERVER_PID_FILE);

    fprintf(fp, "client-connect %s\n", SCRIPT_OVPN_SERVER);
    fprintf(fp, "client-disconnect %s\n", SCRIPT_OVPN_SERVER);

    fprintf(fp, "\n### User params:\n");

    load_user_config(fp, SERVER_CERT_DIR, "server.conf", forbidden_list);

    fclose(fp);

    chmod(conf_file, 0644);

    return 0;
}