Commit 6bd222b1 authored by Marc Ariberti's avatar Marc Ariberti

* first draft for an .xml config file

* needs libxerces2 installed (+ dev files)

* to not compile xml support tune Makefile.opts
* beware, no checks are performed on the xml file yet !
parent 05133a74
......@@ -4,6 +4,7 @@
Head
* added xml config file support for finer security features (needs xerces)
* Denies client according to their ipv4 (see vlcs.conf)
* continuing C++ translation
* new command line options : ipv6, ipv4, bind and port
......
......@@ -2,36 +2,10 @@
# vlcs (VideoLAN Channel Server) main Makefile - (c)2001-2002 VideoLAN
###############################################################################
VERSION=0.2.1
#CC=g++-3.2
CC=c++
CFLAGS=-O3 -g -I. -Wall -DVERSION="\"$(VERSION)\""
include Makefile.opts
all: vlcs
vlcs.o: vlcs.c vlcs.h logger.h socket.h config.h host.h
$(CC) $(CFLAGS) -c -o vlcs.o vlcs.c
host.o: host.c host.h
$(CC) $(CFLAGS) -c -o host.o host.c
socket.o: socket.c socket.h logger.h vlcs.h config.h host.h
$(CC) $(CFLAGS) -c -o socket.o socket.c
logger.o: logger.c logger.h vlcs.h host.h
$(CC) $(CFLAGS) -c -o logger.o logger.c
config.o: config.c config.h logger.h vlcs.h socket.h host.h
$(CC) $(CFLAGS) -c -o config.o config.c
vlcs: vlcs.o logger.o config.o socket.o host.o
$(CC) $(CFLAGS) -o vlcs vlcs.o logger.o config.o socket.o host.o
tar:
mkdir miniVLCS-$(VERSION)
cp logger.c logger.h socket.c socket.h config.c config.h host.c host.h vlcs.c vlcs.h vlcs.conf Makefile README COPYING miniVLCS-$(VERSION)
tar cvzf miniVLCS-$(VERSION).tar.gz miniVLCS-$(VERSION)
rm -rf miniVLCS-$(VERSION)
all:
make -C src
clean:
-rm -f vlcs *.tar.gz *.o
-rm -f src/vlcs *.tar.gz **/*.o
#
# Cpmpilation options for miniVLCS
#
# Set this to 1 if you want to compile with xerces-c
XERCESC=1
VERSION=0.2.1
#CC=g++-3.2
CC=c++
CFLAGS=-O3 -g -I. -Wall -DVERSION="\"$(VERSION)\""
###############################################################################
# vlcs (VideoLAN Channel Server) main Makefile - (c)2001-2002 VideoLAN
###############################################################################
include ../Makefile.opts
LDLIBS=
OBJ= logger.o config-txt.o socket.o host.o
ifeq ($(XERCESC), 1)
LDLIBS += -lxerces-c
CFLAGS += -DXERCES
OBJ += config-xml.o
endif
all: vlcs
%.o: %.cc config-common.h logger.h vlcs.h socket.h host.h config-xml.h
$(CC) $(CFLAGS) -c -o $@ $<
vlcs: vlcs.o $(OBJ)
$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)
tar:
echo "************ Does not work **************"
mkdir miniVLCS-$(VERSION)
cp logger.c logger.h socket.c socket.h config.c config.h vlcs.c vlcs.h vlcs.conf Makefile README COPYING miniVLCS-$(VERSION)
tar cvzf miniVLCS-$(VERSION).tar.gz miniVLCS-$(VERSION)
rm -rf miniVLCS-$(VERSION)
clean:
-rm -f vlcs *.tar.gz *.o
......@@ -2,7 +2,7 @@
* config.c: mini-VideoLAN Channel Server, configuration system
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: config.h,v 1.6 2002/12/02 17:52:24 marcari Exp $
* $Id: config-common.h,v 1.1 2002/12/04 18:10:50 marcari Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Marc Ariberti <marcari@via.ecp.fr>
......@@ -29,37 +29,37 @@ public:
typedef enum { IPV4, IPV6 } inet_type;
C_Config(C_Logger &logger);
~C_Config();
void DestroyList( void );
void AddList( std::string item );
time_t GetModificationTime( void );
void ReadFile( void );
std::string GetChannel( int i_channel );
void CheckUpdate( void );
int GetChannelNumber( void );
virtual ~C_Config();
virtual std::string GetChannel( int i_channel ) = 0;
virtual int GetChannelNumber( void ) = 0;
virtual void ReadFile( void ) = 0;
virtual bool isAllowed(std::string client, int channel) = 0;
void CheckUpdate( void );
void SetConfigFile(std::string psz_config_file);
void setInetType(inet_type t);
void setSocketPort(int port);
void setBindAddr(std::string addr);
inet_type getInetType();
void setSocketPort(int port);
int getSocketPort();
void setBindAddr(std::string addr);
std::string getBindAddr();
std::list<C_Host *> &getHostsAuth();
static char * RemoveLF( char * str );
protected:
int i_channel_max; /* number of valid channels available */
C_Logger &logger; /* logging facility object */
std::string configFile; /* filename of the config file */
time_t mtime; /* last modification time of the config file */
std::vector<std::string> channels;
std::list<C_Host *> h_hosts;
time_t GetModificationTime( void );
inet_type socket_type;
std::string bindAddr;
int socket_port;
C_Logger &logger; /* logging facility object */
std::string configFile; /* filename of the config file */
time_t mtime; /* last modification time of the config file */
};
......@@ -2,7 +2,7 @@
* config.c: mini-VideoLAN Channel Server, configuration system
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: config.c,v 1.9 2002/12/02 18:03:11 marcari Exp $
* $Id: config-txt.cc,v 1.1 2002/12/04 18:10:50 marcari Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Marc Ariberti <marcari@via.ecp.fr>
......@@ -47,16 +47,27 @@
#include "host.h"
#include "vlcs.h"
#include "logger.h"
#include "config.h"
#include "config-common.h"
#include "config-txt.h"
C_Config::C_Config(C_Logger &logger)
: logger(logger), configFile(CHANNEL_CONF), channels(12), bindAddr()
///////
C_Config::C_Config(C_Logger &logger) : logger(logger), configFile(CHANNEL_CONF)
{
}
C_Config::~C_Config()
{
}
C_ConfigTxt::C_ConfigTxt(C_Logger &logger)
: C_Config(logger), channels(12)
{
socket_port = 0;
socket_type = IPV4;
}
C_Config::~C_Config()
C_ConfigTxt::~C_ConfigTxt()
{
DestroyList();
}
......@@ -64,7 +75,7 @@ C_Config::~C_Config()
/*
* Destroy the linked list
*/
void C_Config::DestroyList( void )
void C_ConfigTxt::DestroyList( void )
{
channels.clear();
i_channel_max = 0;
......@@ -91,7 +102,7 @@ char * C_Config::RemoveLF( char * str )
/*
* Adds the item to the list
*/
void C_Config::AddList( std::string item )
void C_ConfigTxt::AddList( std::string item )
{
channels.push_back(item);
//RemoveLF( p_new->psz_vlc_config);
......@@ -100,16 +111,7 @@ void C_Config::AddList( std::string item )
<< item << C_Logger::END;
}
time_t C_Config::GetModificationTime( void )
{
struct stat buf;
stat( configFile.c_str(), &buf);
return buf.st_mtime;
}
void C_Config::ReadFile( void )
void C_ConfigTxt::ReadFile( void )
{
char psz_vlc_command[2048];
char psz_buffer[2048];
......@@ -162,28 +164,57 @@ void C_Config::ReadFile( void )
fclose( p_config );
}
void C_Config::CheckUpdate()
std::string C_ConfigTxt::GetChannel( int i_channel )
{
if( mtime != GetModificationTime() )
{
ReadFile();
}
}
std::string C_Config::GetChannel( int i_channel )
{
if ( i_channel > i_channel_max)
if ( i_channel >= i_channel_max)
{
return *new std::string("E:channel does not exist.");
}
return channels[i_channel];
}
int C_Config::GetChannelNumber( void )
int C_ConfigTxt::GetChannelNumber( void )
{
return i_channel_max + 1;
}
////
std::list<C_Host *> &C_ConfigTxt::getHostsAuth()
{
return h_hosts;
}
bool C_ConfigTxt::isAllowed(std::string client, int channel)
{
in_addr_t client_addr = C_Host::pton(client);
std::list<C_Host *>::iterator host = h_hosts.begin();
while (host != h_hosts.end())
{
if ((*host)->test(client_addr))
{
if ((*host)->getType() == C_Host::ALLOW)
{
return true;
}
else
{
logger << C_Logger::WARNING << "Break in attempt from "
<< client << C_Logger::END;
return false;
}
}
++host;
}
return true;
}
///////////////////////////////////////////////////////////:
// C_Config class implementation
void C_Config::SetConfigFile(std::string new_config_file)
{
configFile = new_config_file;
......@@ -225,11 +256,20 @@ std::string C_Config::getBindAddr()
return bindAddr;
}
////
time_t C_Config::GetModificationTime( void )
{
struct stat buf;
std::list<C_Host *> &C_Config::getHostsAuth()
{
return h_hosts;
stat( configFile.c_str(), &buf);
return buf.st_mtime;
}
void C_Config::CheckUpdate()
{
if( mtime != GetModificationTime() )
{
ReadFile();
}
}
/*****************************************************************************
* config.c: mini-VideoLAN Channel Server, configuration system
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: config-txt.h,v 1.1 2002/12/04 18:10:50 marcari Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Marc Ariberti <marcari@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
class C_ConfigTxt : public C_Config
{
public:
C_ConfigTxt(C_Logger &logger);
virtual ~C_ConfigTxt();
virtual std::string GetChannel( int i_channel );
virtual int GetChannelNumber( void );
virtual void ReadFile( void );
virtual bool isAllowed(std::string client, int channel);
protected:
void DestroyList( void );
void AddList( std::string item );
std::list<C_Host *> &getHostsAuth();
int i_channel_max; /* number of valid channels available */
std::vector<std::string> channels;
std::list<C_Host *> h_hosts;
};
/*****************************************************************************
* config-xml.cc: mini-VideoLAN Channel Server, configuration system
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: config-xml.cc,v 1.1 2002/12/04 18:10:50 marcari Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Marc Ariberti <marcari@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <malloc.h>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <syslog.h>
#include <errno.h>
#include <arpa/inet.h>
#include <signal.h>
#include <time.h>
#include <vector>
#include <list>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <utility>
#include "host.h"
#include "vlcs.h"
#include "logger.h"
#include "config-common.h"
#include "config-xml.h"
C_ConfigXml::C_ConfigXml(C_Logger &logger)
: C_Config(logger), channels(0), i_channel_max(0)
{
socket_port = 0;
socket_type = IPV4;
}
C_ConfigXml::~C_ConfigXml()
{
}
void C_ConfigXml::ReadFile()
{
try {
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
logger << C_Logger::ERROR << "Error during initialization! :\n"
<< message << "\n" << C_Logger::END;
delete [] message;
return;
}
XercesDOMParser* parser = new XercesDOMParser();
parser->setValidationScheme(XercesDOMParser::Val_Always); // optional.
parser->setDoNamespaces(true); // optional
ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
parser->setErrorHandler(errHandler);
mtime = GetModificationTime();
channels.clear();
h_hosts.clear();
try {
parser->parse(configFile.c_str());
}
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
logger << C_Logger::ERROR << "Exception message is: \n"
<< message << "\n" << C_Logger::END;
delete [] message;
return;
}
catch (const DOMException& toCatch) {
char* message = XMLString::transcode(toCatch.msg);
logger << C_Logger::ERROR << "Exception message is: \n"
<< message << "\n" << C_Logger::END;
delete [] message;
return;
}
catch (...) {
logger << C_Logger::ERROR << "Unexpected Exception \n" << C_Logger::END;
return;
}
DOMNode *configuration = parser->getDocument();
DOMNode *current = configuration->getFirstChild();
std::string str = XMLString::transcode(current->getNodeName());
if (str != "vlcs-conf")
{
logger << C_Logger::ERROR << "Bad config file, missing vlcs-conf element" << C_Logger::END;
}
current = current->getFirstChild();
i_channel_max = 0;
while (current != NULL)
{
if (current->getNodeType() == DOMNode::ELEMENT_NODE)
{
str = XMLString::transcode(current->getNodeName());
if (str == "channel")
{
i_channel_max++;
channels.push_back(C_Channel(current));
}
else if (str == "group")
{
h_hosts.insert(newGroup(current));
}
}
current = current->getNextSibling();
}
delete parser;
delete errHandler;
}
std::pair<std::string, std::list<std::pair<std::string, std::string> > >
C_ConfigXml::newGroup(DOMNode * node)
{
std::string name;
std::string addr;
std::string mask;
std::string subnet;
std::list<std::pair<std::string, std::string> > liste;
DOMNode * current;
std::string str;
current = node->getFirstChild();
while (current != NULL)
{
if (current->getNodeType() == DOMNode::ELEMENT_NODE)
{
str = XMLString::transcode(current->getNodeName());
if (str == "name")
{
name = XMLString::transcode(
current->getFirstChild()->getNodeValue());
}
else if (str == "ip")
{
addr = XMLString::transcode(
current->getFirstChild()->getNodeValue());
mask = "255.255.255.255";
liste.push_back(std::pair<std::string, std::string>(addr,mask));
}
else if (str == "subnet")
{
subnet = XMLString::transcode(
current->getFirstChild()->getNodeValue());
int pos = subnet.find('/');
addr = subnet.substr(0, pos);
mask = subnet.substr(pos+1);
liste.push_back(std::pair<std::string, std::string>(addr,mask));
}
}
current = current->getNextSibling();
}
return std::pair<std::string, std::list<std::pair<std::string, std::string> > > (name, liste);
}
int C_ConfigXml::GetChannelNumber()
{
return i_channel_max;
}
bool C_ConfigXml::isAllowed(std::string client, int channel)
{
in_addr_t addr;
in_addr_t mask;
in_addr_t caddr = C_Host::pton(client);
if (channel >= i_channel_max)
{
return true;
}
std::list<std::pair<std::string, C_Channel::type> >
groupes = channels[channel].auth;
std::list<std::pair<std::string, C_Channel::type> >::iterator
groupe = groupes.begin();
while (groupe != groupes.end())
{
std::list<std::pair<std::string, std::string> >
subnets = h_hosts[(*groupe).first];
std::list<std::pair<std::string, std::string> >::iterator
subnet = subnets.begin();
while (subnet != subnets.end())
{
addr = C_Host::pton((*subnet).first);
mask = C_Host::pton((*subnet).second);
if ((addr & mask) == (caddr & mask))
{
if ((*groupe).second == C_Channel::ALLOW)
{
return true;
}
else
{
logger << C_Logger::WARNING << "Break in attempt from "
<< client << C_Logger::END;
return false;
}
}
++subnet;
}
++groupe;
}
return true;
}
std::string C_ConfigXml::GetChannel(int i_channel)
{
return channels[i_channel].vlc_string;
}
/////////////////////
// C_Channel implementation
C_Channel::C_Channel()
{
}
C_Channel::C_Channel(DOMNode * node)
{
DOMNode * current;
std::string str;
current = node->getFirstChild();
while (current != NULL)
{
if (current->getNodeType() == DOMNode::ELEMENT_NODE)
{
str = XMLString::transcode(current->getNodeName());
if (str == "name")
{
name = XMLString::transcode(
current->getFirstChild()->getNodeValue());
}
else if (str == "vlc")
{
vlc_string = XMLString::transcode(
current->getFirstChild()->getNodeValue());
}
else if (str == "allow")
{
auth.push_back(std::pair<std::string, type>(
std::string(XMLString::transcode(current->getFirstChild()->getNodeValue())), ALLOW));
}
else if (str == "deny")
{
auth.push_back(std::pair<std::string, type>(
std::string(XMLString::transcode(current->getFirstChild()->getNodeValue())), DENY));
}
}
current = current->getNextSibling();
}
std::cerr << "Adding : " << name << " " << vlc_string << std::endl;
}
C_Channel::~C_Channel()
{
}
/*****************************************************************************
* config-xml.h: mini-VideoLAN Channel Server, configuration system
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: config-xml.h,v 1.1 2002/12/04 18:10:50 marcari Exp $
*
* Authors: Marc Ariberti <marcari@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
class C_Channel
{
public:
typedef enum { ALLOW, DENY } type;
C_Channel();
C_Channel(DOMNode * node);
~C_Channel();
std::string name;
std::string vlc_string;
std::list<std::pair<std::string, type> > auth;
};