static int uwsgi_sni_cb(SSL *ssl, int *ad, void *arg) {
        const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
        if (!servername) return SSL_TLSEXT_ERR_NOACK;
        size_t servername_len = strlen(servername);

        struct uwsgi_string_list *usl = uwsgi.sni;
        while(usl) {
                if (!uwsgi_strncmp(usl->value, usl->len, (char *)servername, servername_len)) {
                        SSL_set_SSL_CTX(ssl, usl->custom_ptr);
                        return SSL_TLSEXT_ERR_OK;
                }
                usl = usl->next;
        }

#ifdef UWSGI_PCRE
        struct uwsgi_regexp_list *url = uwsgi.sni_regexp;
        while(url) {
                if (uwsgi_regexp_match(url->pattern, url->pattern_extra, (char *)servername, servername_len) >= 0) {
                        SSL_set_SSL_CTX(ssl, url->custom_ptr);
                        return SSL_TLSEXT_ERR_OK;
                }
                url = url->next;
        }
#endif

	if (uwsgi.sni_dir) {
		size_t sni_dir_len = strlen(uwsgi.sni_dir);
		char *sni_dir_cert = uwsgi_concat4n(uwsgi.sni_dir, sni_dir_len, "/", 1, (char *) servername, servername_len, ".crt", 4);
		char *sni_dir_key = uwsgi_concat4n(uwsgi.sni_dir, sni_dir_len, "/", 1, (char *) servername, servername_len, ".key", 4);
		char *sni_dir_client_ca = uwsgi_concat4n(uwsgi.sni_dir, sni_dir_len, "/", 1, (char *) servername, servername_len, ".ca", 3);
		if (uwsgi_file_exists(sni_dir_cert) && uwsgi_file_exists(sni_dir_key)) {
			char *client_ca = NULL;
			if (uwsgi_file_exists(sni_dir_client_ca)) {
				client_ca = sni_dir_client_ca;
			}
			usl = uwsgi_ssl_add_sni_item(uwsgi_str((char *)servername), sni_dir_cert, sni_dir_key, uwsgi.sni_dir_ciphers, client_ca);
			if (!usl) goto done;
			free(sni_dir_cert);
			free(sni_dir_key);
			free(sni_dir_client_ca);
			SSL_set_SSL_CTX(ssl, usl->custom_ptr);
			uwsgi_log("[uwsgi-sni for pid %d] added context for %s\n", (int) getpid(), servername);
			return SSL_TLSEXT_ERR_OK;
		}
done:
		free(sni_dir_cert);
		free(sni_dir_key);
		free(sni_dir_client_ca);
	}

        return SSL_TLSEXT_ERR_NOACK;
}
Exemple #2
0
int uwsgi_logic_opt_if_not_exists(char *key, char *value) {

        if (!uwsgi_file_exists(uwsgi.logic_opt_data)) {
                add_exported_option(key, uwsgi_substitute(value, "%(_)", uwsgi.logic_opt_data), 0);
                return 1;
        }

        return 0;
}
Exemple #3
0
void uwsgi_subscribe(char *subscription, uint8_t cmd) {

	int subfile_size;
	int i;
	char *key = NULL;
	int keysize = 0;
	char *modifier1 = NULL;
	int modifier1_len = 0;
	char *socket_name = NULL;
	char *udp_address = subscription;
	char *udp_port = NULL;
	char *subscription_key = NULL;
	char *sign = NULL;

	// check for explicit socket_name
	char *equal = strchr(subscription, '=');
	if (equal) {
		socket_name = subscription;
		if (socket_name[0] == '=') {
			equal = strchr(socket_name + 1, '=');
			if (!equal)
				return;
			*equal = '\0';
			struct uwsgi_socket *us = uwsgi_get_shared_socket_by_num(atoi(socket_name + 1));
			if (!us)
				return;
			socket_name = us->name;
		}
		*equal = '\0';
		udp_address = equal + 1;
	}

	// check for unix socket
	if (udp_address[0] != '/') {
		udp_port = strchr(udp_address, ':');
		if (!udp_port) {
			if (equal)
				*equal = '=';
			return;
		}
		subscription_key = strchr(udp_port + 1, ':');
	}
	else {
		subscription_key = strchr(udp_address + 1, ':');
	}

	if (!subscription_key) {
		if (equal)
			*equal = '=';
		return;
	}

	udp_address = uwsgi_concat2n(udp_address, subscription_key - udp_address, "", 0);

	if (subscription_key[1] == '@') {
		if (!uwsgi_file_exists(subscription_key + 2))
			goto clear;
		char *lines = uwsgi_open_and_read(subscription_key + 2, &subfile_size, 1, NULL);
		if (subfile_size > 0) {
			key = lines;
			for (i = 0; i < subfile_size; i++) {
				if (lines[i] == 0) {
					if (keysize > 0) {
						if (key[0] != '#' && key[0] != '\n') {
							modifier1 = strchr(key, ',');
							if (modifier1) {
								modifier1[0] = 0;
								modifier1++;
								modifier1_len = strlen(modifier1);
								keysize = strlen(key);
							}
							uwsgi_send_subscription(udp_address, key, keysize, uwsgi_str_num(modifier1, modifier1_len), 0, cmd, socket_name, sign);
							modifier1 = NULL;
							modifier1_len = 0;
						}
					}
					break;
				}
				else if (lines[i] == '\n') {
					if (keysize > 0) {
						if (key[0] != '#' && key[0] != '\n') {
							lines[i] = 0;
							modifier1 = strchr(key, ',');
							if (modifier1) {
								modifier1[0] = 0;
								modifier1++;
								modifier1_len = strlen(modifier1);
								keysize = strlen(key);
							}
							uwsgi_send_subscription(udp_address, key, keysize, uwsgi_str_num(modifier1, modifier1_len), 0, cmd, socket_name, sign);
							modifier1 = NULL;
							modifier1_len = 0;
							lines[i] = '\n';
						}
					}
					key = lines + i + 1;
					keysize = 0;
					continue;
				}
				keysize++;
			}

			free(lines);
		}
	}
	else {
		modifier1 = strchr(subscription_key + 1, ',');
		if (modifier1) {
			modifier1[0] = 0;
			modifier1++;

			sign = strchr(modifier1 + 1, ',');
			if (sign) {
				*sign = 0;
				sign++;
			}
			modifier1_len = strlen(modifier1);
		}

		uwsgi_send_subscription(udp_address, subscription_key + 1, strlen(subscription_key + 1), uwsgi_str_num(modifier1, modifier1_len), 0, cmd, socket_name, sign);
		if (modifier1)
			modifier1[-1] = ',';
		if (sign)
			sign[-1] = ',';
	}

clear:
	if (equal)
		*equal = '=';
	free(udp_address);

}
Exemple #4
0
static int uwsgi_pypy_init() {

	size_t rlen = 0;
	char *buffer = NULL;

	void *is_cpython_loaded = dlsym(RTLD_DEFAULT, "Py_Initialize");
	if (is_cpython_loaded) {
		uwsgi_log("!!! Loading both PyPy and CPython in the same process IS PURE EVIL AND IT IS NOT SUPPORTED !!!\n");
		exit(1);
	}

	if (dlsym(RTLD_DEFAULT, "rpython_startup_code")) {
		uwsgi_log("PyPy runtime detected, skipping libpypy-c loading\n");
		goto ready;
	}
	else if (upypy.lib) {
		upypy.handler = dlopen(upypy.lib, RTLD_NOW | RTLD_GLOBAL);
	}
	else {
		if (upypy.home) {
#ifdef __CYGWIN__
                        char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.dll");
#elif defined(__APPLE__)
                        char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.dylib");
#else
                        char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.so");
#endif
			if (uwsgi_file_exists(libpath)) {
				upypy.handler = dlopen(libpath, RTLD_NOW | RTLD_GLOBAL);
			}
			free(libpath);
		}
		// fallback to standard library search path
		if (!upypy.handler) {
#ifdef __CYGWIN__
			upypy.handler = dlopen("libpypy-c.dll", RTLD_NOW | RTLD_GLOBAL);
#elif defined(__APPLE__)
			upypy.handler = dlopen("libpypy-c.dylib", RTLD_NOW | RTLD_GLOBAL);
#else
			upypy.handler = dlopen("libpypy-c.so", RTLD_NOW | RTLD_GLOBAL);
#endif
		}
	}

	if (!upypy.handler) {
		uwsgi_log("unable to load pypy library: %s\n", dlerror());
		exit(1);
	}

	u_rpython_startup_code = dlsym(upypy.handler, "rpython_startup_code");
	if (!u_rpython_startup_code) {
		uwsgi_log("unable to find rpython_startup_code() symbol\n");
		exit(1);
	}

	u_pypy_setup_home = dlsym(upypy.handler, "pypy_setup_home");
	if (!u_pypy_setup_home) {
		uwsgi_log("unable to find pypy_setup_home() symbol\n");
		exit(1);
	}

	u_pypy_init_threads = dlsym(upypy.handler, "pypy_init_threads");
        if (!u_pypy_init_threads) {
                uwsgi_log("!!! WARNING your libpypy-c does not export pypy_init_threads, multithreading will not work !!!\n");
        }
	
	u_rpython_startup_code();

	if (!upypy.home) {
		upypy.home = getenv("PYPY_HOME");
		if (!upypy.home) {
			uwsgi_log("you have to specify a pypy home with --pypy-home\n");
			exit(1);
		}
	}

	if (u_pypy_setup_home(upypy.home, 0)) {
		char *retry = uwsgi_concat2(upypy.home, "/lib_pypy");
		if (uwsgi_is_dir(retry)) {
			// this time we use debug
			if (!u_pypy_setup_home(retry, 1)) {
				free(retry);
				goto ready;
			}
		}
                uwsgi_log("unable to set pypy home to \"%s\"\n", upypy.home);
		exit(1);
        }

ready:
	u_pypy_execute_source = dlsym(upypy.handler, "pypy_execute_source");
	if (!u_pypy_execute_source) {
		uwsgi_log("unable to find pypy_execute_source() symbol\n");
		exit(1);
	}

	u_pypy_thread_attach = dlsym(upypy.handler, "pypy_thread_attach");
        if (!u_pypy_thread_attach) {
                uwsgi_log("!!! WARNING your libpypy-c does not export pypy_thread_attach, multithreading will not work !!!\n");
        }

	if (upypy.setup) {
		buffer = uwsgi_open_and_read(upypy.setup, &rlen, 1, NULL);
	}
	else {
		char *start = dlsym(RTLD_DEFAULT, "uwsgi_pypy_setup_start");
		if (!start) {
			start = dlsym(RTLD_DEFAULT, "_uwsgi_pypy_setup_start");
		}
		char *end = dlsym(RTLD_DEFAULT, "uwsgi_pypy_setup_end");
		if (!end) {
			end = dlsym(RTLD_DEFAULT, "_uwsgi_pypy_setup_end");
		}
		if (start && end) {
			buffer = uwsgi_concat2n(start, end-start, "", 0);
		}
	}

	if (!buffer) {
		uwsgi_log("you have to load a pypy setup file with --pypy-setup\n");
		exit(1);
	}
	if (u_pypy_execute_source(buffer)) {
		exit(1);
	}
	free(buffer);

	// add items to the pythonpath
	struct uwsgi_string_list *usl = upypy.pp;
	while(usl) {
		if (uwsgi_pypy_hook_pythonpath) {
			uwsgi_pypy_hook_pythonpath(usl->value);
		}
		usl = usl->next;
	}

	return 0;
}
Exemple #5
0
void uwsgi_subscribe2(char *arg, uint8_t cmd) {

	char *s2_server = NULL;
	char *s2_key = NULL;
	char *s2_socket = NULL;
	char *s2_addr = NULL;
	char *s2_weight = NULL;
	char *s2_sign = NULL;
	char *s2_modifier1 = NULL;
	char *s2_modifier2 = NULL;
	char *s2_check = NULL;

	if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=',
                        "server", &s2_server,
                        "key", &s2_key,
                        "socket", &s2_socket,
                        "addr", &s2_addr,
                        "weight", &s2_weight,
                        "modifier1", &s2_modifier1,
                        "modifier2", &s2_modifier2,
                        "sign", &s2_sign,
                        "check", &s2_check,
		NULL)) {
		return;
	}

	if (!s2_server || !s2_key) goto end;

	if (s2_check) {
		if (uwsgi_file_exists(s2_check)) goto end;
	}

	if (s2_weight) {
		uwsgi.weight = atoi(s2_weight);
	}

	if (s2_socket) {
		struct uwsgi_socket *us = uwsgi_get_socket_by_num(atoi(s2_socket));
		if (us) {
			if (s2_addr) {
				free(s2_addr);
			}
			s2_addr = uwsgi_str(us->name);
		}
	}

	uint8_t modifier1 = 0;
	uint8_t modifier2 = 0;

	if (s2_modifier1) {
		modifier1 = atoi(s2_modifier1);
	}

	if (s2_modifier2) {
		modifier2 = atoi(s2_modifier2);
	}

	uwsgi_send_subscription(s2_server, s2_key, strlen(s2_key), modifier1, modifier2, cmd, s2_addr, s2_sign);
