Commit b44429ae authored by Damien Lucas's avatar Damien Lucas

. Added first part of the interface

  ie beginning of a telnetd interface (working but no login check ...
  no buffer overflow known in the telnet

. Changed few things in snmp (but did not correct the desktop bug)
. Splited functions the snmp.c file, creating callback.c.
parent 77edc067
......@@ -62,9 +62,12 @@ SOURCES = \
db/db.c \
snmp/snmp.c \
snmp/if_snmp.c \
snmp/callback.c \
main.c \
types.c \
logger.c \
interface/interface.c\
interface/telnet.c\
OBJECTS = $(SOURCES:%.c=%.o)
......@@ -108,6 +111,7 @@ $(LEXOBJECTS): %.o: deps/%.d
@echo "Compiling $*.c"
@$(CC) $(CFLAGS) -c -o $@ $*.c
$(LEXCFILES): %.c: %.fl
@echo "Running flex for generation of $*.fl"
@$(LEX) $(LEXFLAGS) -o$@ $<
......
(snmp 1): EASY
Gérer les numéros de ports de la meme manière que les vlans et non
(snmp 1): possible GPA
Gérer les numéros de ports de la même manière que les vlans et non
avec ce putain de #define
(snmp 7):
......@@ -15,7 +15,7 @@
(logger 1):
Wrapper les lignes à 80 car.
(logger 2):
(logger 3):
Ecrire la fonction d'affichage, et une queue de manière à ne pas pouvoir
avoir 2 printf simultanés.
......
#include<stdio.h>
#include<pthread.h>
#include "../types.h"
#include "../logger.h"
#include "telnet.h"
#include "interface.h"
ERR_CODE IF_start(void)
{
pthread_t iftelnet;
VS_log(LOGINFO,IF,"Creating the Interface..");
if (pthread_create(&iftelnet,NULL,IF_telnet,NULL))
{
return VS_R_PTHREAD;
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "../types.h"
#include "../logger.h"
#include "./telnet.h"
#define PORT 7891
#define SERVER "138.195.138.42"
#define MAXCONNECTIONS 20 // how many connections are queued
/* TELNET Interface */
#define WELCOME "\nVideoLAN Channel Server Administration System\n"
#define LOGIN "Login: "
#define PASSWD "Password: "
#define PROMPT "@CHANNELServer # "
#define MAX_LOGIN_SIZE 8
/* TELNET Protocol Constants */
#define IAC 255 // Interpret As Command
#define DONT 254 // You are not to use option
#define DO 253 // Please use option
#define WONT 252 // I won't use option
#define WILL 251 // I will use option
#define EC 247 // Erase the current character
#define EL 248 // Erase the current line
#define TELOPT_ECHO 1 // Echo
#define TELOPT_SGA 3 // Suppress go ahead
#define TELOPT_OUTMRK 27 // Output marking
#define TELOPT_LINEMODE 34 // Linemode option
#define KEY_UP 65
#define KEY_DOWN 66
#define KEY_LEFT 67
#define KEY_RIGHT 68
/* Telnet module definition */
#define CONFIG_MODE 1
#define CONTROL_MODE 2
#define INTERACTIVE_MODE 3
#define INIT_PHASE 1
#define LOGIN_PHASE 2
#define PASSWD_PHASE 3
#define COMMAND_PHASE 4
#define HISTORY_SIZE 20
void* IF_telnet(void* ar)
{
int sock,newsock ;
struct sockaddr_in addr;
struct sockaddr_in incoming;
char* sUser;
int size;
unsigned int stop;
int rc;
stop=0;
size=sizeof(struct sockaddr_in);
/* Initialization */
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock==-1)
{
VS_log(LOGERROR,TELNET,"Error creating socket !");
return NULL;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(SERVER);
bzero(&(addr.sin_zero),8);
rc=bind(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr));
if(rc==-1)
{
VS_log(LOGERROR,TELNET,"Unable to bind socket");
return NULL;
}
rc=listen(sock,MAXCONNECTIONS);
if(rc==-1)
{
VS_log(LOGERROR,TELNET,"Unable to listen to the socket");
return NULL;
}
/* New connection */
while(1)
{
newsock=accept(sock,&incoming,&size);
IF_telnet_init(newsock);
sUser=IF_telnet_login(newsock);
if(sUser!=NULL)
{
IF_telnet_commands(newsock,sUser);
}
close(newsock);
}
return NULL;
}
void IF_telnet_init(int isocket)
{
VS_log(LOGDEBUG, TELNET, "Connection attempt");
/* Send the Welcome message */
Message_send(isocket, WELCOME, strlen(WELCOME));
/* Need to negociate Terminal ... */
Request_send(isocket, WILL, TELOPT_ECHO);
Request_send(isocket, WILL, TELOPT_SGA);
Request_send(isocket, DONT, TELOPT_LINEMODE);
}
char* IF_telnet_login (int iSocket)
{
char* sUser;
char* sPasswd;
sUser=NULL;
sPasswd=NULL;
Message_send(iSocket, LOGIN, strlen(LOGIN));
sUser=Catch_Word(iSocket);
if(sUser!=NULL)
{
if(!strcmp(sUser,"gunther"))
{
Message_send(iSocket,"...... CTFLB......\n",19);
return NULL;
}
else
{
Message_send(iSocket, PASSWD, strlen(PASSWD));
sPasswd=Catch_Passwd(iSocket);
if(sPasswd != NULL)
{
VS_log(LOGDEBUG,TELNET, "Connection opened for %s/%s",sUser,sPasswd);
/* TODO Add an authentification here */
free(sPasswd);
}
}
}
return sUser;
}
void IF_telnet_commands (int iSocket, char* sUser)
{
char* sCmd;
unsigned int uStop;
struct IF_Menu mMenu;
struct IFT_Command* z;
uStop=0;
z=NULL;
while(!uStop)
{
Menu_init(&mMenu);
Menu_send(iSocket,mMenu);
Prompt_send(iSocket,sUser);
sCmd=Catch_Word(iSocket);
for(z=mMenu.Command;z!=NULL;z=z->next)
{
if(!strcmp(sCmd,z->sName))
{
uStop=1;
}
}
free(sCmd);
}
}
void Menu_init (struct IF_Menu* mMenu)
{
mMenu->Command=malloc(sizeof(struct IFT_Command));
mMenu->Command->iIndex='0';
sprintf(mMenu->Command->sName,"logout");
sprintf(mMenu->Command->sDescr,"Close the current connection");
mMenu->Command->next=NULL;
}
void Menu_send (int iSocket, struct IF_Menu mMenu)
{
struct IFT_Command* z;
Message_send(iSocket,"\r\n",2);
Message_send(iSocket,
"------------------------- VLCS menu ------------------------------\r\n",68);
for(z=mMenu.Command; z!=NULL; z=z->next)
{
Message_send(iSocket,&(z->iIndex), 1);
Message_send(iSocket," - ",8);
Message_send(iSocket,z->sName,strlen(z->sName));
Message_send(iSocket," - ",21-strlen(z->sName));
Message_send(iSocket,z->sDescr,strlen(z->sDescr));
Message_send(iSocket,"\r\n",2);
}
}
void Request_send (int iSocket, char bAction, char bOption)
{
unsigned char req[3];
req[0]=IAC;
req[1]=bAction;
req[2]=bOption;
write(iSocket, req, 3);
}
char* Catch_Passwd (int iSocket)
{
unsigned char bBuff;
char* sData;
int iPos;
sData=malloc(300*sizeof(char));
if(sData==NULL)
{
VS_log(LOGERROR,TELNET,"Unable to allocate memory");
return NULL;
}
iPos=0;
while(iPos<254)
{
read(iSocket, &bBuff,1);
switch(bBuff)
{
case IAC:
read(iSocket, &bBuff,2);
break; //TODO Terminal negociation
case '\r':
sData[iPos]='\0';
read(iSocket, &bBuff,1); //Need to read next byte: should be \n
Message_send(iSocket,"\r\n",2);
return sData;
default:
sData[iPos]=bBuff;
iPos++;
break;
}
}
return NULL;
}
char* Catch_Word (int iSocket)
{
unsigned char bBuff;
char* sData;
int iPos;
sData=malloc(300*sizeof(char));
iPos=0;
while(iPos<254)
{
read(iSocket, &bBuff,1);
switch(bBuff)
{
case IAC:
read(iSocket, &bBuff,2);
break; //TODO Terminal negociation
case '\r':
sData[iPos]='\0';
read(iSocket, &bBuff,1); //Need to read next byte: should be \n
Message_send(iSocket,"\r\n",2);
return sData;
default:
sData[iPos]=bBuff;
iPos++;
Message_send(iSocket,&bBuff,1);
break;
}
}
return NULL;
}
void Message_send (int iSocket, char* sMessage, size_t size)
{
write(iSocket, sMessage,size);
}
void Prompt_send (int iSocket, char* sUser)
{
Message_send(iSocket,"\r\n",2);
Message_send(iSocket, sUser,strlen(sUser));
Message_send(iSocket, PROMPT,strlen(PROMPT));
}
struct IF_Menu
{
struct IFT_Command *Command;
};
struct IFT_Command
{
unsigned char iIndex;
char sName[17];
char sDescr[40];
struct IFT_Command* next;
};
void* IF_telnet(void* ar);
void IF_telnet_init(int isocket);
char* IF_telnet_login (int isocket);
void IF_telnet_commands (int iSocket, char* sUser);
void Menu_init (struct IF_Menu* mMenu);
void Menu_send (int iSocket, struct IF_Menu mMenu);
void Request_send (int iSocket, char bAction, char bOption);
void Message_send (int iSocket, char* sMessage, size_t size);
char* Catch_Word (int iSocket);
char* Catch_Passwd (int iSocket);
void Prompt_send (int iSocket, char* sUser);
#include <stdlib.h>
#include <string.h>
//#include <sys/time.h>
#include <errno.h>
//#include <unistd.h>
#include "../types.h"
#include "../logger.h"
#include "snmp_switch.h"
#include "callback.h"
/* Functions for the snmp */
struct snmp_pdu * snmp_pdu_create (int command);
void sprint_variable (char *, oid *,size_t, struct variable_list *);
struct variable_list* snmp_add_null_var (struct snmp_pdu *, oid *, size_t);
/* TODO Write a walk in order to have this table for each switch */
#define Snmp_PORT(x) ( (x)+100 )
#define PORT_Snmp(x) ( (x)-100 )
/******************************************************************************
* Callback_Vlans() *
******************************************************************************
* Treat the pdu in order to get the VLAN of a port *
* And put it in the struct zwitch *
* And send the GETNEXT packet if the walk is not at the end *
******************************************************************************/
inline static void Callback_Vlans(struct snmp_session *session,
struct SNMP_switch *zwitch,
struct snmp_pdu *pdu)
{
char buffer[SPRINT_MAX_LEN];
struct snmp_pdu *pdusend;
unsigned long long int vlan;
unsigned int port;
session->sessid++;
zwitch->walk_vlans.session_num++;
sprint_variable(buffer,pdu->variables->name,pdu->variables->name_length,\
pdu->variables);
/* Test if the walk is at the end */
if(!memcmp(buffer, zwitch->walk_vlans.stop,zwitch->walk_vlans.stop_size))
{
/* Need to operate on received pdu
* ifMIB.ifMIBObjects.ifStackTable.ifStackEntry.ifStackStatus.P.V
* ^59 */
switch(zwitch->type)
{
case VS_ST_3C1000:
case VS_ST_3C1100:
case VS_ST_3C3300:
if(sscanf(buffer+59,"%Lu.%u = active(1)",&vlan,&port)==2)
{
if (port<Snmp_PORT(zwitch->nb_ports)+1&&port>100)
{
zwitch->ports[PORT_Snmp(port)].vlan=vlan;
}
}
break;
}
/* Need to send the next request */
pdusend=(struct snmp_pdu *)snmp_pdu_create(SNMP_MSG_GETNEXT);
if(pdusend==NULL)
{
VS_log(LOGERROR,SNMP,"Unable to create the pdu");
return ;
}
if(!snmp_add_null_var(pdusend,pdu->variables->name,\
pdu->variables->name_length))
{
VS_log(LOGERROR,SNMP,"Unable to complete pdu in PORT searching");
return ;
}
if (!snmp_send(session,pdusend))
{
VS_log(LOGERROR,SNMP,"Unable to send the pdu");
snmp_free_pdu(pdusend);
return ;
}
}
else
{
/* Need to stop walking */
zwitch->walk_table.session_num=0;
return ;
}
}
/******************************************************************************
* Callback_Vlanids() *
******************************************************************************
* Treat the pdu in order to get the VLANid of a VLAN *
* And put it in the struct zwitch *
* And send the GETNEXT packet if the walk is not at the end *
******************************************************************************/
inline static void Callback_Vlanid(struct snmp_session *session,
struct SNMP_switch *zwitch,
struct snmp_pdu *pdu)
{
char buffer[SPRINT_MAX_LEN];
char sarass[64];
struct snmp_pdu *pdusend;
unsigned long long int vlan;
int res;
unsigned int i;
zwitch->walk_table.session_num++;
session->sessid++;
sprint_variable(buffer,pdu->variables->name,pdu->variables->name_length,\
pdu->variables);
/* Test if the walk is at the end */
if(!memcmp(buffer,zwitch->walk_table.stop,zwitch->walk_table.stop_size))
{
/* Need to operate on received pdu
* interfaces.ifTable.ifEntry.ifDescr.port = RMON VLAN 1
* ^35 */
switch(zwitch->type)
{
case VS_ST_3C1000:
res=sscanf(buffer+35,"%Lu = RMON:VLAN %u:%s",&vlan,&i,sarass);
if(res>=2)
{
zwitch->vlanid[i]=vlan;
}
break;
case VS_ST_3C1100:
if(sscanf(buffer+35,"%Lu = RMON VLAN %u",&vlan,&i)==2)
{
zwitch->vlanid[i]=vlan;
}
break;
case VS_ST_3C3300:
if(sscanf(buffer+35,"%Lu = RMON VLAN %u",&vlan,&i)==2)
{
zwitch->vlanid[i]=vlan;
}
break;
}
/* Need to send the next request */
pdusend=(struct snmp_pdu *)snmp_pdu_create(SNMP_MSG_GETNEXT);
if(pdusend==NULL)
{
VS_log(LOGERROR,SNMP,"Unable to create the pdu");
return;
}
if(!snmp_add_null_var(pdusend,pdu->variables->name,\
pdu->variables->name_length))
{
VS_log(LOGERROR,SNMP,"Unable to complete pdu in VLAN searching");
return;
}
if (!snmp_send(session,pdusend))
{
VS_log(LOGERROR,SNMP,"Unable to send the pdu");
snmp_free_pdu(pdusend);
return;
}
}
else
{
/* Need to stop walking */
zwitch->walk_table.session_num=0;
return;
}
}
/******************************************************************************
* Callback_Macs() *
******************************************************************************
* Treat the pdu in order to get one the MAC of a port *
* And put it in the struct zwitch *
* And send the GETNEXT packet if the walk is not at the end *
******************************************************************************/
inline static void Callback_Macs(struct snmp_session *session,
struct SNMP_switch *zwitch,
struct snmp_pdu *pdu)
{
char buffer[SPRINT_MAX_LEN];
struct snmp_pdu *pdusend;
unsigned long long int mac,i2;
unsigned int i3,i4,i5,i6;
unsigned int port;
session->sessid++;
zwitch->walk_macs.session_num++;
sprint_variable(buffer,pdu->variables->name,pdu->variables->name_length,\
pdu->variables);
/* Test if the walk is at the end */
if(!memcmp(buffer, zwitch->walk_macs.stop,zwitch->walk_macs.stop_size))
{
/* Need to operate on received pdu
* enterprises.43.10.22.2.1.3.1.port.i1.i2.i3...
* ^ 29 */
if(sscanf(buffer+29,"%u.%Lu.%Lu.%u.%u.%u.%u",&port,&mac,
&i2,&i3,&i4,&i5,&i6)!=7)
{
VS_log(LOGERROR,SNMP,"Bad snmp GETRESPONSE");
(*zwitch->walk_macs.machine)->next=NULL;
for(i3=zwitch->walk_macs.last_port+1;i3<=zwitch->nb_ports;i3++)
{
zwitch->machines[i3]=NULL;
}
zwitch->walk_macs.session_num=0;
return ;
}
mac<<=8; mac|=i2;
mac<<=8; mac|=i3;
mac<<=8; mac|=i4;
mac<<=8; mac|=i5;
mac<<=8; mac|=i6;
*zwitch->walk_macs.machine=malloc(sizeof(struct SNMP_machines_elt));
if(*zwitch->walk_macs.machine==NULL)
{
VS_log(LOGERROR,SNMP,"Unable to allocate memory");
for(i3=zwitch->walk_macs.last_port+1;i3<=zwitch->nb_ports;i3++)
{
zwitch->machines[i3]=NULL;
}
zwitch->walk_macs.session_num=0;
return ;
}
if(port==zwitch->walk_macs.last_port)
{
(*zwitch->walk_macs.machine)->machine=(VS_MachineId)mac;
zwitch->walk_macs.machine=&(*zwitch->walk_macs.machine)->next;
}
else
{
(*zwitch->walk_macs.machine)=NULL;
for(i3=zwitch->walk_macs.last_port+1;i3<port;i3++)
{
zwitch->machines[i3]=NULL;
}
zwitch->walk_macs.machine=zwitch->machines+i3;
*zwitch->walk_macs.machine=malloc(sizeof(struct SNMP_machines_elt));
zwitch->walk_macs.last_port=port;
(*zwitch->walk_macs.machine)->machine=(VS_MachineId)mac;
zwitch->walk_macs.machine=&(*zwitch->walk_macs.machine)->next;
}
/* Need to send the next request */
pdusend=(struct snmp_pdu *)snmp_pdu_create(SNMP_MSG_GETNEXT);
if(pdusend==NULL)
{
VS_log(LOGERROR,SNMP,"Unable to create the new pdu");
return ;
}
if(!snmp_add_null_var(pdusend,pdu->variables->name,\
pdu->variables->name_length))
{
VS_log(LOGERROR,SNMP,"Unable to complete pdu in MAC searching");
*zwitch->walk_macs.machine=NULL;
for(i3=zwitch->walk_macs.last_port+1;i3<=zwitch->nb_ports;i3++)
{
zwitch->machines[i3]=NULL;
}
zwitch->walk_macs.session_num=0;
return ;
}
if (!snmp_send(session,pdusend))
{
VS_log(LOGERROR,SNMP,"Unable to send the pdu");
snmp_free_pdu(pdusend);
*zwitch->walk_macs.machine=NULL;
for(i3=zwitch->walk_macs.last_port+1;i3<=zwitch->nb_ports;i3++)
{
zwitch->machines[i3]=NULL;
}
zwitch->walk_macs.session_num=0;
return ;
}
}
else
{
/* Need to stop walking */
zwitch->walk_macs.session_num=0;
/* complete the MAC table */
*zwitch->walk_macs.machine=NULL;
for(i3=zwitch->walk_macs.last_port+1;i3<=zwitch->nb_ports;i3++)
{
zwitch->machines[i3]=NULL;
}
return ;
}
}