1 /* 2 * uhttpd - Tiny single-threaded httpd 3 * 4 * Copyright (C) 2010-2013 Jo-Philipp Wich <xm@subsignal.org> 5 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org> 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #define _GNU_SOURCE 21 #include <libubox/blobmsg.h> 22 #include "uhttpd.h" 23 24 static LIST_HEAD(interpreters); 25 26 void uh_interpreter_add(const char *ext, const char *path) 27 { 28 struct interpreter *in; 29 char *new_ext, *new_path; 30 31 in = calloc_a(sizeof(*in), 32 &new_ext, strlen(ext) + 1, 33 &new_path, strlen(path) + 1); 34 35 in->ext = strcpy(new_ext, ext); 36 in->path = strcpy(new_path, path); 37 list_add_tail(&in->list, &interpreters); 38 } 39 40 static void cgi_main(struct client *cl, struct path_info *pi, char *url) 41 { 42 const struct interpreter *ip = pi->ip; 43 struct env_var *var; 44 45 clearenv(); 46 setenv("PATH", conf.cgi_path, 1); 47 48 for (var = uh_get_process_vars(cl, pi); var->name; var++) { 49 if (!var->value) 50 continue; 51 52 setenv(var->name, var->value, 1); 53 } 54 55 if (!chdir(pi->root)) { 56 if (ip) 57 execl(ip->path, ip->path, pi->phys, NULL); 58 else 59 execl(pi->phys, pi->phys, NULL); 60 } 61 62 printf("Status: 500 Internal Server Error\r\n\r\n" 63 "Unable to launch the requested CGI program:\n" 64 " %s: %s\n", ip ? ip->path : pi->phys, strerror(errno)); 65 } 66 67 static void cgi_handle_request(struct client *cl, char *url, struct path_info *pi) 68 { 69 unsigned int mode = S_IFREG | S_IXOTH; 70 char *escaped_url; 71 72 if (!pi->ip && !((pi->stat.st_mode & mode) == mode)) { 73 escaped_url = uh_htmlescape(url); 74 75 uh_client_error(cl, 403, "Forbidden", 76 "You don't have permission to access %s on this server.", 77 escaped_url ? escaped_url : "the url"); 78 79 if (escaped_url) 80 free(escaped_url); 81 82 return; 83 } 84 85 if (!uh_create_process(cl, pi, url, cgi_main)) { 86 uh_client_error(cl, 500, "Internal Server Error", 87 "Failed to create CGI process: %s", strerror(errno)); 88 return; 89 } 90 91 return; 92 } 93 94 static bool check_cgi_path(struct path_info *pi, const char *url) 95 { 96 struct interpreter *ip; 97 const char *path = pi->phys; 98 int path_len = strlen(path); 99 100 list_for_each_entry(ip, &interpreters, list) { 101 int len = strlen(ip->ext); 102 103 if (len >= path_len) 104 continue; 105 106 if (strcmp(path + path_len - len, ip->ext) != 0) 107 continue; 108 109 pi->ip = ip; 110 return true; 111 } 112 113 pi->ip = NULL; 114 115 if (conf.cgi_docroot_path) 116 return uh_path_match(conf.cgi_docroot_path, pi->phys); 117 118 return false; 119 } 120 121 struct dispatch_handler cgi_dispatch = { 122 .script = true, 123 .check_path = check_cgi_path, 124 .handle_request = cgi_handle_request, 125 }; 126
This page was automatically generated by LXR 0.3.1. • OpenWrt