Commit 55f0a110 authored by Marc Ariberti's avatar Marc Ariberti

  * Denies client according to their ipv4 (see vlcs.conf), useful to secure
  easily access to vlcs service
  * continuing C++ translation
  * new command line options : ipv6, ipv4, bind and port
parent 38ede3ce
......@@ -4,6 +4,9 @@
Head
* Denies client according to their ipv4 (see vlcs.conf)
* continuing C++ translation
* new command line options : ipv6, ipv4, bind and port
* miniVLCS compiles with gcc 3.2
0.2.0
......
###############################################################################
# vlcs (VideoLAN Channel Server) main Makefile - (c)2001 VideoLAN
# vlcs (VideoLAN Channel Server) main Makefile - (c)2001-2002 VideoLAN
###############################################################################
VERSION=0.2.0b
#CC=g++-3.2
CC=c++
CFLAGS=-O3 -g -I. -Wall
VERSION=0.2.1
CC=g++-3.2
#CC=c++
CFLAGS=-O3 -g -I. -Wall -DVERSION="\"$(VERSION)\""
all: vlcs
vlcs.o: vlcs.c vlcs.h logger.h socket.h config.h
$(CC) $(CFLAGS) -c -o vlcs.o vlcs.c
socket.o: socket.c socket.h logger.h vlcs.h config.h
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
......@@ -21,10 +24,10 @@ logger.o: logger.c logger.h vlcs.h
config.o: config.c config.h logger.h vlcs.h socket.h
$(CC) $(CFLAGS) -c -o config.o config.c
vlcs: vlcs.o logger.o config.o socket.o
$(CC) $(CFLAGS) -o vlcs vlcs.o logger.o config.o socket.o
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: all
tar:
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)
......
......@@ -2,7 +2,7 @@
* config.c: mini-VideoLAN Channel Server, configuration system
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: config.c,v 1.7 2002/10/28 17:38:30 marcari Exp $
* $Id: config.c,v 1.8 2002/12/02 17:52:24 marcari Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Marc Ariberti <marcari@via.ecp.fr>
......@@ -38,25 +38,27 @@
#include <arpa/inet.h>
#include <signal.h>
#include <time.h>
#include <list>
#include <vector>
#include <list>
#include <iostream>
#include <fstream>
#include <string>
#include "host.h"
#include "vlcs.h"
#include "logger.h"
#include "config.h"
C_Config::C_Config(C_Logger &logger)
: logger(logger)
: logger(logger), configFile(CHANNEL_CONF), channels(12), bindAddr()
{
m_pszConfigFile = strdup(CHANNEL_CONF);
socket_port = 0;
socket_type = IPV4;
}
C_Config::~C_Config()
{
DestroyList();
free(m_pszConfigFile);
}
/*
......@@ -64,16 +66,9 @@ C_Config::~C_Config()
*/
void C_Config::DestroyList( void )
{
channel_t * p_channel = p_channels;
channel_t * p_next = NULL;
while( p_channel != NULL )
{
p_next = p_channel->next;
free(p_channel);
p_channel = p_next;
}
p_channels = NULL;
channels.clear();
i_channel_max = 0;
h_hosts.clear();
logger << C_Logger::INFO << "List of channels cleared" << C_Logger::END;
}
......@@ -96,38 +91,20 @@ char * C_Config::RemoveLF( char * str )
/*
* Adds the item to the list
*/
void C_Config::AddList( char * psz_item )
void C_Config::AddList( std::string item )
{
channel_t ** pp_cur = &p_channels;
channel_t * p_new;
/* finds the end of the linked list */
while( (*pp_cur) != NULL )
{
pp_cur = &((*pp_cur)->next);
}
p_new = (channel_t *)malloc( sizeof( channel_t ) );
*pp_cur = p_new;
strncpy( p_new->psz_vlc_config, psz_item, 255 );
p_new->psz_vlc_config[255] = 0;
p_new->next = NULL;
RemoveLF( p_new->psz_vlc_config);
channels.push_back(item);
//RemoveLF( p_new->psz_vlc_config);
i_channel_max++;
logger << C_Logger::INFO << "Adding channel " << i_channel_max << " : "
<< p_new->psz_vlc_config << C_Logger::END;
<< item << C_Logger::END;
}
time_t C_Config::GetModificationTime( void )
{
struct stat buf;
stat( m_pszConfigFile, &buf);
stat( configFile.c_str(), &buf);
return buf.st_mtime;
}
......@@ -137,15 +114,16 @@ void C_Config::ReadFile( void )
char psz_vlc_command[2048];
char psz_buffer[2048];
FILE * p_config;
int config_type = 0;
DestroyList();
st_mtime = GetModificationTime();
mtime = GetModificationTime();
p_config = fopen( m_pszConfigFile, "r" );
p_config = fopen( configFile.c_str(), "r" );
if( p_config == NULL )
{
logger << C_Logger::ALERT << "Cannot fopen " << m_pszConfigFile
logger << C_Logger::ALERT << "Cannot fopen " << configFile
<< " : "<< strerror(errno) << C_Logger::END;
exit( -1 );
}
......@@ -154,10 +132,30 @@ void C_Config::ReadFile( void )
while( fgets( psz_buffer, sizeof( psz_buffer ), p_config ) != NULL )
{
if( psz_buffer[0] != '#' && psz_buffer[0] != '\0' )
if( psz_buffer[0] != '#'
&& psz_buffer[0] != '\0'
&& psz_buffer[0] != '\n'
&& psz_buffer[0] != ' ' )
{
std::string * command;
sscanf(psz_buffer, "%s", psz_vlc_command);
AddList(psz_vlc_command);
command = new std::string(psz_vlc_command);
if (!command->compare("@auth"))
{
config_type = 1;
continue;
}
if (config_type == 0)
{
AddList(*command);
}
else if (config_type == 1)
{
C_Host * h_host = new C_Host(*command);
h_hosts.push_back(h_host);
logger << C_Logger::INFO << h_host->getStr() << C_Logger::END;
}
}
}
......@@ -166,25 +164,19 @@ void C_Config::ReadFile( void )
void C_Config::CheckUpdate()
{
if( st_mtime != GetModificationTime() )
if( mtime != GetModificationTime() )
{
ReadFile();
}
}
channel_t * C_Config::GetChannel( int i_channel )
std::string C_Config::GetChannel( int i_channel )
{
channel_t * p_channel = p_channels;
while( i_channel > 0 )
if ( i_channel >= i_channel_max)
{
p_channel = p_channel->next;
if( p_channel == NULL )
{
return NULL;
}
i_channel--;
return *new std::string("E:channel does not exist.");
}
return p_channel;
return channels[i_channel];
}
int C_Config::GetChannelNumber( void )
......@@ -192,8 +184,52 @@ int C_Config::GetChannelNumber( void )
return i_channel_max + 1;
}
void C_Config::SetConfigFile(char * psz_config_file)
void C_Config::SetConfigFile(std::string new_config_file)
{
free(m_pszConfigFile);
m_pszConfigFile = strdup(psz_config_file);
configFile = new_config_file;
}
////
void C_Config::setInetType(inet_type t)
{
socket_type = t;
}
C_Config::inet_type C_Config::getInetType()
{
return socket_type;
}
////
void C_Config::setSocketPort(int port)
{
socket_port = port;
}
int C_Config::getSocketPort()
{
return socket_port;
}
////
void C_Config::setBindAddr(std::string addr)
{
bindAddr = addr;
}
std::string C_Config::getBindAddr()
{
return bindAddr;
}
////
std::list<C_Host *> &C_Config::getHostsAuth()
{
return h_hosts;
}
......@@ -2,7 +2,7 @@
* config.c: mini-VideoLAN Channel Server, configuration system
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: config.h,v 1.5 2002/10/12 19:45:31 marcari Exp $
* $Id: config.h,v 1.6 2002/12/02 17:52:24 marcari Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Marc Ariberti <marcari@via.ecp.fr>
......@@ -23,33 +23,43 @@
*****************************************************************************/
typedef struct channel_s
{
char psz_vlc_config[256];
struct channel_s * next;
} channel_t;
class C_Config
{
public:
typedef enum { IPV4, IPV6 } inet_type;
C_Config(C_Logger &logger);
~C_Config();
void DestroyList( void );
void AddList( char * psz_item );
void AddList( std::string item );
time_t GetModificationTime( void );
void ReadFile( void );
channel_t * GetChannel( int i_channel );
std::string GetChannel( int i_channel );
void CheckUpdate( void );
int GetChannelNumber( void );
void SetConfigFile(char * psz_config_file);
void SetConfigFile(std::string psz_config_file);
void setInetType(inet_type t);
void setSocketPort(int port);
void setBindAddr(std::string addr);
inet_type getInetType();
int getSocketPort();
std::string getBindAddr();
std::list<C_Host *> &getHostsAuth();
static char * RemoveLF( char * str );
protected:
int i_channel_max;
C_Logger &logger;
char * m_pszConfigFile;
time_t st_mtime; /* last modification time of the config file */
channel_t * p_channels;
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;
inet_type socket_type;
std::string bindAddr;
int socket_port;
};
/*****************************************************************************
* socket.c: VideoLAN Channel Server network facilities
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: host.c,v 1.1 2002/12/02 17:52:25 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.
*****************************************************************************/
#include <string.h>
#include <arpa/inet.h>
#include <fstream>
#include <iostream>
#include "host.h"
static in_addr_t pton(std::string str)
{
struct in_addr addr;
inet_pton(AF_INET, str.c_str(), &addr);
return addr.s_addr;
}
C_Host::C_Host(char * config)
{
C_Host(*new std::string(config));
}
/**
* la chaine est du type : adresse/masque : 192.168.120.0/255.255.255.0
*/
C_Host::C_Host(std::string config)
{
int pos = config.find('/');
std::string sip;
std::string smask;
if (pos >= 0)
{
sip = config.substr(1, pos-1);
smask = config.substr(pos+1);
}
else
{
sip = config.substr(1);
smask = "255.255.255.255";
if (!sip.compare("all"))
{
sip = "0.0.0.0";
smask = "0.0.0.0";
}
}
if (config[0] == '+')
{
m_type = ALLOW;
str = "Allowing ";
}
else
{
m_type = DENY;
str = "Denying ";
}
addr = pton(sip);
mask = pton(smask);
str += "from " + sip + "/" + smask;
}
std::string C_Host::getStr()
{
return str;
}
bool C_Host::test(in_addr_t ip)
{
return ((ip & mask) == (addr & mask));
}
C_Host::type C_Host::getType()
{
return m_type;
}
/*****************************************************************************
* socket.h: VideoLAN Channel Server network facilities
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: host.h,v 1.1 2002/12/02 17:52:25 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_Host
{
public:
typedef enum { ALLOW, DENY } type;
C_Host(char * config);
// C_Host(char * config);
C_Host(std::string config);
bool test(in_addr_t ip);
// bool test(struct sockaddr_in sin);
// bool test(struct in_addr iaddr);
type getType();
std::string getStr();
protected:
std::string str;
in_addr_t addr;
in_addr_t mask;
type m_type;
};
......@@ -2,7 +2,7 @@
* logger.c: VideoLAN Channel Server logging facility
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: logger.c,v 1.6 2002/10/28 17:38:30 marcari Exp $
* $Id: logger.c,v 1.7 2002/12/02 17:52:25 marcari Exp $
*
* Authors: Marc Ariberti <marcari@via.ecp.fr>
*
......@@ -26,15 +26,18 @@
#include <sys/time.h>
#include <stdlib.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <errno.h>
#include <time.h>
#include <list>
#include <list>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include "host.h"
#include "vlcs.h"
#include "logger.h"
......
......@@ -2,7 +2,7 @@
* logger.h: VideoLAN Channel Server logging facility
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: logger.h,v 1.6 2002/10/28 17:38:30 marcari Exp $
* $Id: logger.h,v 1.7 2002/12/02 17:52:25 marcari Exp $
*
* Authors: Marc Ariberti <marcari@via.ecp.fr>
*
......@@ -31,6 +31,11 @@ public:
virtual C_Logger &operator<<(const char * msg) = 0;
virtual C_Logger &operator<<(int value) = 0;
virtual C_Logger &operator<<(log_command value) = 0;
virtual C_Logger &operator<<(std::string value)
{
*this << value.c_str();
return *this;
}
};
......
......@@ -2,7 +2,7 @@
* socket.c: VideoLAN Channel Server network facilities
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: socket.c,v 1.7 2002/10/28 17:38:30 marcari Exp $
* $Id: socket.c,v 1.8 2002/12/02 17:52:25 marcari Exp $
*
* Authors: Marc Ariberti <marcari@via.ecp.fr>
*
......@@ -30,16 +30,19 @@
#include <string.h>
#include <time.h>
#include <list>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include "host.h"
#include "vlcs.h"
#include "logger.h"
#include "config.h"
#include "socket.h"
C_Socket::C_Socket(C_Logger &logger) : i_handle(0), logger(logger)
C_Socket::C_Socket(C_Logger &logger)
: i_handle(0), logger(logger)
{
}
......@@ -52,14 +55,16 @@ void C_Socket::Close( int i_ret )
* C_IPv4Socket class implementation
*/
C_IPv4Socket::C_IPv4Socket(C_Logger &logger, int port, char * bind_addr )
throw (int) : C_Socket(logger)
C_IPv4Socket::C_IPv4Socket(C_Logger &logger, std::list<C_Host *> &hosts,
int port, std::string bind_addr) throw (int) : C_Socket(logger),
h_hosts(hosts)
{
int i_opt;
struct sockaddr_in sa_server;
struct in_addr s_bind_addr;
this->logger = logger;
i_handle = socket( AF_INET, SOCK_DGRAM, 0 );
......@@ -81,16 +86,16 @@ C_IPv4Socket::C_IPv4Socket(C_Logger &logger, int port, char * bind_addr )
sa_server.sin_family = AF_INET;
if ( bind_addr != NULL )
if ( !bind_addr.empty() )
{
inet_aton(bind_addr, &s_bind_addr);
inet_aton(bind_addr.c_str(), &s_bind_addr);
sa_server.sin_addr.s_addr = s_bind_addr.s_addr;
}
else
{
sa_server.sin_addr.s_addr = INADDR_ANY;
}
sa_server.sin_port = ntohs( VLCS_PORT );
sa_server.sin_port = ntohs( port );
if( bind( i_handle, (struct sockaddr *)&sa_server, sizeof(sa_server) ) < 0 )
{
logger << C_Logger::ALERT << "Cannot bind (" << strerror(errno) << "), exiting"
......@@ -107,17 +112,17 @@ int C_IPv4Socket::Receive( char * p_buffer, int buffer_len )
(struct sockaddr *)&m_sa_client, &i_dummy);
}
void C_IPv4Socket::Reply( char * psz_message )
void C_IPv4Socket::Reply( std::string message )
{
time_t tm;
time(&tm);
/* TODO: remove this ugly kludge */
logger << C_Logger::INFO << C_Config::RemoveLF( asctime( localtime( &tm ))) << " : "
<< Ntop( ) << " => " << psz_message << C_Logger::END;
<< Ntop( ) << " => " << message << C_Logger::END;
for( ; ; )
{
if( sendto( i_handle, psz_message, strlen( psz_message ) + 1, 0,
if( sendto( i_handle, message.c_str(), message.length() + 1, 0,
(struct sockaddr *)&m_sa_client,
sizeof( struct sockaddr_in ) ) < 0 )
{
......@@ -135,12 +140,38 @@ const char * C_IPv4Socket::Ntop( void )
{
return inet_ntop(AF_INET, &(m_sa_client.sin_addr), str, sizeof(str));
}
bool C_IPv4Socket::isAllowed()
{
std::list<C_Host *>::iterator host = h_hosts.begin();
while (host != h_hosts.end())
{
if ((*host)->test(m_sa_client.sin_addr.s_addr))
{
if ((*host)->getType() == C_Host::ALLOW)
{
return true;
}
else
{
logger << C_Logger::WARNING << "Break in attempt from "
<< Ntop() << C_Logger::END;
return false;
}
}
++host;
}
return true;
}
#ifdef IPV6_SUPPORT
/**
* C_IPv6Socket class implementation
*/
C_IPv6Socket::C_IPv6Socket(C_Logger &logger, int port, char * bind_addr )
throw (int) : C_Socket(logger)
C_IPv6Socket::C_IPv6Socket(C_Logger &logger,
int port, std::string bind_addr ) throw (int) : C_Socket(logger)
{
int i_opt;
struct sockaddr_in6 sa_server;
......@@ -168,9 +199,9 @@ C_IPv6Socket::C_IPv6Socket(C_Logger &logger, int port, char * bind_addr )
sa_server.sin6_family = AF_INET6;
if ( bind_addr != NULL )
if ( !bind_addr.empty() )
{
inet_pton(AF_INET6, bind_addr, &s_bind_addr);
inet_pton(AF_INET6, bind_addr.c_str(), &s_bind_addr);
memcpy(sa_server.sin6_addr.s6_addr, s_bind_addr.s6_addr,
sizeof(s_bind_addr.s6_addr));
}
......@@ -178,7 +209,7 @@ C_IPv6Socket::C_IPv6Socket(C_Logger &logger, int port, char * bind_addr )
{
sa_server.sin6_addr = in6addr_any;
}
sa_server.sin6_port = ntohs( VLCS_PORT );
sa_server.sin6_port = ntohs( port );
if( bind( i_handle, (struct sockaddr *)&sa_server, sizeof(sa_server) ) < 0 )
{
logger << C_Logger::ALERT << "Cannot bind (" << strerror(errno) << "), exiting"
......@@ -195,18 +226,18 @@ int C_IPv6Socket::Receive( char * p_buffer, int buffer_len )
(struct sockaddr *)&m_sa_client, &i_dummy);
}
void C_IPv6Socket::Reply( char * psz_message )
void C_IPv6Socket::Reply( std::string message )
{
time_t tm;
time(&tm);
/* TODO: remove this ugly kludge */
logger << C_Logger::INFO << C_Config::RemoveLF( asctime( localtime( &tm ))) << " : "
<< Ntop( ) << " => " << psz_message << C_Logger::END;
<< Ntop( ) << " => " << message << C_Logger::END;
for( ; ; )
{
if( sendto( i_handle, psz_message, strlen( psz_message ) + 1, 0,
if( sendto( i_handle, message.c_str(), message.length() + 1, 0,
(struct sockaddr *)&m_sa_client,
sizeof( struct sockaddr_in6 ) ) < 0 )
{
......@@ -224,3 +255,10 @@ const char * C_IPv6Socket::Ntop( void )
{
return inet_ntop(AF_INET6, &(m_sa_client.sin6_addr), str, sizeof(str));
}
bool C_IPv6Socket::isAllowed()
{
return true;
}
#endif // IPV6
......@@ -2,7 +2,7 @@
* socket.h: VideoLAN Channel Server network facilities
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: socket.h,v 1.5 2002/06/09 17:56:17 marcari Exp $
* $Id: socket.h,v 1.6 2002/12/02 17:52:25 marcari Exp $
*
* Authors: Marc Ariberti <marcari@via.ecp.fr>
*
......@@ -26,39 +26,47 @@ class C_Socket
public:
C_Socket(C_Logger &logger);