diff options
author | František Dvořák <valtri@users.sourceforge.net> | 2003-10-20 08:36:56 +0000 |
---|---|---|
committer | František Dvořák <valtri@users.sourceforge.net> | 2003-10-20 08:36:56 +0000 |
commit | 442f9954b62477da117125772d5b5f5321a38182 (patch) | |
tree | 9b01080897706953b2dde6ed93a3bad14ab2b1f4 | |
parent | 4b23b23a6098c7f33737b1f69be0304658bb96ae (diff) | |
download | xine-lib-442f9954b62477da117125772d5b5f5321a38182.tar.gz xine-lib-442f9954b62477da117125772d5b5f5321a38182.tar.bz2 |
Clog the security hole in RIP input plugin. Streams may be saved only into onle directory.
Note, this is patch only for xine-engine. It doesn't cover cfg:// MRLs used by xine-ui.
CVS patchset: 5558
CVS date: 2003/10/20 08:36:56
-rw-r--r-- | src/xine-engine/configfile.c | 8 | ||||
-rw-r--r-- | src/xine-engine/configfile.h | 9 | ||||
-rw-r--r-- | src/xine-engine/input_rip.c | 73 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 65 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 3 |
5 files changed, 129 insertions, 29 deletions
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index 28cc51257..413e158a4 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: configfile.c,v 1.50 2003/07/31 11:59:10 mroi Exp $ + * $Id: configfile.c,v 1.51 2003/10/20 08:36:56 valtri Exp $ * * config object (was: file) management - implementation * @@ -976,6 +976,12 @@ int xine_config_change_opt(config_values_t *config, const char *opt) { entry = config->lookup_entry(config, key); + if(entry->exp_level >= XINE_CONFIG_SECURITY) { + printf(_("configfile: entry '%s' mustn't be modified from MRL\n"), key); + free(key); + return -1; + } + if(entry) { switch(entry->type) { diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h index e3e4cb0a1..c55cfdee5 100644 --- a/src/xine-engine/configfile.h +++ b/src/xine-engine/configfile.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: configfile.h,v 1.25 2003/07/31 12:04:55 mroi Exp $ + * $Id: configfile.h,v 1.26 2003/10/20 08:36:57 valtri Exp $ * * config file management * @@ -41,6 +41,13 @@ extern "C" { #define CONFIG_FILE_VERSION 1 +/* + * config entries above this experience + * level musn't be changed from MRL + */ +#define XINE_CONFIG_SECURITY 50 + + typedef struct cfg_entry_s cfg_entry_t; typedef struct config_values_s config_values_t; diff --git a/src/xine-engine/input_rip.c b/src/xine-engine/input_rip.c index e8535bea7..b96d3414d 100644 --- a/src/xine-engine/input_rip.c +++ b/src/xine-engine/input_rip.c @@ -29,7 +29,14 @@ * - it's possible speeder saving streams in the xine without playing: * xine stream_mrl#save:file.raw\;noaudio\;novideo * - * $Id: input_rip.c,v 1.7 2003/10/13 14:52:54 valtri Exp $ + * $Id: input_rip.c,v 1.8 2003/10/20 08:36:57 valtri Exp $ + */ + +/* TODO: + * - resume feature (via #append) + * - SEEK_SLOW replace by timeout + * - gui activation (after restarting playback) + * - long files support */ #ifdef HAVE_CONFIG_H @@ -39,15 +46,14 @@ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <libgen.h> #include <stdio.h> #include <string.h> #include <errno.h> /* logging */ -/* -#define LOG 1 -*/ +/*#define LOG 1*/ #define LOG_MODULE "input_rip" #define CLR_FAIL "\e[1;31m" #define CLR_RST "\e[0;39m" @@ -55,6 +61,7 @@ #include "xine_internal.h" #define SCRATCH_SIZE 1024 +#define MAX_TARGET_LEN 256 typedef struct { input_plugin_t input_plugin; /* inherited structure */ @@ -479,6 +486,36 @@ static void rip_plugin_dispose(input_plugin_t *this_gen) { free(this); } + +/* + * concat name of directory and name of file, + * returns non-zero, if there was enough space + */ +static int dir_file_concat(char *target, size_t maxlen, const char *dir, const char *name) { + size_t len_dir, len_name, pos_name = 0; + + len_name = strlen(name); + len_dir = strlen(dir); + + /* remove slashes */ + if (dir[len_dir - 1] == '/') len_dir--; + if (name[0] == '/') { + pos_name = 1; + len_name--; + } + + /* test and perform copy */ + if (len_dir + len_name + 2 > maxlen) { + target[0] = '\0'; + return 0; + } + if (len_dir) memcpy(target, dir, len_dir); + target[len_dir] = '/'; + strcpy(&target[len_dir + 1], name + pos_name); + return 1; +} + + /* * create self instance, * target file for writing stream is specified in 'data' @@ -488,8 +525,10 @@ input_plugin_t *rip_plugin_get_instance (xine_stream_t *stream, const char *file input_plugin_t *main_plugin = stream->input_plugin; struct stat pstat; const char *mode; + char target[MAX_TARGET_LEN]; + char *fnc; - lprintf("rip_plugin_get_instance(catch file = %s)\n", filename ? filename : "(null)"); + lprintf("rip_plugin_get_instance(catch file = %s), path = %s\n", filename ? filename : "(null)", stream->xine->save_path); /* check given input plugin */ if (!stream->input_plugin) { @@ -498,6 +537,12 @@ input_plugin_t *rip_plugin_get_instance (xine_stream_t *stream, const char *file return NULL; } + if (!stream->xine->save_path[0]) { + xine_log(stream->xine, XINE_LOG_MSG, + _("input_rip: target directory wasn't specified, please fill out the option 'misc.save_dir'\n")); + return NULL; + } + if ( main_plugin->get_capabilities(main_plugin) & INPUT_CAP_RIP_FORBIDDEN ) { xine_log(stream->xine, XINE_LOG_MSG, _("input_rip: ripping/caching is not permitted!\n")); @@ -516,11 +561,19 @@ input_plugin_t *rip_plugin_get_instance (xine_stream_t *stream, const char *file this->curpos = 0; this->savepos = 0; - /* find out type of file */ - if (stat(filename, &pstat) < 0 && errno != ENOENT) { + fnc = strdup(filename); + dir_file_concat(target, MAX_TARGET_LEN, stream->xine->save_path, + basename(fnc)); + free(fnc); + lprintf("target file: %s\n", target); + + /* find out type of target */ + if (stat(target, &pstat) < 0 && errno != ENOENT) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: stat on the file %s failed: %s\n"), - filename, strerror(errno)); + target, strerror(errno)); + free(this); + return NULL; } if (errno != ENOENT && S_ISFIFO(pstat.st_mode)) { this->regular = 0; @@ -530,10 +583,10 @@ input_plugin_t *rip_plugin_get_instance (xine_stream_t *stream, const char *file mode = "wb+"; } - if ((this->file = fopen(filename, mode)) == NULL) { + if ((this->file = fopen(target, mode)) == NULL) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: error opening file %s: %s\n"), - filename, strerror(errno)); + target, strerror(errno)); free(this); return NULL; } diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 4330bf605..ddca0f974 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine.c,v 1.258 2003/10/13 11:13:59 mroi Exp $ + * $Id: xine.c,v 1.259 2003/10/20 08:36:57 valtri Exp $ */ /* @@ -782,6 +782,7 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { /* when we got here, the stream setup parameter must be a config entry */ const char *tmp = stream_setup; char *config_entry; + int retval; if ((stream_setup = strchr(stream_setup, ';'))) { config_entry = (char *)malloc(stream_setup - tmp + 1); memcpy(config_entry, tmp, stream_setup - tmp); @@ -792,12 +793,22 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { config_entry[strlen(tmp)] = '\0'; } mrl_unescape(config_entry); - if (!xine_config_change_opt(stream->xine->config, config_entry)) { + retval = xine_config_change_opt(stream->xine->config, config_entry); + if (retval <= 0) { + if (retval == 0) { + /* the option not found */ + xine_log(stream->xine, XINE_LOG_MSG, + _("xine: error while parsing MRL\n")); + } else { + /* not permitted to change from MRL */ + xine_log(stream->xine, XINE_LOG_MSG, + _("xine: changing option '%s' from MRL isn't permitted\n"), + config_entry); + } + stream->err = XINE_ERROR_MALFORMED_MRL; + stream->status = XINE_STATUS_STOP; free(config_entry); - printf("xine: error while parsing mrl\n"); - stream->err = XINE_ERROR_MALFORMED_MRL; - stream->status = XINE_STATUS_STOP; - return 0; + return 0; } free(config_entry); } @@ -1203,6 +1214,18 @@ int xine_engine_get_param(xine_t *this, int param) { return -1; } +static void config_demux_strategy_cb (void *this_gen, xine_cfg_entry_t *entry) { + xine_t *this = (xine_t *)this_gen; + + this->demux_strategy = entry->num_value; +} + +static void config_save_cb (void *this_gen, xine_cfg_entry_t *entry) { + xine_t *this = (xine_t *)this_gen; + + this->save_path = entry->str_value; +} + void xine_init (xine_t *this) { static char *demux_strategies[] = {"default", "reverse", "content", "extension", NULL}; @@ -1219,21 +1242,31 @@ void xine_init (xine_t *this) { scan_plugins(this); - /* - * content detection strategy - */ - #ifdef HAVE_SETLOCALE if (!setlocale(LC_CTYPE, "")) printf("xine: locale not supported by C library\n"); #endif - this->demux_strategy = this->config->register_enum (this->config, - "misc.demux_strategy", - 0, - demux_strategies, - "media format detection strategy", - NULL, 10, NULL, NULL); + /* + * content detection strategy + */ + this->demux_strategy = this->config->register_enum ( + this->config, "misc.demux_strategy", 0, + demux_strategies, + _("Media format detection strategy"), + NULL, + 10, config_demux_strategy_cb, this); + + /* + * save directory + */ + this->save_path = this->config->register_string ( + this->config, + "misc.save_dir", "", + _("Path for saving streams"), + _("Streams will be saved only into this directory"), + XINE_CONFIG_SECURITY, config_save_cb, this); + /* * keep track of all opened streams */ diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 332d8f75c..da0fb8514 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_internal.h,v 1.142 2003/10/19 19:45:03 tmattern Exp $ + * $Id: xine_internal.h,v 1.143 2003/10/20 08:36:57 valtri Exp $ * */ @@ -104,6 +104,7 @@ struct xine_s { plugin_catalog_t *plugin_catalog; int demux_strategy; + char *save_path; /* log output that may be presented to the user */ scratch_buffer_t *log_buffers[XINE_LOG_NUM]; |