summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrantišek Dvořák <valtri@users.sourceforge.net>2003-10-20 08:36:56 +0000
committerFrantišek Dvořák <valtri@users.sourceforge.net>2003-10-20 08:36:56 +0000
commit442f9954b62477da117125772d5b5f5321a38182 (patch)
tree9b01080897706953b2dde6ed93a3bad14ab2b1f4
parent4b23b23a6098c7f33737b1f69be0304658bb96ae (diff)
downloadxine-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.c8
-rw-r--r--src/xine-engine/configfile.h9
-rw-r--r--src/xine-engine/input_rip.c73
-rw-r--r--src/xine-engine/xine.c65
-rw-r--r--src/xine-engine/xine_internal.h3
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];