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 if (!in) { 35 fprintf(stderr, 36 "uhttpd: OOM while adding CGI interpreter (%s -> %s)\n", 37 ext, path); 38 return; 39 } 40 41 in->ext = strcpy(new_ext, ext); 42 in->path = strcpy(new_path, path); 43 list_add_tail(&in->list, &interpreters); 44 } 45 46 static void cgi_main(struct client *cl, struct path_info *pi, char *url) 47 { 48 const struct interpreter *ip = pi->ip; 49 struct env_var *var; 50 51 clearenv(); 52 setenv("PATH", conf.cgi_path, 1); 53 54 for (var = uh_get_process_vars(cl, pi); var->name; var++) { 55 if (!var->value) 56 continue; 57 58 setenv(var->name, var->value, 1); 59 } 60 61 if (!chdir(pi->root)) { 62 if (ip) 63 execl(ip->path, ip->path, pi->phys, NULL); 64 else 65 execl(pi->phys, pi->phys, NULL); 66 } 67 68 printf("Status: 500 Internal Server Error\r\n\r\n" 69 "Unable to launch the requested CGI program:\n" 70 " %s: %s\n", ip ? ip->path : pi->phys, strerror(errno)); 71 } 72 73 static void cgi_handle_request(struct client *cl, char *url, struct path_info *pi) 74 { 75 unsigned int mode = S_IFREG | S_IXOTH; 76 char *escaped_url; 77 78 if (!pi->ip && !((pi->stat.st_mode & mode) == mode)) { 79 escaped_url = uh_htmlescape(url); 80 81 uh_client_error(cl, 403, "Forbidden", 82 "You don't have permission to access %s on this server.", 83 escaped_url ? escaped_url : "the url"); 84 85 if (escaped_url) 86 free(escaped_url); 87 88 return; 89 } 90 91 if (!uh_create_process(cl, pi, url, cgi_main)) { 92 uh_client_error(cl, 500, "Internal Server Error", 93 "Failed to create CGI process: %s", strerror(errno)); 94 return; 95 } 96 97 return; 98 } 99 100 static bool check_cgi_path(struct path_info *pi, const char *url) 101 { 102 struct interpreter *ip; 103 const char *path = pi->phys; 104 int path_len = strlen(path); 105 106 list_for_each_entry(ip, &interpreters, list) { 107 int len = strlen(ip->ext); 108 109 if (len >= path_len) 110 continue; 111 112 if (strcmp(path + path_len - len, ip->ext) != 0) 113 continue; 114 115 pi->ip = ip; 116 return true; 117 } 118 119 pi->ip = NULL; 120 121 if (conf.cgi_docroot_path) 122 return uh_path_match(conf.cgi_docroot_path, pi->phys); 123 124 return false; 125 } 126 127 struct dispatch_handler cgi_dispatch = { 128 .script = true, 129 .check_path = check_cgi_path, 130 .handle_request = cgi_handle_request, 131 }; 132
This page was automatically generated by LXR 0.3.1. • OpenWrt