mirror of
				https://github.com/lxsang/ant-http
				synced 2025-10-31 02:15:45 +01:00 
			
		
		
		
	Allow sandboxing plugin instances
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				gitea-sync/ant-http/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	gitea-sync/ant-http/pipeline/head This commit looks good
				
			This commit is contained in:
		| @@ -532,8 +532,7 @@ void *resolve_request(void *data) | |||||||
|     char *rqp = NULL; |     char *rqp = NULL; | ||||||
|     char *oldrqp = NULL; |     char *oldrqp = NULL; | ||||||
|     rq->client->state = ANTD_CLIENT_RESOLVE_REQUEST; |     rq->client->state = ANTD_CLIENT_RESOLVE_REQUEST; | ||||||
|     htdocs(rq, path); |     snprintf(path, sizeof(path), "%s/%s", (char *)dvalue(rq->request, "SERVER_WWW_ROOT"), url); | ||||||
|     strcat(path, url); |  | ||||||
|     LOG("URL is : %s", url); |     LOG("URL is : %s", url); | ||||||
|     LOG("Resource Path is : %s", path); |     LOG("Resource Path is : %s", path); | ||||||
|     // if (path[strlen(path) - 1] == '/') |     // if (path[strlen(path) - 1] == '/') | ||||||
| @@ -567,8 +566,7 @@ void *resolve_request(void *data) | |||||||
|                 { |                 { | ||||||
|                     newurl = __s("%s/index.%s", url, it->key); |                     newurl = __s("%s/index.%s", url, it->key); | ||||||
|                     memset(path, 0, sizeof(path)); |                     memset(path, 0, sizeof(path)); | ||||||
|                     htdocs(rq, path); |                     snprintf(path, sizeof(path), "%s/%s", (char *)dvalue(rq->request, "SERVER_WWW_ROOT"), newurl); | ||||||
|                     strcat(path, newurl); |  | ||||||
|                     if (stat(path, &st) != 0) |                     if (stat(path, &st) != 0) | ||||||
|                     { |                     { | ||||||
|                         free(newurl); |                         free(newurl); | ||||||
| @@ -1768,19 +1766,6 @@ dictionary_t mimes_list() | |||||||
|     return server_config.mimes; |     return server_config.mimes; | ||||||
| } | } | ||||||
|  |  | ||||||
| void dbdir(char **dest) |  | ||||||
| { |  | ||||||
|     *dest = server_config.db_path; |  | ||||||
| } |  | ||||||
| void tmpdir(char **dest) |  | ||||||
| { |  | ||||||
|     *dest = server_config.tmpdir; |  | ||||||
| } |  | ||||||
| void plugindir(char **dest) |  | ||||||
| { |  | ||||||
|     *dest =server_config.plugins_dir; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #ifdef USE_ZLIB | #ifdef USE_ZLIB | ||||||
| int compressable(char *ctype) | int compressable(char *ctype) | ||||||
| { | { | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								lib/handle.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								lib/handle.c
									
									
									
									
									
								
							| @@ -106,28 +106,6 @@ int compressable(char *ctype) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| void htdocs(antd_request_t *rq, char *dest) |  | ||||||
| { |  | ||||||
|     //dictionary_t xheader = (dictionary_t)dvalue(rq->request, "REQUEST_HEADER"); |  | ||||||
|     char *www = (char *)dvalue(rq->request, "SERVER_WWW_ROOT"); |  | ||||||
|     if (www) |  | ||||||
|     { |  | ||||||
|         strcpy(dest, www); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| void dbdir(char **dest) |  | ||||||
| { |  | ||||||
|     UNUSED(dest); |  | ||||||
| } |  | ||||||
| void tmpdir(char **dest) |  | ||||||
| { |  | ||||||
|     UNUSED(dest); |  | ||||||
| } |  | ||||||
| void plugindir(char **dest) |  | ||||||
| { |  | ||||||
|     UNUSED(dest); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const char *get_status_str(int stat) | const char *get_status_str(int stat) | ||||||
| { | { | ||||||
|     switch (stat) |     switch (stat) | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								lib/handle.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								lib/handle.h
									
									
									
									
									
								
							| @@ -30,6 +30,8 @@ | |||||||
|  |  | ||||||
| #define ANTD_PLUGIN_READY 0x0 | #define ANTD_PLUGIN_READY 0x0 | ||||||
| #define ANTD_PLUGIN_PANNIC 0x1 | #define ANTD_PLUGIN_PANNIC 0x1 | ||||||
|  | #define ANTD_PLUGIN_INIT 0x2 | ||||||
|  | #define MAX_PATH_LEN 256 | ||||||
|  |  | ||||||
| typedef enum | typedef enum | ||||||
| { | { | ||||||
| @@ -108,26 +110,22 @@ typedef struct | |||||||
|  |  | ||||||
| typedef struct | typedef struct | ||||||
| { | { | ||||||
|     char name[128]; |     char name[MAX_PATH_LEN]; | ||||||
|     char* dbpath; |     char dbpath[MAX_PATH_LEN]; | ||||||
|     char* tmpdir; |     char tmpdir[MAX_PATH_LEN]; | ||||||
|     char* pdir; |     char pdir[MAX_PATH_LEN]; | ||||||
|     dictionary_t config; |     dictionary_t config; | ||||||
|     int raw_body; |     int raw_body; | ||||||
|     int status; |     int status; | ||||||
| } plugin_header_t; | } plugin_header_t; | ||||||
|  |  | ||||||
| int __attribute__((weak)) require_plugin(const char *); |  | ||||||
| void __attribute__((weak)) htdocs(antd_request_t *rq, char *dest); |  | ||||||
| void __attribute__((weak)) dbdir(char **dest); |  | ||||||
| void __attribute__((weak)) tmpdir(char **dest); |  | ||||||
| void __attribute__((weak)) plugindir(char **dest); |  | ||||||
|  |  | ||||||
| int __attribute__((weak)) compressable(char *ctype); |  | ||||||
|  |  | ||||||
| void set_nonblock(int socket); | void set_nonblock(int socket); | ||||||
| //void set_block(int socket); | //void set_block(int socket); | ||||||
|  |  | ||||||
|  | int __attribute__((weak)) compressable(char *ctype); | ||||||
|  |  | ||||||
| void antd_send_header(void *, antd_response_header_t *); | void antd_send_header(void *, antd_response_header_t *); | ||||||
| const char *get_status_str(int stat); | const char *get_status_str(int stat); | ||||||
| int __t(void *, const char *, ...); | int __t(void *, const char *, ...); | ||||||
|   | |||||||
| @@ -40,13 +40,8 @@ STATIC PART, should be included in any plugin | |||||||
|  |  | ||||||
| static plugin_header_t __plugin__; | static plugin_header_t __plugin__; | ||||||
| // private function | // private function | ||||||
| void __init_plugin__(const char* pl, dictionary_t* conf){ | void __init_plugin__(plugin_header_t* pl, dictionary_t* conf){ | ||||||
| 	strcpy(__plugin__.name,pl); | 	(void) memcpy(&__plugin__, pl, sizeof(plugin_header_t)); | ||||||
| 	dbdir(&__plugin__.dbpath); |  | ||||||
| 	plugindir(&__plugin__.pdir); |  | ||||||
| 	tmpdir(&__plugin__.tmpdir);  |  | ||||||
| 	__plugin__.config = conf; |  | ||||||
| 	__plugin__.raw_body = 0; |  | ||||||
| 	__plugin__.status = ANTD_PLUGIN_READY; | 	__plugin__.status = ANTD_PLUGIN_READY; | ||||||
| 	init(); | 	init(); | ||||||
| };  | };  | ||||||
|   | |||||||
							
								
								
									
										121
									
								
								plugin_manager.c
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								plugin_manager.c
									
									
									
									
									
								
							| @@ -1,12 +1,15 @@ | |||||||
| #include <dlfcn.h> | #include <dlfcn.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include <sys/sendfile.h> | ||||||
|  | #include <unistd.h> | ||||||
| #include "plugin_manager.h" | #include "plugin_manager.h" | ||||||
| #include "lib/utils.h" | #include "lib/utils.h" | ||||||
| #include "lib/handle.h" | #include "lib/handle.h" | ||||||
| #include "http_server.h" | #include "http_server.h" | ||||||
|  |  | ||||||
| static void unload_plugin_by_name(const char *); | static void unload_plugin_by_name(const char *); | ||||||
| static void * plugin_from_file(char* name, dictionary_t conf); | static void *plugin_from_file(char *name, char *path, dictionary_t conf); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Plugin table to store the loaded plugin |  * Plugin table to store the loaded plugin | ||||||
| @@ -27,12 +30,6 @@ struct plugin_entry *plugin_lookup(char *s) | |||||||
|     return NULL;       /* not found */ |     return NULL;       /* not found */ | ||||||
| } | } | ||||||
|  |  | ||||||
| int require_plugin(const char* name) |  | ||||||
| { |  | ||||||
| 	struct plugin_entry* ptr = plugin_load((char*)name, NULL); |  | ||||||
| 	return ptr != NULL; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Load a plugin to the plugin table |  * Load a plugin to the plugin table | ||||||
|  * Only load when not available in the plugin table |  * Only load when not available in the plugin table | ||||||
| @@ -40,41 +37,88 @@ int require_plugin(const char* name) | |||||||
|  * @param config: plugin configuration |  * @param config: plugin configuration | ||||||
|  * @return      pointer to the loaded plugin |  * @return      pointer to the loaded plugin | ||||||
|  */ |  */ | ||||||
| struct plugin_entry *plugin_load(char *name, dictionary_t config) | struct plugin_entry *plugin_load(char *name, dictionary_t pconf) | ||||||
| { | { | ||||||
|     char *pname = NULL; |     char *pname = NULL; | ||||||
|  |     char path[BUFFLEN]; | ||||||
|     struct plugin_entry *np; |     struct plugin_entry *np; | ||||||
|     unsigned hashval; |     unsigned hashval; | ||||||
|     plugin_header_t *(*metafn)(); |     plugin_header_t *(*metafn)(); | ||||||
|     plugin_header_t *meta = NULL; |     plugin_header_t *meta = NULL; | ||||||
|  |     config_t *sconf = config(); | ||||||
|  |     int fromfd, tofd; | ||||||
|     char *error; |     char *error; | ||||||
| 	if(config) |     struct stat st; | ||||||
|  |     int is_tmp = 0; | ||||||
|  |     if (pconf) | ||||||
|     { |     { | ||||||
| 		pname = dvalue(config, "name"); |         pname = dvalue(pconf, "name"); | ||||||
|     } |     } | ||||||
| 	if(!pname) |     if ((np = plugin_lookup(name)) == NULL) | ||||||
| 	{ |     { /* not found */ | ||||||
| 		pname = name; |         LOG("Loading plugin: %s...", name); | ||||||
| 	} |  | ||||||
|     if ((np = plugin_lookup(name)) == NULL) { /* not found */ |  | ||||||
| 		LOG("Loading plugin: %s -> %s", name, pname); |  | ||||||
|         np = (struct plugin_entry *)malloc(sizeof(*np)); |         np = (struct plugin_entry *)malloc(sizeof(*np)); | ||||||
|         if (np == NULL || name == NULL) |         if (np == NULL || name == NULL) | ||||||
|         { |         { | ||||||
| 			if(np) free(np); |             if (np) | ||||||
|  |                 free(np); | ||||||
|             return NULL; |             return NULL; | ||||||
|         } |         } | ||||||
| 		np->pname = strdup(name); |  | ||||||
|         if ((np->handle = plugin_from_file(pname,config)) == NULL) |         (void)snprintf(path, sizeof(path), "%s/%s%s", sconf->plugins_dir, name, sconf->plugins_ext); | ||||||
|  |         if (pname && strcmp(name, pname) != 0) | ||||||
|         { |         { | ||||||
| 			if(np->pname) free(np->pname); |             // copy plugin file to tmpdir | ||||||
| 			if(np) free(np); |             (void)snprintf(path, sizeof(path), "%s/%s%s", sconf->plugins_dir, pname, sconf->plugins_ext); | ||||||
|  |             LOG("Original plugin file: %s", path); | ||||||
|  |             if ((fromfd = open(path, O_RDONLY)) < 0) | ||||||
|  |             { | ||||||
|  |                 ERROR("Unable to open file for reading %s: %s", path, strerror(errno)); | ||||||
|  |                 return NULL; | ||||||
|  |             } | ||||||
|  |             if (stat(path, &st) != 0) | ||||||
|  |             { | ||||||
|  |                 close(fromfd); | ||||||
|  |                 ERROR("Unable to get file stat %s: %s", path, strerror(errno)); | ||||||
|  |                 return NULL; | ||||||
|  |             } | ||||||
|  |             (void)snprintf(path, sizeof(path), "%s/%s%s", sconf->tmpdir, name, sconf->plugins_ext); | ||||||
|  |             LOG("TMP plugin file: %s", path); | ||||||
|  |             if ((tofd = open(path, O_WRONLY | O_CREAT, 0600)) < 0) | ||||||
|  |             { | ||||||
|  |                 close(fromfd); | ||||||
|  |                 ERROR("Unable open file for reading %s: %s", path, strerror(errno)); | ||||||
|  |                 return NULL; | ||||||
|  |             } | ||||||
|  |             if (sendfile(tofd, fromfd, NULL, st.st_size) != st.st_size) | ||||||
|  |             { | ||||||
|  |                 close(fromfd); | ||||||
|  |                 close(tofd); | ||||||
|  |                 ERROR("Unable to copy file: %s", strerror(errno)); | ||||||
|  |                 return NULL; | ||||||
|  |             } | ||||||
|  |             is_tmp = 1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         np->pname = strdup(name); | ||||||
|  |         np->handle = plugin_from_file(name, path, pconf); | ||||||
|  |         if (is_tmp) | ||||||
|  |         { | ||||||
|  |             (void)remove(path); | ||||||
|  |         } | ||||||
|  |         if (np->handle == NULL) | ||||||
|  |         { | ||||||
|  |             if (np->pname) | ||||||
|  |                 free(np->pname); | ||||||
|  |             if (np) | ||||||
|  |                 free(np); | ||||||
|             return NULL; |             return NULL; | ||||||
|         } |         } | ||||||
|         hashval = hash(name, HASHSIZE); |         hashval = hash(name, HASHSIZE); | ||||||
|         np->next = plugin_table[hashval]; |         np->next = plugin_table[hashval]; | ||||||
|         plugin_table[hashval] = np; |         plugin_table[hashval] = np; | ||||||
|     } else /* already there */ |     } | ||||||
|  |     else /* already there */ | ||||||
|     { |     { | ||||||
|         LOG("The plugin %s id already loaded", name); |         LOG("The plugin %s id already loaded", name); | ||||||
|     } |     } | ||||||
| @@ -104,28 +148,35 @@ struct plugin_entry *plugin_load(char *name, dictionary_t config) | |||||||
|  * @param  name Name of the plugin |  * @param  name Name of the plugin | ||||||
|  * @return |  * @return | ||||||
|  */ |  */ | ||||||
| static void * plugin_from_file(char* name, dictionary_t conf) | static void *plugin_from_file(char *name, char *path, dictionary_t conf) | ||||||
| { | { | ||||||
|     void *lib_handle; |     void *lib_handle; | ||||||
|     char *error; |     char *error; | ||||||
|   char* path = __s("%s/%s%s",config()->plugins_dir,name,config()->plugins_ext); |     config_t *cnf = config(); | ||||||
|   void (*fn)(const char*, dictionary_t); |     void (*fn)(plugin_header_t *, dictionary_t); | ||||||
|    lib_handle = dlopen(path, RTLD_LAZY); |     lib_handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL /*| RTLD_NODELETE*/); | ||||||
|     if (!lib_handle) |     if (!lib_handle) | ||||||
|     { |     { | ||||||
|         ERROR("Cannot load plugin '%s' : '%s'", name, dlerror()); |         ERROR("Cannot load plugin '%s' : '%s'", name, dlerror()); | ||||||
| 	  if(path) |  | ||||||
| 		free(path); |  | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|     // set database path |     // set database path | ||||||
|    fn = (void (*)(const char*, dictionary_t))dlsym(lib_handle, "__init_plugin__"); |     fn = (void (*)(plugin_header_t *, dictionary_t))dlsym(lib_handle, "__init_plugin__"); | ||||||
|     if ((error = dlerror()) != NULL) |     if ((error = dlerror()) != NULL) | ||||||
|         ERROR("Problem when finding plugin init function for %s : %s", name, error); |         ERROR("Problem when finding plugin init function for %s : %s", name, error); | ||||||
|     else |     else | ||||||
| 	(*fn)(name, conf);  |     { | ||||||
|   if(path) |         plugin_header_t header; | ||||||
| 	free(path); |         strncpy(header.name, name, MAX_PATH_LEN - 1); | ||||||
|  |         strncpy(header.dbpath, cnf->db_path, MAX_PATH_LEN - 1); | ||||||
|  |         strncpy(header.tmpdir, cnf->tmpdir, MAX_PATH_LEN - 1); | ||||||
|  |         strncpy(header.pdir, cnf->plugins_dir, MAX_PATH_LEN - 1); | ||||||
|  |         header.config = conf; | ||||||
|  |         header.raw_body = 0; | ||||||
|  |         header.status = ANTD_PLUGIN_INIT; | ||||||
|  |         (*fn)(&header, conf); | ||||||
|  |     } | ||||||
|  |     // trick libc that we close this lib, but it is not realy deleted | ||||||
|     return lib_handle; |     return lib_handle; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -170,7 +221,8 @@ void unload_plugin_by_name(const char* name) | |||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 		if(np == NULL) return; // the plugin is is not loaded |         if (np == NULL) | ||||||
|  |             return; // the plugin is is not loaded | ||||||
|         unload_plugin(np->next); |         unload_plugin(np->next); | ||||||
|         np->next = np->next->next; |         np->next = np->next->next; | ||||||
|     } |     } | ||||||
| @@ -196,4 +248,3 @@ void unload_all_plugin() | |||||||
|     } |     } | ||||||
|     exit(0); |     exit(0); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user