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; }
static int uwsgi_routing_func_rewrite(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { char *tmp_qs = NULL; char **subject = (char **) (((char *)(wsgi_req))+ur->subject); uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len); if (!ub) return UWSGI_ROUTE_BREAK; uint16_t path_info_len = ub->pos; uint16_t query_string_len = 0; char *query_string = memchr(ub->buf, '?', ub->pos); if (query_string) { path_info_len = query_string - ub->buf; query_string++; query_string_len = ub->pos - (path_info_len + 1); if (wsgi_req->query_string_len > 0) { tmp_qs = uwsgi_concat4n(query_string, query_string_len, "&", 1, wsgi_req->query_string, wsgi_req->query_string_len, "", 0); query_string = tmp_qs; query_string_len = strlen(query_string); } } // over engineering, could be required in the future... else { if (wsgi_req->query_string_len > 0) { query_string = wsgi_req->query_string; query_string_len = wsgi_req->query_string_len; } else { query_string = ""; } } char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, ub->buf, path_info_len); if (!ptr) goto clear; // set new path_info wsgi_req->path_info = ptr; wsgi_req->path_info_len = path_info_len; ptr = uwsgi_req_append(wsgi_req, "QUERY_STRING", 12, query_string, query_string_len); if (!ptr) goto clear; // set new query_string wsgi_req->query_string = ptr; wsgi_req->query_string_len = query_string_len; uwsgi_buffer_destroy(ub); if (tmp_qs) free(tmp_qs); if (ur->custom) return UWSGI_ROUTE_CONTINUE; return UWSGI_ROUTE_NEXT; clear: uwsgi_buffer_destroy(ub); if (tmp_qs) free(tmp_qs); return UWSGI_ROUTE_BREAK; }
int uwsgi_routing_func_rewrite(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { char *tmp_qs = NULL; char **subject = (char **) (((char *)(wsgi_req))+ur->subject); uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); char *path_info = uwsgi_regexp_apply_ovec(*subject, *subject_len, ur->data, ur->data_len, ur->ovector, ur->ovn); uint16_t path_info_len = strlen(path_info); uint16_t query_string_len = 0; char *query_string = strchr(path_info, '?'); if (query_string) { path_info_len = query_string - path_info; query_string++; query_string_len = strlen(query_string); if (wsgi_req->query_string_len > 0) { tmp_qs = uwsgi_concat4n(query_string, query_string_len, "&", 1, wsgi_req->query_string, wsgi_req->query_string_len, "", 0); query_string = tmp_qs; query_string_len = strlen(query_string); } } // over engineering, could be required in the future... else { if (wsgi_req->query_string_len > 0) { query_string = wsgi_req->query_string; query_string_len = wsgi_req->query_string_len; } else { query_string = ""; } } char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, path_info, path_info_len); if (!ptr) goto clear; // set new path_info wsgi_req->path_info = ptr; wsgi_req->path_info_len = path_info_len; ptr = uwsgi_req_append(wsgi_req, "QUERY_STRING", 12, query_string, query_string_len); if (!ptr) goto clear; // set new query_string wsgi_req->query_string = ptr; wsgi_req->query_string_len = query_string_len; free(path_info); if (tmp_qs) free(tmp_qs); if (ur->custom) return UWSGI_ROUTE_CONTINUE; return UWSGI_ROUTE_NEXT; clear: free(path_info); if (tmp_qs) free(tmp_qs); return UWSGI_ROUTE_BREAK; }
char *uwsgi_sanitize_cert_filename(char *base, char *key, uint16_t keylen) { uint16_t i; char *filename = uwsgi_concat4n(base, strlen(base), "/", 1, key, keylen, ".pem\0", 5); for (i = strlen(base) + 1; i < (strlen(base) + 1) + keylen; i++) { if (filename[i] >= '0' && filename[i] <= '9') continue; if (filename[i] >= 'A' && filename[i] <= 'Z') continue; if (filename[i] >= 'a' && filename[i] <= 'z') continue; if (filename[i] == '.') continue; if (filename[i] == '-') continue; if (filename[i] == '_') continue; filename[i] = '_'; } return filename; }
char *uwsgi_upload_progress_create(struct wsgi_request *wsgi_req, int *fd) { const char *x_progress_id = "X-Progress-ID="; char *xpi_ptr = (char *) x_progress_id; uint16_t i; char *upload_progress_filename = NULL; if (wsgi_req->uri_len <= 51) return NULL; for (i = 0; i < wsgi_req->uri_len; i++) { if (wsgi_req->uri[i] == xpi_ptr[0]) { if (xpi_ptr[0] == '=') { if (wsgi_req->uri + i + 36 <= wsgi_req->uri + wsgi_req->uri_len) { upload_progress_filename = wsgi_req->uri + i + 1; } break; } xpi_ptr++; } else { xpi_ptr = (char *) x_progress_id; } } // now check for valid uuid (from spec available at http://en.wikipedia.org/wiki/Universally_unique_identifier) if (!upload_progress_filename) return NULL; uwsgi_log("upload progress uuid = %.*s\n", 36, upload_progress_filename); if (!check_hex(upload_progress_filename, 8)) return NULL; if (upload_progress_filename[8] != '-') return NULL; if (!check_hex(upload_progress_filename + 9, 4)) return NULL; if (upload_progress_filename[13] != '-') return NULL; if (!check_hex(upload_progress_filename + 14, 4)) return NULL; if (upload_progress_filename[18] != '-') return NULL; if (!check_hex(upload_progress_filename + 19, 4)) return NULL; if (upload_progress_filename[23] != '-') return NULL; if (!check_hex(upload_progress_filename + 24, 12)) return NULL; upload_progress_filename = uwsgi_concat4n(uwsgi.upload_progress, strlen(uwsgi.upload_progress), "/", 1, upload_progress_filename, 36, ".js", 3); // here we use O_EXCL to avoid eventual application bug in uuid generation/using *fd = open(upload_progress_filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP); if (*fd < 0) { uwsgi_error_open(upload_progress_filename); free(upload_progress_filename); return NULL; } return upload_progress_filename; }
static char *emperor_check_on_demand_socket(char *filename) { size_t len = 0; if (uwsgi.emperor_on_demand_extension) { char *tmp = uwsgi_concat2(filename, uwsgi.emperor_on_demand_extension); int fd = open(tmp, O_RDONLY); free(tmp); if (fd < 0) return NULL; char *ret = uwsgi_read_fd(fd, &len, 1); close(fd); // change the first non prinabel character to 0 size_t i; for(i=0;i<len;i++) { if (ret[i] < 32) { ret[i] = 0; break; } } if (ret[0] == 0) { free(ret); return NULL; } return ret; } else if (uwsgi.emperor_on_demand_directory) { // we need to build the socket path automagically char *start_of_vassal_name = uwsgi_get_last_char(filename, '/'); if (!start_of_vassal_name) { start_of_vassal_name = filename; } else { start_of_vassal_name++; } char *last_dot = uwsgi_get_last_char(filename, '.'); if (!last_dot) return NULL; return uwsgi_concat4n(uwsgi.emperor_on_demand_directory, strlen(uwsgi.emperor_on_demand_directory), "/", 1, start_of_vassal_name, last_dot - start_of_vassal_name, ".socket", 7); } else if (uwsgi.emperor_on_demand_exec) { int cpipe[2]; if (pipe(cpipe)) { uwsgi_error("emperor_check_on_demand_socket()pipe()"); return NULL; } char *cmd = uwsgi_concat4(uwsgi.emperor_on_demand_exec, " \"", filename, "\""); int r = uwsgi_run_command(cmd, NULL, cpipe[1]); free(cmd); if (r < 0) { close(cpipe[0]); close(cpipe[1]); return NULL; } char *ret = uwsgi_read_fd(cpipe[0], &len, 1); close(cpipe[0]); close(cpipe[1]); // change the first non prinabel character to 0 size_t i; for(i=0;i<len;i++) { if (ret[i] < 32) { ret[i] = 0; break; } } if (ret[0] == 0) { free(ret); return NULL; } return ret; } return NULL; }
int uwsgi_amqp_consume_queue(int fd, char *vhost, char *username, char *password, char *queue, char *exchange, char *exchange_type) { char *auth = uwsgi_concat4n("\0",1, username, strlen(username), "\0",1, password, strlen(password)); if (send(fd, AMQP_CONNECTION_HEADER, 8, 0) < 0) { uwsgi_error("send()"); return -1; } if (amqp_wait_connection_start(fd) < 0) { uwsgi_log("AMQP error waiting for Connection.start\n"); return -1; } uwsgi_log("sending Connection.start-ok\n"); if (amqp_send_connection_start_ok(fd, "PLAIN", auth, strlen(username)+strlen(password)+2, "en_US") < 0) { free(auth); uwsgi_log("AMQP error sending Connection.start-ok\n"); return -1; } free(auth); if (amqp_wait_connection_tune(fd) < 0) { uwsgi_log("AMQP error waiting for Connection.tune\n"); return -1; } uwsgi_log("sending Connection.tune-ok\n"); if (amqp_send_connection_tune_ok(fd, 0, 0xffff, 0) < 0) { uwsgi_log("AMQP error sending Connection.tune-ok\n"); return -1; } uwsgi_log("sending Connection.open\n"); if (amqp_send_connection_open(fd, vhost) < 0) { uwsgi_log("AMQP error sending Connection.open\n"); return -1; } if (amqp_wait_connection_open_ok(fd) < 0) { uwsgi_log("AMQP error waiting for Connection.open-ok\n"); return -1; } uwsgi_log("sending Channel.open\n"); if (amqp_send_channel_open(fd, 1) < 0) { uwsgi_log("AMQP error sending Channel.open\n"); return -1; } if (amqp_wait_channel_open_ok(fd) < 0) { uwsgi_log("AMQP error waiting for Channel.open-ok\n"); return -1; } queue = amqp_get_queue(fd, queue); if (!queue) { uwsgi_log("AMQP error sending Queue.declare\n"); return -1; } if (exchange) { if (amqp_send_exchange_declare(fd, exchange, exchange_type) < 0) { uwsgi_log("AMQP error sending Exchange.declare\n"); free(queue); return -1; } if (amqp_wait_exchange_declare_ok(fd) < 0) { uwsgi_log("AMQP error waiting for Exchange.declare-ok\n"); free(queue); return -1; } if (amqp_send_queue_bind(fd, queue, exchange) < 0) { uwsgi_log("AMQP error sending Queue.bind\n"); free(queue); return -1; } if (amqp_wait_queue_bind_ok(fd) < 0) { uwsgi_log("AMQP error waiting for Queue.bind-ok\n"); free(queue); return -1; } } if (amqp_send_queue_consume(fd, queue) < 0) { uwsgi_log("AMQP error sending Basic.consume\n"); free(queue); return -1; } if (amqp_wait_basic_consume_ok(fd) < 0) { uwsgi_log("AMQP error waiting for Basic.consume-ok\n"); free(queue); return -1; } free(queue); uwsgi_log("AMQP subscription done, waiting for events...\n"); return 0; }