From 0b7e9057daceab33b13238f4dea90976b5d2074d Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 2 Feb 2002 17:20:54 +0100 Subject: [PATCH] Introduced 'svdrphosts.conf' --- FORMATS | 20 +++++++++++++++++++ HISTORY | 3 +++ INSTALL | 5 +++++ config.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- config.h | 19 +++++++++++++++++- svdrp.c | 14 +++++++++++--- svdrphosts.conf | 13 +++++++++++++ vdr.c | 3 ++- 8 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 svdrphosts.conf diff --git a/FORMATS b/FORMATS index 2a99e6ef..7cc4333d 100644 --- a/FORMATS +++ b/FORMATS @@ -111,6 +111,26 @@ Video Disk Recorder File Formats 1..9, the command can be selected directly by pressing the respective numerical key on the remote control. +* svdrphosts.conf + + This file contains the IP numbers of all hosts that are allowed to access the + SVDRP port. + + Each line contains one IP number in the format + + IP-Address[/Netmask] + + where 'IP-Address' is the address of a host or a network in the usual dot + separated notation (as in 192.168.100.1). If the optional 'Netmask' is given + only the given number of bits of 'IP-Address' are taken into account. This + allows you to grant SVDRP access to all hosts of an entire network. 'Netmask' + can be any integer from 1 to 32. The special value of 0 is only accepted if + the 'IP-Address' is 0.0.0.0, because this will give access to any host (USE + THIS WITH CARE!). + + Everything following (and including) a '#' character is considered to be + comment. + * marks.vdr This file (if present in a recording directory) contains the editing marks diff --git a/HISTORY b/HISTORY index 98e04e99..75966ef0 100644 --- a/HISTORY +++ b/HISTORY @@ -950,3 +950,6 @@ Video Disk Recorder Revision History thus making it safe to use them in nested 'if/else' statements. - Fixed error handling in establishing an SVDRP connection (thanks to Davide Achilli) for pointing this out). +- The new configuration file 'svdrphosts.conf' is now used to define which + hosts may access the SVDRP port (by default only 'localhost' has access). + See FORMATS for details. diff --git a/INSTALL b/INSTALL index d1650961..cf694890 100644 --- a/INSTALL +++ b/INSTALL @@ -81,6 +81,11 @@ WARNING: DUE TO THE OPEN SVDRP PORT THIS PROGRAM MAY CONSTITUTE A A CONTROLLED ENVIRONMENT, YOU MAY WANT TO DISABLE SVDRP BY USING '--port=0'! +The file 'svdrphosts.conf' can be used to define which hosts are allowed +to access the SVDRP port. By default only localhost (127.0.0.1) is granted +access. If you want to give other hosts access to your SVDRP port you need to +add their IP numbers to 'svdrphosts.conf'. + If the program shall run as a daemon, use the --daemon option. This will completely detach it from the terminal and will continue as a background process. diff --git a/config.c b/config.c index eaf937a3..9a2ab7a0 100644 --- a/config.c +++ b/config.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.80 2002/02/02 15:57:48 kls Exp $ + * $Id: config.c 1.81 2002/02/02 17:15:03 kls Exp $ */ #include "config.h" @@ -646,6 +646,40 @@ const char *cCommand::Execute(void) return result; } +// -- cSVDRPhost ------------------------------------------------------------- + +cSVDRPhost::cSVDRPhost(void) +{ + addr.s_addr = 0; + mask = 0; +} + +bool cSVDRPhost::Parse(const char *s) +{ + mask = 0xFFFFFFFF; + const char *p = strchr(s, '/'); + if (p) { + char *error = NULL; + int m = strtoul(p + 1, &error, 10); + if (error && !isspace(*error) || m > 32) + return false; + *(char *)p = 0; // yes, we know it's 'const' - will be restored! + if (m == 0) + mask = 0; + else + mask >>= (32 - m); + } + int result = inet_aton(s, &addr); + if (p) + *(char *)p = '/'; // there it is again + return result != 0 && (mask != 0 || addr.s_addr == 0); +} + +bool cSVDRPhost::Accepts(in_addr_t Address) +{ + return (Address & mask) == addr.s_addr; +} + // -- cKeys ------------------------------------------------------------------ cKeys Keys; @@ -778,6 +812,21 @@ cTimer *cTimers::GetNextActiveTimer(void) return t0; } +// -- cSVDRPhosts ------------------------------------------------------------ + +cSVDRPhosts SVDRPhosts; + +bool cSVDRPhosts::Acceptable(in_addr_t Address) +{ + cSVDRPhost *h = First(); + while (h) { + if (h->Accepts(Address)) + return true; + h = (cSVDRPhost *)h->Next(); + } + return false; +} + // -- cSetup ----------------------------------------------------------------- cSetup Setup; diff --git a/config.h b/config.h index 15069438..06cd583d 100644 --- a/config.h +++ b/config.h @@ -4,12 +4,13 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.91 2002/02/02 15:57:48 kls Exp $ + * $Id: config.h 1.92 2002/02/02 15:59:18 kls Exp $ */ #ifndef __CONFIG_H #define __CONFIG_H +#include #include #include #include @@ -171,6 +172,16 @@ public: const char *Execute(void); }; +class cSVDRPhost : public cListObject { +private: + struct in_addr addr; + in_addr_t mask; +public: + cSVDRPhost(void); + bool Parse(const char *s); + bool Accepts(in_addr_t Address); + }; + template class cConfig : public cList { private: char *fileName; @@ -268,10 +279,16 @@ public: class cCommands : public cConfig {}; +class cSVDRPhosts : public cConfig { +public: + bool Acceptable(in_addr_t Address); + }; + extern cChannels Channels; extern cTimers Timers; extern cKeys Keys; extern cCommands Commands; +extern cSVDRPhosts SVDRPhosts; class cSetup { private: diff --git a/svdrp.c b/svdrp.c index eba409bb..08da0667 100644 --- a/svdrp.c +++ b/svdrp.c @@ -10,7 +10,7 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 1.29 2002/02/02 13:33:57 kls Exp $ + * $Id: svdrp.c 1.30 2002/02/02 15:59:18 kls Exp $ */ #include "svdrp.h" @@ -101,8 +101,16 @@ int cSocket::Accept(void) struct sockaddr_in clientname; uint size = sizeof(clientname); int newsock = accept(sock, (struct sockaddr *)&clientname, &size); - if (newsock > 0) - isyslog(LOG_INFO, "connect from %s, port %hd", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port)); + if (newsock > 0) { + bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr); + if (!accepted) { + const char *s = "Access denied!\n"; + write(newsock, s, strlen(s)); + close(newsock); + newsock = -1; + } + isyslog(LOG_INFO, "connect from %s, port %hd - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED"); + } else if (errno != EINTR && errno != EAGAIN) LOG_ERROR; return newsock; diff --git a/svdrphosts.conf b/svdrphosts.conf new file mode 100644 index 00000000..dec9c42a --- /dev/null +++ b/svdrphosts.conf @@ -0,0 +1,13 @@ +# +# svdrphosts This file describes a number of host addresses that +# are allowed to connect to the SVDRP port of the Video +# Disk Recorder (VDR) running on this system. +# Syntax: +# +# IP-Address[/Netmask] +# + +127.0.0.1 # always accept localhost +#192.168.100.0/24 # any host on the local net +#204.152.189.113 # a specific host +#0.0.0.0/0 # any host on any net (USE THIS WITH CARE!) diff --git a/vdr.c b/vdr.c index 5351e409..72f04f8f 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.93 2002/01/26 14:07:01 kls Exp $ + * $Id: vdr.c 1.94 2002/02/02 15:59:18 kls Exp $ */ #include @@ -272,6 +272,7 @@ int main(int argc, char *argv[]) Channels.Load(AddDirectory(ConfigDirectory, "channels.conf")); Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")); Commands.Load(AddDirectory(ConfigDirectory, "commands.conf")); + SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true); #if defined(REMOTE_LIRC) Keys.SetDummyValues(); #elif !defined(REMOTE_NONE)