end:
	if (s2_server) free(s2_server);
	if (s2_key) free(s2_key);
	if (s2_socket) free(s2_socket);
	if (s2_addr) free(s2_addr);
	if (s2_weight) free(s2_weight);
	if (s2_modifier1) free(s2_modifier1);
	if (s2_modifier2) free(s2_modifier2);
	if (s2_sign) free(s2_sign);
	if (s2_check) free(s2_check);
}
Exemple #6
0
void uwsgi_build_plugin(char *directory) {

	if (!uwsgi_file_exists(UWSGI_BUILD_DIR)) {
		if (mkdir(UWSGI_BUILD_DIR, S_IRWXU) < 0) {
        		uwsgi_error("uwsgi_build_plugin()/mkdir() " UWSGI_BUILD_DIR "/");
			_exit(1);
		}
	}

	char *dot_h = uwsgi_get_dot_h();
	if (!dot_h) {
		uwsgi_log("unable to generate uwsgi.h");
		_exit(1);
	}

	if (strlen(dot_h) == 0) {
		free(dot_h);
		uwsgi_log("invalid uwsgi.h");
		_exit(1);
	}

	int dot_h_fd = open(UWSGI_BUILD_DIR "/uwsgi.h", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
	if (dot_h_fd < 0) {
		uwsgi_error_open(UWSGI_BUILD_DIR "/uwsgi.h");
		free(dot_h);
		_exit(1);
	}

	ssize_t dot_h_len = (ssize_t) strlen(dot_h);
	if (write(dot_h_fd, dot_h, dot_h_len) != dot_h_len) {
		uwsgi_error("uwsgi_build_plugin()/write()");
		_exit(1);
	}

	char *config_py = uwsgi_get_config_py();
        if (!config_py) {
                uwsgi_log("unable to generate uwsgiconfig.py");
                _exit(1);
        }

        if (strlen(config_py) == 0) {
                uwsgi_log("invalid uwsgiconfig.py");
                _exit(1);
        }

        int config_py_fd = open(UWSGI_BUILD_DIR "/uwsgiconfig.py", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
        if (config_py_fd < 0) {
                uwsgi_error_open(UWSGI_BUILD_DIR "/uwsgiconfig.py");
                _exit(1);
        }

        ssize_t config_py_len = (ssize_t) strlen(config_py);
        if (write(config_py_fd, config_py, config_py_len) != config_py_len) {
                uwsgi_error("uwsgi_build_plugin()/write()");
                _exit(1);
        }

	char *cflags = uwsgi_get_cflags();
	if (!cflags) {
		uwsgi_log("unable to find cflags\n");
		_exit(1);
	}
	if (strlen(cflags) == 0) {
		uwsgi_log("invalid cflags\n");
		_exit(1);
	}

	if (setenv("UWSGI_PLUGINS_BUILDER_CFLAGS", cflags, 1)) {
		uwsgi_error("uwsgi_build_plugin()/setenv()");
		_exit(1);
	}
	
	// now run the python script
	char *argv[6];

	argv[0] = getenv("PYTHON");
	if (!argv[0]) argv[0] = "python";

	argv[1] = UWSGI_BUILD_DIR "/uwsgiconfig.py";
	argv[2] = "--extra-plugin";
	char *space = strchr(directory, ' ');
	if (space) {
		*space = 0;
		argv[3] = directory;
                argv[4] = space+1;
		argv[5] = NULL;
	}
	else {
		argv[3] = directory;
		argv[4] = NULL;
	}

	execvp(argv[0], argv);
	// never here...	
	_exit(1);
}