From c0b6f303dc51a1668881b3c59eb2c0c02d9c56e4 Mon Sep 17 00:00:00 2001 From: alonso Date: Tue, 5 May 2009 14:18:43 +0000 Subject: [PATCH] git-svn-id: https://opengnsys.es/svn/trunk@43 a21b9725-9963-47de-94b9-378ad31fedc9 --- Hidra/hidraboot/fuentes/hidraboot.cpp | 1287 ++++++++++ Hidra/hidraboot/fuentes/hidraboot.h | 278 +++ Hidra/hidrac/fuentes/hidrac.c | 2096 +++++++++++++++++ Hidra/hidrac/fuentes/hidrac.h | 289 +++ Hidra/hidrarepos/fuentes/hidrarepos.cpp | 1159 +++++++++ Hidra/hidrarepos/fuentes/hidrarepos.h | 131 ++ Hidra/webhidra/barramenu.php | 14 +- Hidra/webhidra/controlacceso.php | 4 +- .../idiomas/php/esp/barramenu_esp.php | 8 +- .../esp/informacion_procedimientos_esp.php | 6 +- Hidra/webhidra/principal/acciones.php | 29 +- .../varios/informacion_procedimientos.php | 17 +- 12 files changed, 5280 insertions(+), 38 deletions(-) create mode 100644 Hidra/hidraboot/fuentes/hidraboot.cpp create mode 100644 Hidra/hidraboot/fuentes/hidraboot.h create mode 100644 Hidra/hidrac/fuentes/hidrac.c create mode 100644 Hidra/hidrac/fuentes/hidrac.h create mode 100644 Hidra/hidrarepos/fuentes/hidrarepos.cpp create mode 100644 Hidra/hidrarepos/fuentes/hidrarepos.h diff --git a/Hidra/hidraboot/fuentes/hidraboot.cpp b/Hidra/hidraboot/fuentes/hidraboot.cpp new file mode 100644 index 00000000..80ab1eef --- /dev/null +++ b/Hidra/hidraboot/fuentes/hidraboot.cpp @@ -0,0 +1,1287 @@ +// ************************************************************************************************************* +// Aplicacin HIDRA +// Copyright 2003-2005 Jos Manuel Alonso. Todos los derechos reservados. +// Fichero: hidrabootp.cpp +// +// Descripcin: +// Este fichero implementa el servicio dhcp para la aplicacin hidra, en un ordenador con plataforma windows NT. +// ************************************************************************************************************** +#include "hidraboot.h" +#include "encriptacion.c" +// ________________________________________________________________________________________________________ +// Funcin�: RegistraLog +// +// Descripcin�: +// Esta funcin� registra los evento de errores en un fichero log +// Parametros: +// - msg : Mensage de error +// - swerrno: Switch que indica que recupere literal de error del sistema +// ________________________________________________________________________________________________________ +void RegistraLog(char *msg,int swerrno) +{ + struct tm * timeinfo; + timeinfo = TomaHora(); + + FLog=fopen(szPathFileLog,"at"); + if(swerrno) + fprintf (FLog,"%02d/%02d/%d %02d:%02d ***%s:%s\n",timeinfo->tm_mday,timeinfo->tm_mon+1,timeinfo->tm_year+1900,timeinfo->tm_hour,timeinfo->tm_min,msg,strerror(errno)); + else + fprintf (FLog,"%02d/%02d/%d %02d:%02d ***%s\n",timeinfo->tm_mday,timeinfo->tm_mon+1,timeinfo->tm_year+1900,timeinfo->tm_hour,timeinfo->tm_min,msg); + fclose(FLog); +} +// ________________________________________________________________________________________________________ +// Funcin�: TomaHora +// +// Descripcin�: +// Esta funcin� toma la hora actual del sistema y devuelve una estructura conlos datos +// Parametros: +// - msg : Mensage de error +// - swerrno: Switch que indica que recupere literal de error del sistema +// ________________________________________________________________________________________________________ +struct tm * TomaHora() +{ + time_t rawtime; + time ( &rawtime ); + return(gmtime(&rawtime)); +} +//________________________________________________________________________________________________________ +// +// Funcin: TomaConfiguracion +// +// Descripcin: +// Esta funcin lee el fichero de configuracin del programa hidralinuxcli y toma los parametros +// Parametros: +// - pathfilecfg : Ruta al fichero de configuracin +//________________________________________________________________________________________________________ +int TomaConfiguracion(char* pathfilecfg) +{ + long lSize; + char * buffer,*lineas[100],*dualparametro[2]; + char ch[2]; + int i,numlin,resul; + + if(pathfilecfg==NULL) return(FALSE); // Nombre del fichero en blanco + + Fconfig = fopen ( pathfilecfg , "rb" ); + if (Fconfig==NULL) return(FALSE); + fseek (Fconfig , 0 , SEEK_END); // Obtiene tamaño del fichero. + lSize = ftell (Fconfig); + rewind (Fconfig); + buffer = (char*) malloc (lSize); // Toma memoria para el buffer de lectura. + if (buffer == NULL) return(FALSE); + fread (buffer,1,lSize,Fconfig); // Lee contenido del fichero + fclose(Fconfig); + + //inicializar + IPlocal[0]=(char)NULL; + usuario[0]=(char)NULL; + pasguor[0]=(char)NULL; + datasource[0]=(char)NULL; + catalog[0]=(char)NULL; + + strcpy(ch,"\n");// caracter delimitador ( salto de linea) + numlin=split_parametros(lineas,buffer,ch); + for (i=0;isockaddrsize = sizeof(trmInfo->cliente); + trmInfo->sck=socket_s; + // Espera tramas DHCP + ret = recvfrom(trmInfo->sck,(char *)&trmInfo->pckDchp, sizeof(trmInfo->pckDchp),0,(struct sockaddr *)&trmInfo->cliente, &trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***Error al recibir mensaje DHCP. Se para el servicio",true); + return(FALSE); + } + else{ + if (ret>0){ + resul=pthread_create(&hThread,NULL,GestionaServicioDHCP,(LPVOID)trmInfo); + if(resul!=0){ + RegistraLog("***Fallo al crear la hebra cliente DHCP",false); + return(FALSE); + } + pthread_detach(hThread); + } + } + } + close(socket_s); +} +// _____________________________________________________________________________________________________________ +// Funcin: ServicioBOOTP +// +// Descripcin: +// Esta hebra despacha el servicio BOOTP +// _____________________________________________________________________________________________________________ + +LPVOID ServicioBOOTP(LPVOID iplocal) +{ + SOCKET socket_s; // Socket donde escucha el servidor + struct TramaDhcpBootp * trmInfo; + struct sockaddr_in local; + int ret,resul; + pthread_t hThread; + + socket_s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Crea socket para UDP + if (socket_s == SOCKET_ERROR){ + RegistraLog("***Error al crear socket para servicio BOOTP:",true); + return(FALSE); + } + local.sin_addr.s_addr = htonl(INADDR_ANY); // selecciona interface + local.sin_family = AF_INET; + local.sin_port = htons(PUERTOBOOTPORIGEN); // Puerto + + // Enlaza socket + if (bind(socket_s,(struct sockaddr *)&local,sizeof(local)) == SOCKET_ERROR){ + RegistraLog("***Error al enlazar socket con interface para servicio BOOTP",true); + return(FALSE); + } + while(true){ + trmInfo = (struct TramaDhcpBootp*)malloc(sizeof(struct TramaDhcpBootp)); // Crea estructura de control para hebra + if (trmInfo == NULL){ + RegistraLog("***Fallo al crear estructura de control para protocolo TFTP",false); + return(FALSE); + } + // Inicializa parmetros + memset(trmInfo,0,sizeof(struct TramaDhcpBootp)); + trmInfo->sockaddrsize = sizeof(trmInfo->cliente); + trmInfo->sck=socket_s; + // Espera tramas BOOTP + ret = recvfrom(trmInfo->sck,(char *)&trmInfo->pckDchp, sizeof(trmInfo->pckDchp),0,(struct sockaddr *)&trmInfo->cliente, &trmInfo->sockaddrsize); + + if (ret == SOCKET_ERROR){ + RegistraLog("***Error al recibir mensaje BOOTP. Se para el servicio",true); + return(FALSE); + } + else{ + if (ret>0){ + resul=pthread_create(&hThread,NULL,GestionaServicioBOOTP,(LPVOID)trmInfo); + if(resul!=0){ + RegistraLog("***Fallo al crear la hebra cliente BOOTP",false); + return(FALSE); + } + pthread_detach(hThread); + } + } + } + close(socket_s); +} +// _____________________________________________________________________________________________________________ +// Funcin: ServicioTFTP +// +// Descripcin: +// Esta hebra despacha el servicio TFTP +// _____________________________________________________________________________________________________________ + +LPVOID ServicioTFTP(LPVOID ipl) +{ + SOCKET socket_s; // Socket donde escucha el servidor + struct TramaTftp * trmInfo; + struct sockaddr_in local; + pthread_t hThread; + int ret,resul; + + socket_s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Crea socket para UDP + if (socket_s == SOCKET_ERROR){ + RegistraLog("***Error al crear socket para servicio TFTP:",true); + return(FALSE); + } + local.sin_addr.s_addr = htonl(INADDR_ANY); // selecciona interface + local.sin_family = AF_INET; + local.sin_port = htons(PUERTOTFTPORIGEN); // Puerto + + // Enlaza socket + if (bind(socket_s,(struct sockaddr *)&local,sizeof(local)) == SOCKET_ERROR){ + RegistraLog("***Error al enlazar socket con interface para servicio TFTP",true); + return(FALSE); + } + while(true){ + trmInfo = (struct TramaTftp*)malloc(sizeof(struct TramaTftp)); // Crea estructura de control para hebra + if (trmInfo == NULL){ + RegistraLog("***Fallo al crear estructura de control para protocolo TFTP",false); + return(FALSE); + } + memset(trmInfo,0,sizeof(struct TramaTftp)); + trmInfo->sockaddrsize = sizeof(trmInfo->cliente); + // Espera tramas TFTP + ret = recvfrom(socket_s,(char *)&trmInfo->pckTftp, sizeof(trmInfo->pckTftp),0,(struct sockaddr *)&trmInfo->cliente,&trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***Error al recibir mensaje TFTPP. Se para el servicio",true); + return(FALSE); + } + else{ + if (ret>0){ + resul=pthread_create(&hThread,NULL,GestionaServicioTFTP,(LPVOID)trmInfo); + if(resul!=0){ + RegistraLog("***Fallo al crear la hebra cliente TFTP",false); + return(FALSE); + } + pthread_detach(hThread); + } + } + + } + close(socket_s); +} +//_______________________________________________________________________________________________________________ +// +// Gestiona la conexion con un cliente que sea Hidra para el servicio DHCP +// Parmetros: +// lpParam: Puntero a la estructura de control para la conversacion DHCP +//_______________________________________________________________________________________________________________ +LPVOID GestionaServicioDHCP(LPVOID lpParam) +{ + struct TramaDhcpBootp * trmInfo=(struct TramaDhcpBootp *)lpParam; + char IPCliente[16]; // Ip del cliente + char MACCliente[16]; // Mac del cliente + + if(!OpcionesPresentes(trmInfo->pckDchp.magiccookie)) // Comprueba que existen opciones en la trama Dhcp + return(false); + strcpy(IPCliente,inet_ntoa(trmInfo->cliente.sin_addr)); + if(strcmp(IPCliente,"0.0.0.0")!=0){ // El cliente tiene una IP concreta distinta de 0.0.0.0 + if(!ClienteExistente(trmInfo,IPCliente,1)){ // Comprueba que se trata de un cliente Hidra + free(trmInfo); + return(false); + } + } + else{ + sprintf(MACCliente,"%02.2x%02.2x%02.2x%02.2x%02.2x%02.2x",(unsigned int)trmInfo->pckDchp.chaddr[0],(unsigned int)trmInfo->pckDchp.chaddr[1],(unsigned int)trmInfo->pckDchp.chaddr[2],(unsigned int)trmInfo->pckDchp.chaddr[3],(unsigned int)trmInfo->pckDchp.chaddr[4],(unsigned int)trmInfo->pckDchp.chaddr[5]); + if(!ClienteExistente(trmInfo,MACCliente,0)){ // Comprueba que se trata de un cliente Hidra (Por la Mac) + free(trmInfo); + return(false); + } + } + if(OpcionPXEClient(&trmInfo->pckDchp)) // Comprueba que sea un cliente PXE + ProcesaTramaClientePXE(trmInfo); // Procesa DHCP para el protocolo PXE + else + ProcesaTramaClienteDHCP(trmInfo); // Procesa DHCP de cliente Windows o Linux + + free(trmInfo); + return(false); +} +//_______________________________________________________________________________________________________________ +// +// Gestiona la conexion con un cliente que sea Hidra para el servicio BOOTP +// Parmetros: +// lpParam: Puntero a la estructura de control para la conversacion BOOTP +//_______________________________________________________________________________________________________________ +LPVOID GestionaServicioBOOTP(LPVOID lpParam) +{ + struct TramaDhcpBootp * trmInfo=(struct TramaDhcpBootp *)lpParam; + char IPCliente[16]; // Ip del cliente + + if(!OpcionesPresentes(trmInfo->pckDchp.magiccookie)) // Comprueba que existen opciones en la trama Dhcp + return(false); + + strcpy(IPCliente,inet_ntoa(trmInfo->cliente.sin_addr)); + if(!ClienteExistente(trmInfo,IPCliente,1)) // Comprueba que se trata de un cliente Hidra + return(false); + + if(OpcionPXEClient(&trmInfo->pckDchp)) // Comprueba que sea un cliente PXE + ProcesaTramaClienteBOOTP(trmInfo); // Procesa DHCP para el protocolo PXE + + free(trmInfo); + return(trmInfo); +} +//_______________________________________________________________________________________________________________ +// +// Comprueba si la IP del cliente est?a en la base de datos de Hidra +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin DHCP +// ipmac: IP o MAC del cliente que ha abierto la hebra +// sw: Si vale 1 o 2 o 3 el parmetro anterior ser una IP en caso contrario ser una MAC +// +// Devuelve: +// true: Si el cliente est en la base de datos +// false: En caso contrario +// +// Comentarios: +// Slo se procesarn mensages dhcp de clientes hidra. +//_______________________________________________________________________________________________________________ +int ClienteExistente(struct TramaDhcpBootp *trmInfo,char* ipmac,int sw) +{ + char sqlstr[1000],ErrStr[200]; + Database db; + Table tbl; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // ACCESO atnico A TRAVEZ DE OBJETO MUTEX a este trozo de cnigo + pthread_mutex_lock(&guardia); + + // Abre conexion con base de datos + if(!db.Open(usuario,pasguor,datasource,catalog)){ // error de conexion + db.GetErrorErrStr(ErrStr); + return(false); + } + + if(sw==1 || sw==2){ // Bsqueda por IP + sprintf(sqlstr,"SELECT ip FROM ordenadores WHERE ip='%s' ",ipmac); + } + else{ // Bsqueda por MAC + sprintf(sqlstr,"SELECT ip FROM ordenadores WHERE mac='%s' ",ipmac); + } + if(!db.Execute(sqlstr,tbl)){ // Error al leer + db.GetErrorErrStr(ErrStr); + db.Close(); + pthread_mutex_unlock(&guardia); + return(false); + } + + if(tbl.ISEOF()){ // No existe el cliente + db.Close(); + pthread_mutex_unlock(&guardia); + return(false); + } + if(sw==1 || sw==0){ // Slo para las tramas dhcp PXE y BOOTP + if(!tbl.Get("ip",trmInfo->bdIP)){ // Incorpora la IP a asignar al cliente a la estructura de control + tbl.GetErrorErrStr(ErrStr); // error al acceder al registro + db.Close(); + pthread_mutex_unlock(&guardia); + return(false); + } + } + db.Close(); + pthread_mutex_unlock(&guardia); + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + return(true); +} +//_______________________________________________________________________________________________________________ +// +// Comprueba que existen opciones en el mensage dhcp analizando la magic cookie +// Parmetros: +// mc: Puntero al primer elemento de la magic cookie (primer campo de las opciones) +// +// Devuelve: +// true: Si esta presenta el valor 99..130.83.99 +// false: En caso contrario +//_______________________________________________________________________________________________________________ +int OpcionesPresentes(unsigned char *mc) +{ + if(mc[0]!=0x63) return(false); + if(mc[1]!=0x82) return(false); + if(mc[2]!=0x53) return(false); + if(mc[3]!=0x63) return(false); + + // Magic Cookie presente + return(true); +} +//_______________________________________________________________________________________________________________ +// +// Busca una determinada opcin dentro de la trama dhcp +// Parmetros: +// dhcp_packet: Puntero a la estructura que contiene el mensaje dhcp +// codop: Cdigo de la opcin a buscar +// +// Devuelve: +// Si existe, un puntero al primer elemento de la estructura de la opcin (codigo,longitud,valor) +// en caso contrario devuelve null +//_______________________________________________________________________________________________________________ +unsigned char * BuscaOpcion(dhcp_packet* tDhcp,unsigned char codop) +{ + unsigned char wcodop; + unsigned char wlongitud; + unsigned char *ptrOp,*ptrDhcp; + + ptrDhcp=(unsigned char*)tDhcp; // Se toma el puntero al principio del mensage + ptrOp=(unsigned char*)&tDhcp->options[0]; // Se toma el puntero a las opciones + + while(ptrOp-ptrDhcppckDchp,DHCP_MESSAGE_TYPE); // Puntero a la opcin tipo de mensaje + if(!ptrOp){ // No existe la opcin DHCP + RegistraLog("***No se encontr opción DHCP:",true); + return; + } + codop = ptrOp[0]; + longitud=ptrOp[1]; + msgDhcp=ptrOp+2; // Puntero al dato tipo de mensaje + switch(*msgDhcp){ + case DHCPDISCOVER: + dhcpDISCOVER_PXE(trmInfo); + break; + case DHCPREQUEST: + dhcpREQUEST_PXE(trmInfo); + break; + } +} +//_______________________________________________________________________________________________________________ +// +// Procesa un mensaje BOOTP recibido que proviene de un cliente PXE +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin BOOTP +//_______________________________________________________________________________________________________________ +void ProcesaTramaClienteBOOTP(struct TramaDhcpBootp* trmInfo) +{ + unsigned char codop; + unsigned char longitud; + unsigned char *ptrOp; + unsigned char *msgDhcp; + + + ptrOp=BuscaOpcion(&trmInfo->pckDchp,DHCP_MESSAGE_TYPE); // Puntero a la opcin tipo de mensaje + if(!ptrOp){ // No existe la opcin DHCP + RegistraLog("***No se encontr opción DHCP:",true); + return; + } + codop = ptrOp[0]; + longitud=ptrOp[1]; + msgDhcp=ptrOp+2; // Puntero al dato tipo de mensaje + switch(*msgDhcp){ + case DHCPREQUEST: + bootpREQUEST_PXE(trmInfo); + break; + } +} +//_______________________________________________________________________________________________________________ +// +// Gestiona la conexion con un cliente que sea Hidra para el servicio TFTP +// Parmetros: +// lpParam: Puntero a la estructura de control para la conversacion TFTP +//_______________________________________________________________________________________________________________ +LPVOID GestionaServicioTFTP(LPVOID lpParam) +{ + struct TramaTftp * trmInfo=(struct TramaTftp *)lpParam; + char IPCliente[16]; // Ip del cliente + + strcpy(IPCliente,inet_ntoa(trmInfo->cliente.sin_addr)); + if(!ClienteExistente((struct TramaDhcpBootp*)trmInfo,IPCliente,2)) // Comprueba que se trata de un cliente Hidra + return(false); + + // Inicializa parmetros + trmInfo->sockaddrsize = sizeof(trmInfo->cliente); + trmInfo->sck=TomaSocketUser(); + if(trmInfo->sck==INVALID_SOCKET) return(false); // Ha habido algn problama para crear el socket de usuario + + trmInfo->currentopCode=0x0000; // Cdigo de operacin para detectar errores de secuencia + trmInfo->bloquesize=512; // Tamao de bloque por defecto 512 + trmInfo->tsize=0; // Tamao del fichero + trmInfo->interval=0; // Intervalo + + ProcesaTramaClienteTFTP(trmInfo); // Procesa TFTP para el protocolo PXE + close(trmInfo->sck); + free(trmInfo); + return(trmInfo); +} +//_______________________________________________________________________________________________________________ +// +// Procesa un mensaje TFTP recibido que proviene de un cliente PXE +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin TFTP +//_______________________________________________________________________________________________________________ +void ProcesaTramaClienteTFTP(struct TramaTftp* trmInfo) +{ + char *ptr; + int bloque,lon,ret; + char tam[20]; + struct tftppacket_ack* ptrack; + + while(true){ + switch(ntohs(trmInfo->pckTftp.opcode)){ + case TFTPRRQ: // Read Request + if(trmInfo->currentopCode!=0x0000) return; // Error en la secuencia de operaciones + if(!PeticionFichero(trmInfo)) return; + fseek(trmInfo->fileboot,0,SEEK_SET); + trmInfo->pckTftp.opcode= htons(TFTPOACK); + trmInfo->currentopCode=TFTPOACK; + ptr=&trmInfo->pckTftp.buffer[0]; + if(trmInfo->tsize>0){ // Opcin tsize + strcpy(ptr,"tsize"); + ptr+=strlen(ptr)+1; + //itoa(trmInfo->tsize,tam,10); + sprintf(tam,"%d",trmInfo->tsize); + strcpy(ptr,tam); + ptr+=strlen(ptr)+1; + *ptr=0x00; + } + else{ + if(trmInfo->bloquesize>0){ // Opcin blksize + strcpy(ptr,"blksize"); + ptr+=strlen(ptr)+1; + //itoa(trmInfo->bloquesize,tam,10); + sprintf(tam,"%d",trmInfo->bloquesize); + strcpy(ptr,tam); + ptr+=strlen(ptr)+1; + *ptr=0x00; + } + else + trmInfo->bloquesize=512; + } + + lon=ptr-(char*)&trmInfo->pckTftp; + //ret=connect(trmInfo->sck,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + //if (ret == SOCKET_ERROR){ + // RegistraLog("***connect() fallo:",true); + // return; + //} + ret=sendto(trmInfo->sck,(char*)&trmInfo->pckTftp,lon,0,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + //ret=send(trmInfo->sck,(char*)&trmInfo->pckTftp,lon,0); + if (ret == SOCKET_ERROR){ + RegistraLog("***sendto() fallo:",true); + return; + } + break; + + case TFTPACK: // + if(trmInfo->currentopCode!=TFTPOACK && trmInfo->currentopCode!=TFTPDATA) return; // Error en la secuencia de operaciones + ptrack=(struct tftppacket_ack*)&trmInfo->pckTftp; + bloque=ntohs(ptrack->block); + trmInfo->currentopCode=TFTPDATA; + ptrack->opcode=htons(TFTPDATA); + bloque++; + ptrack->block=htons(bloque); + trmInfo->numblock=bloque; + lon=fread(ptrack->buffer,1,trmInfo->bloquesize,trmInfo->fileboot); + //ret=connect(trmInfo->sck,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + //if (ret == SOCKET_ERROR){ + // RegistraLog("***connect() fallo:",true); + // return; + //} + ret=sendto(trmInfo->sck,(char*)&trmInfo->pckTftp,lon+4,0,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + //ret=send(trmInfo->sck,(char*)&trmInfo->pckTftp,lon+4,0); + if (ret == SOCKET_ERROR){ + RegistraLog("***sendto() fallo:",true); + return; + } + if(lon==0) + return; // Fin de la trama tftp + break; + case TFTPERROR: + RegistraLog("***ERROR TFTP:",false); + } + ret = recvfrom(trmInfo->sck,(char *)&trmInfo->pckTftp, sizeof(trmInfo->pckTftp),0,(struct sockaddr *)&trmInfo->cliente,&trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***Error al recibir mensaje TFTP en hebra cliente",true); + return; + } + else + if(ret==0) break; + } + return; +} +//_______________________________________________________________________________________________________________ +// +// Procesa un mensaje Tftp de peticin de fichero. Recupera datos de tamao de bloque y otros parmetros +// para gestionar la conversacin. +// +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin TFTP +//_______________________________________________________________________________________________________________ +int PeticionFichero(struct TramaTftp* trmInfo) +{ + char *ptr; + char nomfile[250]; + + if(strncmp(trmInfo->pckTftp.buffer,"pxelinux.cfg",12)==0) + strcpy(nomfile,"default"); + else + strcpy(nomfile,trmInfo->pckTftp.buffer); + + trmInfo->currentopCode=ntohs(trmInfo->pckTftp.opcode); // Guarda cdigo de operacin + // Localiza parmetros + ptr=&trmInfo->pckTftp.buffer[0]; + ptr+=strlen(ptr)+1; // Avanza al campo siguiente al del nombre de fichero + if(!strcmp(ptr,"octet")){ // Modo de apertura + //trmInfo->fileboot=fopen(trmInfo->pckTftp.buffer,"rb"); + trmInfo->fileboot=fopen(nomfile,"rb"); + } + else{ + //trmInfo->fileboot=fopen(trmInfo->pckTftp.buffer,"rt"); + trmInfo->fileboot=fopen(nomfile,"rt"); + } + if(trmInfo->fileboot==NULL) + return(false); // No existe el fichero boot + ptr+=strlen(ptr)+1; // Paso al parmetro siguiente + while(*ptr){ + if(strcmp(ptr,"blksize")==0){ // Parmetro blksize + ptr+=strlen(ptr) + 1; + trmInfo->bloquesize=atoi(ptr); + if(trmInfo->bloquesize<512) trmInfo->bloquesize=512; + if(trmInfo->bloquesize>MAXBLOCK) trmInfo->bloquesize=512; + ptr+=strlen(ptr) + 1; + } + else{ + if(strcmp(ptr,"tsize")==0){ // Parmetro tsize + ptr+=strlen(ptr) + 1; + fseek(trmInfo->fileboot,0,SEEK_END); + trmInfo->tsize=ftell(trmInfo->fileboot); + ptr+=strlen(ptr) + 1; + } + else{ + if(strcmp(ptr,"interval")==0){ // Tamao de los bloques + ptr+=strlen(ptr) + 1; + trmInfo->interval=atoi(ptr); + ptr+=strlen(ptr) + 1; + } + else + return(false); + } + + } + } + return(true); +} +//_______________________________________________________________________________________________________________ +// +// Procesa un mensaje recibido que proviene de un cliente Hidra pero no en el momento de arranque con PXE +// sino cuando arranca con algn S.O. como (Windows oLinux) +// +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin DHCP +//_______________________________________________________________________________________________________________ +void ProcesaTramaClienteDHCP(struct TramaDhcpBootp* trmInfo) +{ + unsigned char codop; + unsigned char longitud; + unsigned char *ptrOp; + unsigned char *msgDhcp; + int ret; + + while(true){ + ptrOp=BuscaOpcion(&trmInfo->pckDchp,DHCP_MESSAGE_TYPE); // Puntero a la opcin tipo de mensaje + if(!ptrOp){ // No existe la opcin DHCP + RegistraLog("***No se encontr opción DHCP:",true); + return; + } + codop = ptrOp[0]; + longitud=ptrOp[1]; + msgDhcp=ptrOp+2; // Puntero al dato tipo de mensaje + + switch(*msgDhcp){ + case DHCPDISCOVER: + dhcpDISCOVER_PXE(trmInfo); + break; + case DHCPREQUEST: + dhcpREQUEST_PXE(trmInfo); + break; + } + ret = recvfrom(trmInfo->sck,(char *)&trmInfo->pckDchp, sizeof(trmInfo->pckDchp),0,(struct sockaddr *)&trmInfo->cliente,&trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***Error al recibir mensaje DHCP",true); + } + else + if(ret==0) break; + } +} +//_______________________________________________________________________________________________________________ +// +// Rellena el campo IP asignada(yiaddr) al cliente dentro del mensaje DHCP +// +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin DHCP +//_______________________________________________________________________________________________________________ +void RellenaIPCLiente(struct TramaDhcpBootp* trmInfo) +{ + unsigned long aux; + + aux=inet_addr(trmInfo->bdIP); // Ip para el cliente + memcpy((void*)&trmInfo->pckDchp.yiaddr,&aux,sizeof(aux)); +} +//_______________________________________________________________________________________________________________ +// +// Rellena el campo IP del servidor(siaddr) dentro del mensaje DHCP +// +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin DHCP +//_______________________________________________________________________________________________________________ +void RellenaIPServidor(struct TramaDhcpBootp* trmInfo) +{ + unsigned long aux; + + aux=inet_addr(IPlocal); // Ip del servidor + memcpy(&trmInfo->pckDchp.siaddr,&aux,sizeof(aux)); +} +//_______________________________________________________________________________________________________________ +// +// Rellena el campo nombre del servidor boot dentro del mensaje BOOTP +// +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin BOOTP +//_______________________________________________________________________________________________________________ +void RellenaNombreServidorBoot(struct TramaDhcpBootp* trmInfo) +{ + char aux[100]; + strcpy(aux,"Hidra 2.0 PXE Boot Server"); + + memcpy(&trmInfo->pckDchp.sname,&aux,25); +} +//_______________________________________________________________________________________________________________ +// +// Rellena el campo nombre del fichero boot dentro del mensaje BOOTP +// +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin BOOTP +//_______________________________________________________________________________________________________________ +void RellenaNombreFicheroBoot(struct TramaDhcpBootp* trmInfo) +{ + char aux[100]; + strcpy(aux,"pxelinux.0"); + + memcpy(&trmInfo->pckDchp.file,&aux,25); +} +//_______________________________________________________________________________________________________________ +// +// Procesa un mensaje DHCPDISCOVER +// +// Parmetros: +// trmInfo: Puntero a la estructura de control de la conversacin DHCP +// +// Devuelve: +// true: Si el mensaje se procesa correctamente +// false: En caso contrario +//_______________________________________________________________________________________________________________ +void dhcpDISCOVER_PXE(struct TramaDhcpBootp* trmInfo) +{ + unsigned char *ptrOp,*ptrDhcp; + int lon,ret; + + ptrDhcp=(unsigned char*)&trmInfo->pckDchp; // Se toma el puntero al principio del mensage + ptrOp=(unsigned char*)&trmInfo->pckDchp.options[0]; // Se toma el puntero a las opciones + lon=ptrOp-ptrDhcp; //Longitud del mensaje sin las opciones ni la magic coockie + + RellenaIPCLiente(trmInfo); + RellenaIPServidor(trmInfo); + *ptrOp='\0'; //Borra opciones del mensaje recibido para colocar las nuevas + + + AdjDHCPOFFER(&ptrOp,&lon); // Genera opcin de Mensaje (0x35) dhcp valor 1 + AdjSERVERIDENTIFIER(&ptrOp,&lon); // Genera opcin de Mensaje (0x36) Dhcp + AdjLEASETIME(&ptrOp,&lon); // Genera opcin de Mensaje (0x33) Dhcp + AdjSUBNETMASK(&ptrOp,&lon); // Genera opcin de Mensaje (0x01) Dhcp + AdjROUTERS(&ptrOp,&lon); // Genera opcin de Mensaje (0x03) Dhcp + AdjCLASSIDENTIFIER(&ptrOp,&lon); // Genera opcin de Mensaje (0x3c) Dhcp + *ptrOp=DHCP_END; + lon++; + trmInfo->pckDchp.op=DHCPOFFER; + //MandaRespuesta(&trmInfo->pckDchp,htonl(INADDR_BROADCAST),lon,htons(PUERTODHCPDESTINO)); + trmInfo->cliente.sin_addr.s_addr=htonl(INADDR_BROADCAST); + ret=sendto(trmInfo->sck,(char*)&trmInfo->pckDchp,lon,0,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***sendto() fallo:",true); + } +} + +//_______________________________________________________________________________________________________________ +// +// Procesa un mensaje DHCPREQUEST (DHCP) +// +// Parmetros: +// trmInfo: Puntero a la estructura de control para la conversacin DHCP +// +// Devuelve: +// true: Si el mensaje se procesa correctamente +// false: En caso contrario +//_______________________________________________________________________________________________________________ +void dhcpREQUEST_PXE(struct TramaDhcpBootp* trmInfo) +{ + unsigned char * ptrOp,*ptrDhcp; + struct dhcp_opcion; + int lon,ret; + + ptrDhcp=(unsigned char*)&trmInfo->pckDchp; // Se toma el puntero al principio del mensage + ptrOp=(unsigned char*)&trmInfo->pckDchp.options[0]; // Se toma el puntero a las opciones + lon=ptrOp-ptrDhcp; //Longitud del mensaje sin las opciones ni la magic coockie + + RellenaIPCLiente(trmInfo); + RellenaIPServidor(trmInfo); + *ptrOp='\0'; //Borra opciones del mensaje recibido para colocar las nuevas + + AdjDHCPACK(&ptrOp,&lon); // Ge db.Close();nera opcin de Mensaje (0x35) dhcp valor 5 + AdjSERVERIDENTIFIER(&ptrOp,&lon); // Genera opcin de Mensaje (0x36) Dhcp + AdjLEASETIME(&ptrOp,&lon); // Genera opcin de Mensaje (0x33) Dhcp + AdjSUBNETMASK(&ptrOp,&lon); // Genera opcin de Mensaje (0x01) Dhcp + AdjROUTERS(&ptrOp,&lon); // Genera opcin de Mensaje (0x03) Dhcp + AdjCLASSIDENTIFIER(&ptrOp,&lon); // Genera opcin de Mensaje (0x3c) Dhcp + + *ptrOp=DHCP_END; + lon++; + + trmInfo->pckDchp.op=DHCPOFFER; + //MandaRespuesta(&trmInfo->pckDchp,htonl(INADDR_BROADCAST),lon,htons(PUERTODHCPDESTINO)); + trmInfo->cliente.sin_addr.s_addr=htonl(INADDR_BROADCAST); + ret=sendto(trmInfo->sck,(char*)&trmInfo->pckDchp,lon,0,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***sendto() fallo:",true); + } +} +//_______________________________________________________________________________________________________________ +// +// Procesa un mensaje DHCPREQUEST (BOOTP) +// +// Parmetros: +// trmInfo: Puntero a la estructura de control para la conversacin BOOTP +// +// Devuelve: +// true: Si el mensaje se procesa correctamente +// false: En caso contrario +//_______________________________________________________________________________________________________________ +void bootpREQUEST_PXE(struct TramaDhcpBootp* trmInfo) +{ + unsigned char * ptrOp,*ptrDhcp; + struct dhcp_opcion; + int lon,ret; + unsigned long aux; + + ptrDhcp=(unsigned char*)&trmInfo->pckDchp; // Se toma el puntero al principio del mensage + ptrOp=(unsigned char*)&trmInfo->pckDchp.options[0]; // Se toma el puntero a las opciones + lon=ptrOp-ptrDhcp; //Longitud del mensaje sin las opciones ni la magic coockie + + aux=inet_addr("0.0.0.0"); // Borra Ip del cliente ( No se porqu pero en la trama aparece as) + memcpy(&trmInfo->pckDchp.ciaddr,&aux,4); + RellenaNombreServidorBoot(trmInfo); + RellenaNombreFicheroBoot(trmInfo); + + *ptrOp='\0'; //Borra opciones del mensaje recibido para colocar las nuevas + + AdjDHCPACK(&ptrOp,&lon); // Genera opcin de Mensaje (0x35) dhcp valor 5 + AdjSERVERIDENTIFIER(&ptrOp,&lon); // Genera opcin de Mensaje (0x36) Dhcp + AdjBOOTSIZE(&ptrOp,&lon); // Genera opcin de Mensaje (0x0D) Dhcp + AdjCLASSIDENTIFIER(&ptrOp,&lon); // Genera opcin de Mensaje (0x3c) Dhcp + + *ptrOp=DHCP_END; + lon++; + + trmInfo->pckDchp.op=DHCPOFFER; + //ret=connect(trmInfo->sck,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + //if (ret == SOCKET_ERROR){ + // RegistraLog("***connect() fallo:",true); + // return; + //} + //ret=send(trmInfo->sck,(char*)&trmInfo->pckDchp,lon,0); + ret=sendto(trmInfo->sck,(char*)&trmInfo->pckDchp,lon,0,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***sendto() fallo:",true); + return; + } +} +//_______________________________________________________________________________________________________________ +// +// Genera una opcin del tipo 0x35(53) con el valor "Dhcp Offer" valor 2 +// +// Devuelve: +// Una estructura de opciones de dhcp(codigo,longitud,dato) con la opciones de Mensaje dhcp Offer +//_______________________________________________________________________________________________________________ +void AdjDHCPOFFER(unsigned char* *ptrOp,int*lon) +{ + **ptrOp=DHCP_MESSAGE_TYPE; + *ptrOp+=1; + **ptrOp=1; + *ptrOp+=1; + **ptrOp=DHCPOFFER; + *ptrOp+=1; + *lon+=3; +} +//_______________________________________________________________________________________________________________ +// +// Genera una opcin del tipo 0x35(53) con el valor "Dhcp Ack" valor 5 +// +// Devuelve: +// Una estructura de opciones de dhcp(codigo,longitud,dato) con la opciones de Mensaje dhcp Ack +//_______________________________________________________________________________________________________________ +void AdjDHCPACK(unsigned char** ptrOp,int*lon) + +{ + **ptrOp=DHCP_MESSAGE_TYPE; + *ptrOp+=1; + **ptrOp=1; + *ptrOp+=1; + **ptrOp=DHCPACK; + *ptrOp+=1; + *lon+=3; +} +//_______________________________________________________________________________________________________________ +// +// Genera una opcin del tipo 0x03(3) con la IP del router +// +// Devuelve: +// Una estructura de opciones de dhcp(codigo,longitud,dato) con la opciones de Ip del Routers +//_______________________________________________________________________________________________________________ +void AdjROUTERS(unsigned char** ptrOp,int*lon) +{ + unsigned long aux; + aux=inet_addr("10.1.12.1"); // Router + + **ptrOp=DHCP_ROUTERS; + *ptrOp+=1; + **ptrOp=4; + *ptrOp+=1; + memcpy(*ptrOp,&aux,4); // Copia la Ip del router en la estructura + *ptrOp+=4; + *lon+=6; + +} +//_______________________________________________________________________________________________________________ +// +// Genera una opcin del tipo 0x01(1) con la mascara de red +// +// Devuelve: +// Una estructura de opciones de dhcp(codigo,longitud,dato) con la opciones de mscara de red +//_______________________________________________________________________________________________________________ +void AdjSUBNETMASK(unsigned char** ptrOp,int*lon) +{ + unsigned long aux; + aux=inet_addr("255.255.252.0"); // Mascara de red + + **ptrOp=DHCP_SUBNET_MASK; + *ptrOp+=1; + **ptrOp=4; + *ptrOp+=1; + memcpy(*ptrOp,&aux,4); // Copia la mscara de red + *ptrOp+=4; + *lon+=6; +} +//_______________________________________________________________________________________________________________ +// +// Genera una opcin del tipo 0x3c(60) con el literal "PXECLient" para clientes PXE +// +// Devuelve: +// Una estructura de opciones de dhcp(codigo,longitud,dato) con la opciones de clase de cliente +//_______________________________________________________________________________________________________________ +void AdjCLASSIDENTIFIER(unsigned char** ptrOp,int*lon) +{ + **ptrOp=DHCP_CLASS_IDENTIFIER; + *ptrOp+=1; + **ptrOp=9; + *ptrOp+=1; + memcpy(*ptrOp,"PXEClient",9); // Copia el literal PXClient + *ptrOp+=9; + *lon+=11; +} +//_______________________________________________________________________________________________________________ +// +// Genera una opcin del tipo 0x36(54) con la IP del servidor +// +// Devuelve: +// Una estructura de opciones de dhcp(codigo,longitud,dato) con la opciones de Ip del servidor +//_______________________________________________________________________________________________________________ +void AdjSERVERIDENTIFIER(unsigned char** ptrOp,int*lon) +{ + unsigned long aux; + aux=inet_addr(IPlocal); // Ip del servidor + + **ptrOp=DHCP_SERVER_IDENTIFIER; + *ptrOp+=1; + **ptrOp=4; + *ptrOp+=1; + memcpy(*ptrOp,&aux,4); // Copia la Ip del ervidor en la estructura + *ptrOp+=4; + *lon+=6; + +} +//_______________________________________________________________________________________________________________ +// +// Genera una opcin del tipo 0x33(51) con el tiempo de "lease" de la IP +// +// Devuelve: +// Una estructura de opciones de dhcp(codigo,longitud,dato) con la opciones del "Lease Time" +//_______________________________________________________________________________________________________________ +void AdjLEASETIME(unsigned char** ptrOp,int*lon) +{ + unsigned long aux; + aux=0x00006054; // tiempo en segundos + + **ptrOp=DHCP_LEASE_TIME; + *ptrOp+=1; + **ptrOp=4; + *ptrOp+=1; + memcpy(*ptrOp,&aux,4); // Copia el lease time en la estructura + *ptrOp+=4; + *lon+=6; +} +//_______________________________________________________________________________________________________________ +// +// Genera una opcin del tipo 0x0D(13) con el tiempo tamao del fichero boot +// +// Devuelve: +// Una estructura de opciones de dhcp(codigo,longitud,dato) con la opciones del "Lease Time" +//_______________________________________________________________________________________________________________ +void AdjBOOTSIZE(unsigned char** ptrOp,int*lon) +{ + unsigned short aux; + aux=0x0402; // Tamao en bytes + + **ptrOp=DHCP_BOOT_SIZE; + *ptrOp+=1; + **ptrOp=2; + *ptrOp+=1; + memcpy(*ptrOp,&aux,2); // Copia el tamao en la estructura + *ptrOp+=2; + *lon+=4; +} +//_______________________________________________________________________________________________________________ +// +// Crea un socket en un puerto determinado para la conversacin de las distintas hebras +// +//_______________________________________________________________________________________________________________ +SOCKET TomaSocketUser() +{ + SOCKET socket_c; // Socket para hebras (UDP) + struct sockaddr_in cliente; + int ret,puerto; + BOOL bOpt; + + socket_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Crea socket para UDP + + if (socket_c == SOCKET_ERROR){ + RegistraLog("***Error al crear socket de usuario para hebra:",true); + return(false); + } + cliente.sin_addr.s_addr = htonl(INADDR_ANY); // selecciona interface + cliente.sin_family = AF_INET; + puerto=PUERTOMINUSER; + while(puerto=PUERTOMAXUSER){ // No hay puertos libres + RegistraLog("*** No hay puertos libres para la hebra del servicio",true); + return(INVALID_SOCKET); + } + + bOpt=TRUE; // Pone el socket en modo "soportar Broadcast" + ret=setsockopt(socket_c,SOL_SOCKET,SO_BROADCAST,(char *)&bOpt,sizeof(bOpt)); + if (ret == SOCKET_ERROR){ + RegistraLog("*** setsockopt(SO_BROADCAST) fallo",true); + return(INVALID_SOCKET); + } + return(socket_c); +} +//_______________________________________________________________________________________________________________ +void Pinta(dhcp_packet* tdp) +{ + return; + printf("\nop = %d htype = %d hlen = %d hops = %d",tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops); + //printf ("\nxid = %x secs = %d flags = %x",tdp -> xid, tdp -> secs, tdp -> flags); + printf ("\nciaddr = %s", inet_ntoa (tdp -> ciaddr)); + printf ("\nyiaddr = %s", inet_ntoa (tdp -> yiaddr)); + printf ("\nsiaddr = %s", inet_ntoa (tdp -> siaddr)); + printf ("\ngiaddr = %s", inet_ntoa (tdp -> giaddr)); + printf ("\nchaddr = %x:%x:%x:%x:%x:%x",((unsigned char *)(tdp -> chaddr)) [0],((unsigned char *)(tdp -> chaddr)) [1],((unsigned char *)(tdp -> chaddr)) [2],((unsigned char *)(tdp -> chaddr)) [3],((unsigned char *)(tdp -> chaddr)) [4],((unsigned char *)(tdp -> chaddr)) [5]); + printf ("\nfilename = %s", tdp -> file); + printf ("\nserver_name = %s", tdp -> sname); + + printf ("\n\n"); +} +//*************************************************************************************************************** +// PROGRAMA PRINCIPAL +//*************************************************************************************************************** +int main(int argc, char **argv) +{ + pthread_t hThreadDHCP,hThreadBOOTP,hThreadTFTP; + int i,resul; + + + for(i = 1; i < argc; i++){ + if (argv[i][0] == '-'){ + switch (tolower(argv[i][1])){ + case 'f': + if (argv[i+1]!=NULL) + strcpy(szPathFileCfg, argv[i+1]); + else{ + RegistraLog("Fallo en los parmetros: Debe especificar el fichero de configuracin del servicio",false); + exit(EXIT_FAILURE); + } + break; + case 'l': + if (argv[i+1]!=NULL) + strcpy(szPathFileLog, argv[i+1]); + else{ + RegistraLog("Fallo en los parmetros: Debe especificar el fichero de log para el servicio",false); + exit(EXIT_FAILURE); + } + break; + default: + RegistraLog("Fallo de sintaxis en los parmetros: Debe especificar -f nombre_del_fichero_de_configuracin_del_servicio",false); + exit(EXIT_FAILURE); + break; + } + } + } + if(!TomaConfiguracion(szPathFileCfg)){ // Toma parametros de configuracion + RegistraLog("NO existe fichero de configuracin o contiene un error de sintaxis",false); + exit(EXIT_FAILURE); + } + + RegistraLog("***Inicio de sesion***",false); + + // Hebra servicio DHCP --------------------------------- + resul=pthread_create(&hThreadDHCP,NULL,ServicioDHCP,(LPVOID)IPlocal); + if(resul!=0){ + RegistraLog("***Fallo al crear la hebra DHCP",false); + exit(EXIT_FAILURE); + } + pthread_detach(hThreadDHCP); + + + // Hebra servicio BOOTP --------------------------------- + resul=pthread_create(&hThreadBOOTP,NULL,ServicioBOOTP,(LPVOID)IPlocal); + if(resul!=0){ + RegistraLog("***Fallo al crear la hebra BOOTP",false); + exit(EXIT_FAILURE); + } + pthread_detach(hThreadBOOTP); + + // Hebra servicio TFTP ---------------------------------- + resul=pthread_create(&hThreadTFTP,NULL,ServicioTFTP,(LPVOID)IPlocal); + if(resul!=0){ + RegistraLog("***Fallo al crear la hebra TFTP",false); + exit(EXIT_FAILURE); + } + pthread_detach(hThreadTFTP); + + while (true) + sleep(1000); + +} diff --git a/Hidra/hidraboot/fuentes/hidraboot.h b/Hidra/hidraboot/fuentes/hidraboot.h new file mode 100644 index 00000000..456a0698 --- /dev/null +++ b/Hidra/hidraboot/fuentes/hidraboot.h @@ -0,0 +1,278 @@ +// ************************************************************************************************************* +// Aplicacin HIDRA +// Copyright 2003-2005 Jos Manuel Alonso. Todos los derechos reservados. +// Fichero: hidrapxedhcp.h +// +// Descripcin: +// Fichero de cabecera de hidrapxedhcp.cpp +// ************************************************************************************************************** +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Database.h" +// _____________________________________________________________________________________________________________ + +#define PUERTODHCPORIGEN 67 +#define PUERTODHCPDESTINO 68 + +#define PUERTOBOOTPORIGEN 4011 +#define PUERTOBOOTPDESTINO 68 + +#define PUERTOTFTPORIGEN 69 + +#define PUERTOMINUSER 20000 +#define PUERTOMAXUSER 60000 + +#define MAX_INTERFACE_LIST 20 +#define MAX_NUM_CSADDRS 20 + +// __________________________________________________________________________________________________________ +typedef unsigned long DWORD; +typedef unsigned short WORD; +typedef int BOOL; +typedef char BYTE; +typedef int SOCKET; +typedef void* LPVOID; + +#define SOCKET_ERROR (-1) +#define INVALID_SOCKET (SOCKET)(~0) + +#define TRUE 1 +#define FALSE 0 + +#define true 1 +#define false 0 +// __________________________________________________________________________________________________________ + +char szPathFileCfg[128],szPathFileLog[128]; +FILE *FLog,*Fconfig; +char mensaje[1000]; +// _____________________________________________________________________________________________________________ +#define DHCP_UDP_OVERHEAD (20 + 8 ) // IP header + UDP header +#define DHCP_SNAME_LEN 64 +#define DHCP_FILE_LEN 128 +#define DHCP_FIXED_NON_UDP 236 +#define DHCP_FIXED_LEN (DHCP_FIXED_NON_UDP + DHCP_UDP_OVERHEAD) // Longitud de la trama sin las opciones +#define DHCP_MTU_MAX 1500 +#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN) + +#define BOOTP_MIN_LEN 300 +#define DHCP_MIN_LEN 548 + +struct dhcp_packet { + unsigned char op; // Message opcode + unsigned char htype; // Hardware addr type + unsigned char hlen; // Hardware addr length + unsigned char hops; // Number of relay agent hops from client + unsigned long xid; // Transaction ID + unsigned short secs; // Seconds since client started looking + unsigned short flags; // Flag bits + struct in_addr ciaddr; // Client IP address + struct in_addr yiaddr; // Client IP address + struct in_addr siaddr; // IP address of next server + struct in_addr giaddr; // DHCP relay agent IP address + unsigned char chaddr [16];// Client hardware address + char sname[DHCP_SNAME_LEN]; // Server name + char file[DHCP_FILE_LEN]; // Boot filename + unsigned char magiccookie[4]; + unsigned char options [DHCP_OPTION_LEN-4]; // Optional parameters. +}; + +// Estructura genrica de una opcin DHCP +struct dhcp_opcion { + unsigned char codop; + unsigned char tam; + unsigned char dato; +}; + +// Cdigo de las distintas opciones DHCP +#define DHCP_PAD 0 +#define DHCP_SUBNET_MASK 1 +#define DHCP_TIME_OFFSET 2 +#define DHCP_ROUTERS 3 +#define DHCP_TIME_SERVERS 4 +#define DHCP_NAME_SERVERS 5 +#define DHCP_DOMAIN_NAME_SERVERS 6 +#define DHCP_LOG_SERVERS 7 +#define DHCP_COOKIE_SERVERS 8 +#define DHCP_LPR_SERVERS 9 +#define DHCP_IMPRESS_SERVERS 10 +#define DHCP_RESOURCE_LOCATION_SERVERS 11 +#define DHCP_HOST_NAME 12 +#define DHCP_BOOT_SIZE 13 +#define DHCP_MERIT_DUMP 14 +#define DHCP_DOMAIN_NAME 15 +#define DHCP_SWAP_SERVER 16 +#define DHCP_ROOT_PATH 17 +#define DHCP_EXTENSIONS_PATH 18 +#define DHCP_IP_FORWARDING 19 +#define DHCP_NON_LOCAL_SOURCE_ROUTING 20 +#define DHCP_POLICY_FILTER 21 +#define DHCP_MAX_DGRAM_REASSEMBLY 22 +#define DHCP_DEFAULT_IP_TTL 23 +#define DHCP_PATH_MTU_AGING_TIMEOUT 24 +#define DHCP_PATH_MTU_PLATEAU_TABLE 25 +#define DHCP_INTERFACE_MTU 26 +#define DHCP_ALL_SUBNETS_LOCAL 27 +#define DHCP_BROADCAST_ADDRESS 28 +#define DHCP_PERFORM_MASK_DISCOVERY 29 +#define DHCP_MASK_SUPPLIER 30 +#define DHCP_ROUTER_DISCOVERY 31 +#define DHCP_ROUTER_SOLICITATION_ADDRESS 32 +#define DHCP_STATIC_ROUTES 33 +#define DHCP_TRAILER_ENCAPSULATION 34 +#define DHCP_ARP_CACHE_TIMEOUT 35 +#define DHCP_IEEE802_3_ENCAPSULATION 36 +#define DHCP_DEFAULT_TCP_TTL 37 +#define DHCP_TCP_KEEPALIVE_INTERVAL 38 +#define DHCP_TCP_KEEPALIVE_GARBAGE 39 +#define DHCP_NIS_DOMAIN 40 +#define DHCP_NIS_SERVERS 41 +#define DHCP_NTP_SERVERS 42 +#define DHCP_VENDOR_ENCAPSULATED_OPTIONS 43 +#define DHCP_NETBIOS_NAME_SERVERS 44 +#define DHCP_NETBIOS_DD_SERVER 45 +#define DHCP_NETBIOS_NODE_TYPE 46 +#define DHCP_NETBIOS_SCOPE 47 +#define DHCP_FONT_SERVERS 48 +#define DHCP_X_DISPLAY_MANAGER 49 +#define DHCP_REQUESTED_ADDRESS 50 +#define DHCP_LEASE_TIME 51 +#define DHCP_OPTION_OVERLOAD 52 +#define DHCP_MESSAGE_TYPE 53 +#define DHCP_SERVER_IDENTIFIER 54 +#define DHCP_PARAMETER_REQUEST_LIST 55 +#define DHCP_MESSAGE 56 +#define DHCP_MAX_MESSAGE_SIZE 57 +#define DHCP_RENEWAL_TIME 58 +#define DHCP_REBINDING_TIME 59 +#define DHCP_CLASS_IDENTIFIER 60 +#define DHCP_CLIENT_IDENTIFIER 61 +#define DHCP_USER_CLASS_ID 77 +#define DHCP_END 255 + +// DHCP message types. +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 +#define DHCPINFORM 8 + +// Estructura para trabajar en cada hebra con el cliente en cuestion +struct TramaDhcpBootp{ + SOCKET sck; + struct sockaddr_in cliente; + socklen_t sockaddrsize; + struct dhcp_packet pckDchp; + char bdIP[16]; +}; +// _____________________________________________________________________________________________________________ + +#define MAXBLOCK 4096 + + +// TFTP Cdigos de operacin. +#define TFTPRRQ 1 // Read request. +#define TFTPWRQ 2 // Write request +#define TFTPDATA 3 // Read or write the next block of data. +#define TFTPACK 4 // Confirnacin de bloque procesado +#define TFTPERROR 5 // Error message +#define TFTPOACK 6 // Option acknowledgment + +// Paquete TFTP genrico +struct tftp_packet +{ + WORD opcode; + char buffer[MAXBLOCK+2]; +}; +// Paquete TFTP tipo ACK +struct tftppacket_ack +{ + WORD opcode; + WORD block; + char buffer[MAXBLOCK]; +}; +// Paquete TFTP tipo ERROR packet +struct tftppacket_error +{ + WORD opcode; + WORD errorcode; + char errormessage[508]; +}; +// Estructura para trabajar en cada hebra con el cliente en cuestion +struct TramaTftp{ + SOCKET sck; + struct sockaddr_in cliente; + socklen_t sockaddrsize; + struct tftp_packet pckTftp; + FILE * fileboot; + int bloquesize; + int tsize; + int interval; + int numblock; + unsigned short currentopCode; +}; +//______________________________________________________ +static pthread_mutex_t guardia; // Controla acceso exclusivo de hebras +//______________________________________________________ +char IPlocal[20]; +char usuario[20]; +char pasguor[20]; +char datasource[20]; +char catalog[50]; + +// Prototipo de funciones +void RegistraLog(char *,int); +int TomaParametrosReg(); + +LPVOID ServicioDHCP(LPVOID); +LPVOID ServicioBOOTP(LPVOID); +LPVOID ServicioTFTP(LPVOID); +LPVOID GestionaServicioDHCP(LPVOID); +LPVOID GestionaServicioBOOTP(LPVOID); +LPVOID GestionaServicioTFTP(LPVOID); + +int ClienteExistente(struct TramaDhcpBootp *,char*,int); +int OpcionesPresentes(unsigned char *); +unsigned char * BuscaOpcion(dhcp_packet* ,unsigned char ); + +int OpcionPXEClient(dhcp_packet* ); +void ProcesaTramaClientePXE(struct TramaDhcpBootp* trmInfo); +void ProcesaTramaClienteDHCP(struct TramaDhcpBootp* trmInfo); +void ProcesaTramaClienteBOOTP(struct TramaDhcpBootp* trmInfo); +void ProcesaTramaClienteTFTP(struct TramaTftp * trmInfo); + +void RellenaIPCLiente(struct TramaDhcpBootp*); +void RellenaIPServidor(struct TramaDhcpBootp*); +void dhcpDISCOVER_PXE(struct TramaDhcpBootp*); +void dhcpREQUEST_PXE(struct TramaDhcpBootp*); +void bootpREQUEST_PXE(struct TramaDhcpBootp*); + +int PeticionFichero(struct TramaTftp*); + +void AdjDHCPOFFER(unsigned char**,int*); +void AdjDHCPACK(unsigned char**,int*); +void AdjROUTERS(unsigned char** ,int*); +void AdjSUBNETMASK(unsigned char**,int*); +void AdjCLASSIDENTIFIER(unsigned char** ,int*); +void AdjSERVERIDENTIFIER(unsigned char** ,int*); +void AdjLEASETIME(unsigned char** ,int*); +void AdjBOOTSIZE(unsigned char** ,int*); + +SOCKET TomaSocketUser(); +struct tm * TomaHora(); +int split_parametros(char **,char *, char *); +void duerme(unsigned int ); diff --git a/Hidra/hidrac/fuentes/hidrac.c b/Hidra/hidrac/fuentes/hidrac.c new file mode 100644 index 00000000..44465d50 --- /dev/null +++ b/Hidra/hidrac/fuentes/hidrac.c @@ -0,0 +1,2096 @@ +// ****************************************************************************************************** +// Aplicación HIDRA (Gestión y Admistración de aulas de informática) +// Autor: José Manuel Alonso (E.T.S.I.I.) Universidad de Sevilla. +// Fichero: hidrac.c +// Descripción: +// Este programa es el que utiliza el cliente Hidra para comunicarse con su servidor y +// su repositorio mediante sockets +// ***************************************************************************************************** +#include "hidrac.h" +//______________________________________________________________________________________________________ +// Función: Encripta +// +// Descripción: +// Encripta una cadena +// Parámetros: +// - cadena: Cadena a encriptar +// Devuelve: +// - La cadena encriptada +//______________________________________________________________________________________________________ +char* Encriptar(char *cadena) +{ + return(cadena); + + int i,lon; + char clave; + + clave = 12 & 0xFFU; // La clave elegida entre 0-255, en este caso 12 + lon=strlen(cadena); + for(i=0;itm_mday,timeinfo->tm_mon+1,timeinfo->tm_year+1900,timeinfo->tm_hour,timeinfo->tm_min,msg); + fclose(FLog); + + // Lo muestra por consola + sprintf(msgcon,"echo '%02d/%02d/%d %02d:%02d ***%s'\n",timeinfo->tm_mday,timeinfo->tm_mon+1,timeinfo->tm_year+1900,timeinfo->tm_hour,timeinfo->tm_min,msg); + system(msgcon); +} +//______________________________________________________________________________________________________ +// Función: UltimoError +// +// Descripción: +// Almacena el último error producido y lo registra en el log +// Parámetros: +// - herror: Código del error +// - msg: Descripción del error +// - modulo: Función donde se produjo el error +//______________________________________________________________________________________________________ +void UltimoError(int herror,char*modulo) +{ + e.herror=herror; + if(herror>MAXERROR){ + strcpy(e.msg,tbErrores[23]); + } + else + strcpy(e.msg,tbErrores[herror]); + strcpy(e.modulo,modulo); + sprintf(msglog,"Error %d.-(%s) en modulo %s",e.herror,e.msg,e.modulo); + Log(msglog); +} +//______________________________________________________________________________________________________ +// Función: INTROaFINCAD +// +// Descripción: +// Cambia los INTROS (\r) por caracteres fin de cadena ('\0') en una cadena +// Parámetros: +// - parametros : La cadena a explorar +// ________________________________________________________________________________________________________ +void INTROaFINCAD(char* parametros) +{ + int lon,i; + lon=strlen(parametros); + for(i=0;i2){ + sprintf(msglog,">>>EJECUCIÓN DEL comando %s",script); + Log(msglog); + } + + nargs=SplitParametros(argumentos,parametros," "); // Crea matriz de los argumentos del scripts + for(i=nargs;i2){ + for(i=0;i>>PARAMETRO %d DEL comando %s",i,argumentos[i]); + Log(msglog); + } + } + + if((pid=fork())==0){ + /* Proceso hijo que ejecuta el script */ + close (descr[LEER]); + dup2 (descr[ESCRIBIR], 1); + close (descr[ESCRIBIR]); + resul=execv(script,argumentos); + //resul=execlp (script, script, argumentos[0],argumentos[1],NULL); + exit(resul); + } + else { + if (pid ==-1){ + sprintf(msglog,"***Error en la creación del proceso hijo pid=%d",pid); + Log(msglog); + return(-1); + } + /* Proceso padre que lee la salida del script */ + close (descr[ESCRIBIR]); + bytesleidos = read (descr[LEER], buffer, 512); + while(bytesleidos>0){ + if(salida!=(char*)NULL){ // Si se solicita retorno de información... + buffer[bytesleidos]='\0'; + for(i=bytesleidos-1;i>=0;i--){ + if(buffer[i]<32) // Caracter Asci menor de 32 + buffer[i]='\0'; + } + strcat(salida,buffer); + } + bytesleidos = read (descr[LEER], buffer, 512); + } + close (descr[LEER]); + if(ndebug>2){ + sprintf(msglog,">>>Información DEVUELTA %s",salida); + Log(msglog); + } + //kill(pid,SIGQUIT); + waitpid(pid,&estado,0); + resul=WEXITSTATUS(estado); + if(ndebug>2){ + sprintf(msglog,">>>Estatus de FINALIZACIÓN:%d",resul); + Log(msglog); + } + return(resul); + } + return(-1); +} +//______________________________________________________________________________________________________ +// Función: ReservaMemoria +// +// Descripción: +// Reserva memoria para una variable +// Parámetros: +// - lon: Longitud en bytes de la reserva +// Devuelve: +// Un puntero a la zona de memoria reservada que ha sido previamente rellena con zeros o nulos +//______________________________________________________________________________________________________ +char* ReservaMemoria(int lon) +{ + char *mem; + mem=(char*)malloc(lon); + if(mem!=NULL) + memset(mem,0,lon); + return(mem); +} +//______________________________________________________________________________________________________ +// Función: TCPConnect +// +// Descripción: +// Crea un socket y lo conecta a un servidor +// Parámetros: +// - ips : La Dirección IP del servidor +// - port : Puerto para la comunicación +// Devuelve: +// Un socket para comunicaciones por protocolo TCP +//______________________________________________________________________________________________________ +SOCKET TCPConnect(char *ips,char* port) +{ + SOCKET s; + struct sockaddr_in server; + + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (s == INVALID_SOCKET){ + return (INVALID_SOCKET); + } + server.sin_family = AF_INET; + server.sin_port = htons((short)atoi(port)); + server.sin_addr.s_addr = inet_addr(ips); + + if (connect(s, (struct sockaddr *)&server, sizeof(server)) == INVALID_SOCKET) + return (INVALID_SOCKET); + + return(s); +} +//______________________________________________________________________________________________________ +// Función: TCPClose +// +// Descripción: +// Cierra una conexión establecida a través de un socket +// Parámetros: +// - s : El socket que implementa la conexión +//______________________________________________________________________________________________________ +void TCPClose(SOCKET s){ + close(s); +} +//______________________________________________________________________________________________________ +// Función: AbreConexionTCP +// +// Descripción: +// Abre la conexión entre el cliente y el servidor HIDRA +// Parámetros: +// - ips : La Dirección IP del servidor +// - port : Puerto para la comunicación +// Devuelve: +// Un socket para comunicaciones por protocolo TCP con el servidor Hidra +//______________________________________________________________________________________________________ +int AbreConexionTCP() +{ + BOOL swloop=true; + int vez=0; + + while(swloop){ + sock=TCPConnect(Propiedades.servidorhidra,Propiedades.puerto); + if(sock!= INVALID_SOCKET){ + return(true); + } + if(swloop){ + vez++; + if (vez>MAXCNX){ + swloop=false; + UltimoError(2,"AbreConexionTCP()"); + return(false); + } + } + sleep(5); // Espera dos cinco antes de intentar una nueva conexión con el servidor Hidra + } + return(true); +} +//______________________________________________________________________________________________________ +// Función: CierraConexionTCP +// +// Descripción: +// Cierra la conexión entre el cliente y el servidor HIDRA +//______________________________________________________________________________________________________ +void CierraConexionTCP() +{ + TCPClose(sock); +} +//______________________________________________________________________________________________________ +// Función: EnviaTramasHidra +// +// Descripción: +// Envía una trama TCP al servidor Hidra +// Parámetros: +// s: socket TCP +// trama: contenido a enviar +// Devuelve: +// true si el envío ha sido correcto o false en caso contrario +//______________________________________________________________________________________________________ +int EnviaTramasHidra(SOCKET s,TRAMA *trama) +{ + int lon; + + trama->arroba='@'; // cabecera de la trama + strcpy(trama->identificador,"JMMLCAMDJ"); // identificador de la trama + trama->ejecutor='1'; // Origen del envío 1=el servidor hidra 2=el cliente hidra 2=el repositorio de imágenes + + lon=strlen(trama->parametros); // Compone la trama + lon+=sprintf(trama->parametros+lon,"iph=%s\r",Propiedades.IPlocal); // Ip del ordenador + lon+=sprintf(trama->parametros+lon,"ido=%s\r",Propiedades.idordenador); // Identificador del ordenador + return(TCPWrite(s,trama)); +} +//______________________________________________________________________________________________________ +// Función: RecibeTramasHidra +// +// Descripción: +// Recibe una trama TCP del servidor Hidra +// Parámetros: +// s: socket TCP +// trama: contenido a enviar +// Devuelve: +// true si el envío ha sido correcto o false en caso contrario +//______________________________________________________________________________________________________ +int RecibeTramasHidra(SOCKET s,TRAMA *trama) +{ + return(TCPRead(s,trama)); +} +//______________________________________________________________________________________________________ +// Función: TCPWrite +// +// Descripción: +// Envia una trama por la red (TCP) +// Parámetros: +// s: socket TCP +// trama: contenido a enviar +// Devuelve: +// true si el envío ha sido correcto o false en caso contrario +//______________________________________________________________________________________________________ +int TCPWrite(SOCKET s,TRAMA* trama) +{ + int nLeft,idx,ret; + + Encriptar((char*)trama); + nLeft = strlen((char*)trama); + idx = 0; + while(nLeft > 0){ + ret = send(s,(char*)&trama[idx], nLeft, 0); + if (ret == 0) + break; + else + if (ret == SOCKET_ERROR){ + return(false); + } + nLeft -= ret; + idx += ret; + } + return(true); +} +//______________________________________________________________________________________________________ +// Función: TCPRead +// +// Descripción: +// Recibe una trama por la red (TCP) +// Parámetros: +// s: socket TCP +// trama: contenido a enviar +// Devuelve: +// true si el envío ha sido correcto o false en caso contrario +//______________________________________________________________________________________________________ +int TCPRead(SOCKET s,TRAMA* trama) +{ + int ret; + + ret = recv(s,(char*)trama,LONGITUD_TRAMA,0); + if (ret == 0) // conexión cerrada por parte del cliente (Graceful close) + return (false); + else{ + if (ret == SOCKET_ERROR){ + return (false); + } + else{ // Datos recibidos + Desencriptar((char*)trama); + trama->parametros[ret-11]='\0'; // Coloca caracter fin de cadena en trama + return(true); + } + } + +} +//______________________________________________________________________________________________________ +// Función: UDPConnect +// +// Descripción: +// Crea un socket UDP para la comunicación con su repositorio +// Parámetros: +// Ninguno +// Devuelve: +// Un socket para comunicaciones por protocolo UDP +//______________________________________________________________________________________________________ +SOCKET UDPConnect() +{ + SOCKET socket_c; + + socket_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (socket_c == SOCKET_ERROR) + return (INVALID_SOCKET); + return(socket_c); +} +//______________________________________________________________________________________________________ +// Función: EnviaTramaRepo +// +// Descripción: +// Envía una trama UDP a su repositorio de imágenes +// Parámetros: +// s: socket UDP +// trama: contenido a enviar +// iprepo: Dirección IP del repositorio +// puertorepo: Puerto de destino donde el repositorio espera la trama +// Devuelve: +// true si el envío ha sido correcto o false en caso contrario +//______________________________________________________________________________________________________ +int EnviaTramaRepo(SOCKET s,TRAMA* trama, char* iprepo,char *puertorepo) +{ + int ret,lon; + struct sockaddr_in addrRepo; + + trama->arroba='@'; // cabecera de la trama + strcpy(trama->identificador,"JMMLCAMDJ"); // identificador de la trama + trama->ejecutor='2'; // Origen del envío 1=el servidor hidra 2=el cliente hidra 3=el repositorio de imágenes + + lon=strlen(trama->parametros); // Compone la trama + lon+=sprintf(trama->parametros+lon,"iph=%s\r",Propiedades.IPlocal); // Ip local del ordenador + lon+=sprintf(trama->parametros+lon,"ido=%s\r",Propiedades.idordenador); // identificador del ordenador + + addrRepo.sin_family = AF_INET; + addrRepo.sin_port = htons((short)atoi(puertorepo)); // Puerto del repositorio + addrRepo.sin_addr.s_addr = inet_addr(iprepo); // Dirección IP del repositorio + + Encriptar((char*)trama); // Encripta la trama + ret = sendto(s,(char *)trama,lon+11,0,(struct sockaddr *)&addrRepo, sizeof(addrRepo)); + if (ret == SOCKET_ERROR) + return(false); + return true; +} +//______________________________________________________________________________________________________ +// Función: RecibeTramaRepo +// +// Descripción: +// Recibe una trama UDP de su repositorio de imágenes +// Parámetros: +// s: socket UDP con el que se envío anteriormente una trama al repositorio +// Devuelve: +// true si la receción ha sido correcta o false en caso contrario +//______________________________________________________________________________________________________ +int RecibeTramaRepo(SOCKET s) +{ + int ret; + struct sockaddr_in addrRepo; + + socklen_t iAddrSize = sizeof(addrRepo); + ret = recvfrom(s,(char *)trama, LONGITUD_TRAMA,0,(struct sockaddr *)&addrRepo,&iAddrSize); + if (ret != SOCKET_ERROR){ + Desencriptar((char*)trama); // Desencripta la trama + return(true); + } + return(false); +} +//______________________________________________________________________________________________________ +// Función: CreateTextFile +// +// Descripción: +// Crea un fichero de texto local y escribe en él cierto contenido +// Parámetros: +// - nomfile: Nombre del fichero +// - texto: Texto a escribir en el fichero +// Devuelve: +// - La longitud en bytes del contenido escrito +//______________________________________________________________________________________________________ +long CreateTextFile(char *nomfile,char *texto) +{ + long lSize; + FILE *f; + f = fopen(nomfile,"wt"); + if(!f){ // El fichero por algún motivo no ha podido crearse + UltimoError(3,"CreateTextFile()"); + return(0); + } + lSize=strlen(texto); + fwrite(texto,1,lSize,f); // Escribe el contenido del fichero + fclose(f); + return(lSize); +} +//______________________________________________________________________________________________________ +// Función: ExisteFichero +// +// Descripción: +// Comprueba si un archivo existe en su repositorio +// Parámetros: +// - nomfile : Nombre del fichero +// Devuelve: +// true si el archivo existe o false en caso contrario +// ________________________________________________________________________________________________________ +int ExisteFichero(char *nomfile) +{ + SOCKET udpsock; + int res; + + udpsock=UDPConnect(); + if (udpsock == INVALID_SOCKET){ + UltimoError(15,"ExisteFichero()"); + return(false); + } + sprintf(trama->parametros,"nfn=ExisteFichero\rnfl=%s\r",nomfile); // Nombre de la función a ejecutar en el servidor HIDRA + if(EnviaTramaRepo(udpsock,trama,Propiedades.iprepo,Propiedades.puertorepo)){ + res=RecibeTramaRepo(udpsock); + close(udpsock); + if(res) + return(GestionTramas(trama)); + } + else{ + UltimoError(16,"ExisteFichero()"); + return(false); + } +} +//______________________________________________________________________________________________________ +// Función: RemoveFile +// +// Descripción: +// Elimina un fichero del repositorio +// Parámetros: +// - nomfile : Nombre del fichero +// Devuelve: +// true si el archivo se ha eliminado correctamente o false en caso contrario +// ________________________________________________________________________________________________________ +int RemoveFile(char *nomfile) +{ + SOCKET udpsock; + int res; + + udpsock=UDPConnect(); + if (udpsock == INVALID_SOCKET){ + UltimoError(15,"RemoveFile()"); + return(false); + } + sprintf(trama->parametros,"nfn=EliminaFichero\rnfl=%s\r",nomfile); // Nombre de la función a ejecutar en el servidor HIDRA + if(EnviaTramaRepo(udpsock,trama,Propiedades.iprepo,Propiedades.puertorepo)){ + res=RecibeTramaRepo(udpsock); + close(udpsock); + if(res) + return(GestionTramas(trama)); + } + else{ + UltimoError(16,"RemoveFile()"); + return(false); + } +} +//______________________________________________________________________________________________________ +// Función: LoadTextFile +// +// Descripción: +// Lee un fichero del repositorio +// Parámetros: +// - nomfile : Nombre del fichero +// Devuelve: +// true si el proceso es correcto y false en caso contrario +// Especificaciones: +// En los parametros de la trama se copian el contenido del del archivo de comandos +// ________________________________________________________________________________________________________ +int LoadTextFile(char *nomfile) +{ + SOCKET udpsock; + int res; + char *txt; + + udpsock=UDPConnect(); + if (udpsock == INVALID_SOCKET){ + UltimoError(15,"LoadTextFile()"); + return(false); + } + sprintf(trama->parametros,"nfn=LeeFicheroTexto\rnfl=%s\r",nomfile); // Nombre de la función a ejecutar en el servidor HIDRA + if(EnviaTramaRepo(udpsock,trama,Propiedades.iprepo,Propiedades.puertorepo)){ + res=RecibeTramaRepo(udpsock); + close(udpsock); + if(res){ + if(GestionTramas(trama)){ + txt=TomaParametro("txt",trama->parametros); // Toma contenido del fichero de comandos + strcpy(trama->parametros,txt); + if(ndebug>3){ + sprintf(msglog,">>>>ARCHIVO DE COMANDO:\r%s",trama->parametros); + Log(msglog); + } + return(true); // Devuelve contrenido del fichero + } + else{ + UltimoError(3,"LoadTextFile()"); + return(false); + } + } + else{ + UltimoError(16,"LoadTextFile()"); + return(false); + } + } + else{ + UltimoError(16,"LoadTextFile()"); + return(false); + } +} +//______________________________________________________________________________________________________ +// Función: ProcesaComandos +// +// Descripción: +// Espera comando desde el servidor Hidra para ejecutarlos +// Parámetros: +// Ninguno +// Devuelve: +// true si el archivo se ha eliminado correctamente o false en caso contrario +// ________________________________________________________________________________________________________ +int ProcesaComandos() +{ + sprintf(filecmd,"/comandos/CMD_%s",Propiedades.IPlocal); // Nombre del fichero de comandos + if(ExisteFichero(filecmd)) // Borra fichero de comandos si previamente exista de anteriores procesos + RemoveFile(filecmd); + if(!DisponibilidadComandos(true)){ // Notifica al servidor HIDRA su disponibilidad para recibir comandos + UltimoError(0,"ProcesaComandos()"); + return(false); + } + PRCCMD=true; + while(PRCCMD){ // Bucle de espera de comandos interactivos + if(ExisteFichero(filecmd)){ // Busca fichero de comandos + Log("Comando recibido desde el servidor Hidra"); + if(!LoadTextFile(filecmd)){ // Toma comando + UltimoError(1,"ProcesaComandos()"); + return(false); + } + GestionTramas(trama); // Analiza la trama y ejecuta el comando + Log("Procesa comandos pendientes"); + ComandosPendientes(); // Bucle para procesar comandos pendientes + Log("Disponibilidad para comandos interactivos activada ..."); + if(!DisponibilidadComandos(true)){ // Notifica al servidor HIDRA su disponibilidad para recibir comandos + UltimoError(0,"ProcesaComandos()"); + return(false); + } + if(!RemoveFile(filecmd)){ // Lo elimina + UltimoError(0,"ProcesaComandos()"); + return(false); + } + } + sleep(5); // Espera 5 segundos antes de volver a esperar comandos + } + return(true); +} +//______________________________________________________________________________________________________ +// Función: DisponibilidadComandos +// +// Descripción: +// Notifica al servidor su disponibilidad a recibir comandos ( Lgica negativa ) +// Parámetros: +// - swdis : Indica disponibilidad si es true y NO disponibilidad en caso de ser false +// Devuelve: +// true si el proceso es correcto y false en caso contrario +// ________________________________________________________________________________________________________ +int DisponibilidadComandos(int swdis) +{ + int lon; + + lon=sprintf(trama->parametros,"nfn=DisponibilidadComandos\r"); + if(!swdis) + lon+=sprintf(trama->parametros+lon,"swd=0\r"); // No disponible + else + lon+=sprintf(trama->parametros+lon,"swd=1\r"); // Disponible + + if(AbreConexionTCP()){ + if(!EnviaTramasHidra(sock,trama)){ + UltimoError(21,"DisponibilidadComandos()"); // No se pudo recuperar la configuración hardware + return(false); + } + if(!RecibeTramasHidra(sock,trama)){ + UltimoError(22,"DisponibilidadComandos()"); // No se pudo recuperar la configuración hardware + return(false); + } + CierraConexionTCP(); + GestionTramas(trama); // Analiza la trama + } + else{ + UltimoError(2,"DisponibilidadComandos()"); + return(false); + } + return(true); +} +//______________________________________________________________________________________________________ +// Función: GestionTramas +// +// Descripción: +// Gestiona las tramas recibidas por la red +// Parámetros: +// - trama : Una trama recibida +// Devuelve: +// true o false dependiendo del éxito en la ejecución del comandoo si se trata de una trama +// del servidor Hidra o bien del resultado de la petición de información al repositorio +// ________________________________________________________________________________________________________ +int GestionTramas(TRAMA *trama) +{ + TRAMA *nwtrama=NULL; + int res; + char *nombrefuncion; + INTROaFINCAD(trama->parametros); + nombrefuncion=TomaParametro("nfn",trama->parametros); + nwtrama=(TRAMA*)ReservaMemoria(LONGITUD_TRAMA); // Reserva buffer para la trama devuelta + if(!nwtrama){ + UltimoError(1,"GestionTramas()"); + return(false); + } + if(ndebug>2){ + sprintf(msglog,">>>>GESTION DE TRAMAS.-Función a ejecutar:%s",nombrefuncion); + Log(msglog); + } + // Mensajes entre el cliente y el servidor Hidra + res=strcmp(nombrefuncion,"Apagar"); + if(res==0) + return(Apagar(trama,nwtrama)); + + res=strcmp(nombrefuncion,"Arrancar"); + if(res==0) + return(Arrancar(trama,nwtrama)); + + res=strcmp(nombrefuncion,"Reiniciar"); + if(res==0) + return(Reiniciar(trama,nwtrama)); + + res=strcmp(nombrefuncion,"RESPUESTA_InclusionClienteHIDRA"); + if(res==0) + return(RESPUESTA_InclusionClienteHIDRA(trama)); + + res=strcmp(nombrefuncion,"Actualizar"); + if(res==0) + return(Actualizar()); + + res=strcmp(nombrefuncion,"NoComandosPtes"); + if(res==0) + return(NoComandosPtes()); + + res=strcmp(nombrefuncion,"Cortesia"); + if(res==0) + return(Cortesia()); + + + res=strcmp(nombrefuncion,"ExecShell"); + if(res==0) + return(ExecShell(trama,nwtrama)); + + res=strcmp(nombrefuncion,"CrearPerfilSoftware"); + if(res==0) + return(CrearPerfilSoftware(trama,nwtrama)); + + res=strcmp(nombrefuncion,"RestaurarImagen"); + if(res==0) + return(RestaurarImagen(trama,nwtrama)); + + res=strcmp(nombrefuncion,"TomaConfiguracion"); + if(res==0) + return(TomaConfiguracion(trama,nwtrama)); + + res=strcmp(nombrefuncion,"InventarioHardware"); + if(res==0) + return(InventarioHardware(trama,nwtrama)); + + res=strcmp(nombrefuncion,"ParticionaryFormatear"); + if(res==0) + return(ParticionaryFormatear(trama,nwtrama)); + + // Mensajes entre el cliente y el repositorio + res=strcmp(nombrefuncion,"Respuesta_ExisteFichero"); + if(res==0){ + res=atoi(TomaParametro("res",trama->parametros)); + return(res); + } + + res=strcmp(nombrefuncion,"Respuesta_EliminaFichero"); + if(res==0){ + res=atoi(TomaParametro("res",trama->parametros)); + return(res); + } + + res=strcmp(nombrefuncion,"Respuesta_LeeFicheroTexto"); + if(res==0){ + res=atoi(TomaParametro("res",trama->parametros)); + return(res); + } + + UltimoError(4,"GestionTramas()"); + return(false); +} +//______________________________________________________________________________________________________ +// Función: Cortesia +// +// Descripción: +// Respuesta estandar del servidor Hidra +// Parámetros: +// Ninguno +// Devuelve: +// true siempre +// Especificaciones: +// Esta función se ejecuta de forma estandar para cerrar la conversación con el servidor Hidra +//______________________________________________________________________________________________________ +int Cortesia(){ + return(true); +} +//______________________________________________________________________________________________________ +// Función: NoComandosPtes +// +// Descripción: +// Conmuta el switch de los comandos pendientes y lo pone a false +// Parámetros: +// Ninguno +// Devuelve: +// true siempre +// Especificaciones: +// Cuando se ejecuta esta función se sale del bucle que recupera los comandos pendientes en el servidor y +// el cliente pasa a a estar disponible para recibir comandos desde el éste. +//______________________________________________________________________________________________________ +int NoComandosPtes(){ + CMDPTES=false; // Corta el bucle de comandos pendientes + return(true); +} +//______________________________________________________________________________________________________ +// Función: TomaIPlocal +// +// Descripción: +// Recupera la IP local +// Parámetros: +// Ninguno +// Devuelve: +// Una cadena con el valor de la IP en formato xxx.xxx.xxx.xxx +// Especificaciones: +// En caso de no encontrar la IP o generarse algún error se devuelve la dirección 0.0.0.0 +//______________________________________________________________________________________________________ +int TomaIPlocal() +{ + int herror; + + sprintf(cmdshell,"%s/hidraClientIP",HIDRASCRIPTS); + herror=EjecutarScript (cmdshell,NULL,IPlocal); + if(herror){ + UltimoError(herror,"TomaIPlocal()"); // Se ha producido algún error + return(false); + } + return(true); +} +//______________________________________________________________________________________________________ +// Función: InclusionClienteHIDRA +// +// Descripción: +// Abre una sesión en el servidor Hidra y registra al cliente en el sistema +// Parámetros: +// Ninguno +// Devuelve: +// true si el registro ha tenido éxito o false en caso contrario +//______________________________________________________________________________________________________ +int InclusionClienteHIDRA() +{ + int lon; + char *parametroscfg; + + parametroscfg=(char*)ReservaMemoria(256); + if(!parametroscfg){ + UltimoError(1,"InclusionClienteHIDRA()"); // No se pudo reservar memoria + return(false); + } + + char *disco=(char*)ReservaMemoria(2); + sprintf(disco,"1"); // Siempre el disco 1 + parametroscfg=LeeConfiguracion(disco); // Toma configuración + + if(ndebug>3){ + sprintf(msglog,"CONFIGURACION=%s",parametroscfg); + Log(msglog); + } + + if(!parametroscfg){ + UltimoError(18,"InclusionClienteHIDRA()"); // No se pudo recuperar la configuración hardware + return(false); + } + lon=sprintf(trama->parametros,"nfn=InclusionClienteHIDRA\r"); // Nombre de la función a ejecutar en el servidor HIDRA + lon+=sprintf(trama->parametros+lon,"cfg=%s\r",parametroscfg); // Configuración de los Sistemas Operativos del cliente + if(AbreConexionTCP()){ + Log("Enviando peticion de inclusion del cliente Hidra"); + if(!EnviaTramasHidra(sock,trama)){ + UltimoError(21,"InclusionClienteHIDRA()"); // No se pudo recuperar la configuración hardware + return(false); + } + Log("Recibiendo respuesta del Servidor Hidra"); + if(!RecibeTramasHidra(sock,trama)){ + UltimoError(22,"InclusionClienteHIDRA()"); // No se pudo recuperar la configuración hardware + return(false); + } + CierraConexionTCP(); + if(!GestionTramas(trama)){ // Analiza la trama + UltimoError(0,"InclusionClienteHIDRA()"); + return(false); + } + return(true); + } + else{ + UltimoError(2,"InclusionClienteHIDRA()"); // No se pudo conectar con el servidor Hidra + return(false); + } + return(true); +} +//______________________________________________________________________________________________________ +// Función: RESPUESTA_InclusionClienteHIDRA +// +// Descripción: +// Respuesta del servidor HIDRA a la petición de inicio enviando los datos identificativos del cliente y otras configuraciones +// Parámetros: +// trama: Trama recibida por el cliente desde el Servidor Hidra +// Devuelve: +// true si el registro ha tenido éxito o false en caso contrario +//______________________________________________________________________________________________________ +int RESPUESTA_InclusionClienteHIDRA(TRAMA *trama) +{ + strcpy(Propiedades.idordenador,TomaParametro("ido",trama->parametros)); // Identificador del ordenador + strcpy(Propiedades.nombreordenador,TomaParametro("npc",trama->parametros)); // Nombre del ordenador + strcpy(Propiedades.idaula,TomaParametro("ida",trama->parametros)); // Identificador del aula a la que pertenece + strcpy(Propiedades.idperfilhard,TomaParametro("ifh",trama->parametros)); // Identificador del perfil hardware del ordenador + strcpy(Propiedades.servidorhidra,TomaParametro("hrd",trama->parametros)); // Dirección IP del servidor Hidra + strcpy(Propiedades.puerto,TomaParametro("prt",trama->parametros)); // Puerto de comunicación con el servidor Hidra + strcpy(Propiedades.iprepo,TomaParametro("ipr",trama->parametros)); // Dirección IP del repositorio + strcpy(Propiedades.puertorepo,TomaParametro("repr",trama->parametros)); // Puerto de comunicación con el repositorio + + // Guarda items del menú + char* cabmenu=TomaParametro("cmn",trama->parametros); + if (cabmenu){ + swmnu=true; + char *auxCab[15]; + SplitParametros(auxCab,cabmenu,"&"); // Caracter separador de los elementos de un item + strcpy(CabMnu.titulo,auxCab[0]); // Tìtulo del menú + strcpy(CabMnu.coorx,auxCab[1]); // Coordenada x del menú público + strcpy(CabMnu.coory,auxCab[2]); // Coordenada y del menú público + strcpy(CabMnu.modalidad,auxCab[3]); // Modalidad de columnas del menú público + strcpy(CabMnu.scoorx,auxCab[4]); // Coordenada x del menú privado + strcpy(CabMnu.scoory,auxCab[5]); // Coordenada y del menú privado + strcpy(CabMnu.smodalidad,auxCab[6]); // Modalidad de columnas del menú privado + strcpy(CabMnu.resolucion,auxCab[7]); // Resolución de pantalla + } + /*char* menu=TomaParametro("mnu",trama->parametros); // Menú estandar + + char* auxMenu[MAXITEMS],auxItem[10]; + int iMnu=SplitParametros(auxMenu,menu,"?"); // Caracter separador de los item + int i,nitem; + + for( i = 0; iparametros,"nfn=ComandosPendientes\r"); // Nombre de la función a ejecutar en el servidor HIDRA + if(AbreConexionTCP()){ + if(!EnviaTramasHidra(sock,trama)){ + UltimoError(21,"ComandosPendientes()"); // No se pudo recuperar la configuración hardware + return(false); + } + if(!RecibeTramasHidra(sock,trama)){ + UltimoError(22,"ComandosPendientes()"); // No se pudo recuperar la configuración hardware + return(false); + } + CierraConexionTCP(); + GestionTramas(trama); // Analiza la trama + } + else{ + UltimoError(2,"ComandosPendientes()"); // No se pudo conectar con el servidor Hidra + return(false); + } + } + CMDPTES=false; + return(true); +} +//_____________________________________________________________________________________________________ +// Función: Arrancar +// +// Descripción: +// Contesta ante un comando de arrancar +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true siempre +//_____________________________________________________________________________________________________ +int Arrancar(TRAMA *trama,TRAMA *nwtrama) +{ + sprintf(nwtrama->parametros,"nfn=RESPUESTA_Arrancar\r"); + return(RespuestaEjecucionComando(trama,nwtrama,true)); +} +//_____________________________________________________________________________________________________ +// Función: Apagar +// +// Descripción: +// Apaga el cliente +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//_____________________________________________________________________________________________________ +int Apagar(TRAMA *trama,TRAMA *nwtrama) +{ + int res; + + sprintf(nwtrama->parametros,"nfn=RESPUESTA_Apagar\r"); + res=RespuestaEjecucionComando(trama,nwtrama,true); + strcpy(cmdshell,"shutdown -h now"); + system(cmdshell); + return(res); +} +//______________________________________________________________________________________________________ +// Función: Reiniciar +// +// Descripción: +// Reinicia el cliente +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//______________________________________________________________________________________________________ +int Reiniciar(TRAMA *trama,TRAMA *nwtrama) +{ + int res; + + sprintf(nwtrama->parametros,"nfn=RESPUESTA_Reiniciar\r"); + res=RespuestaEjecucionComando(trama,nwtrama,true); + strcpy(cmdshell,"shutdown -r now"); + system(cmdshell); + return(res); +} +//______________________________________________________________________________________________________ +// Función: Actualizar +// +// Descripción: +// Actualiza los datos de un ordenador como si volviera a solicitar la entrada en el sistema al servidor HIDRA +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//______________________________________________________________________________________________________ +int Actualizar() +{ + int res; + + res=InclusionClienteHIDRA(); + return(res); +} +//______________________________________________________________________________________________________ +// Función: CrearPerfilSoftware +// +// Descripción: +// Genera una imagen de una partición +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//_____________________________________________________________________________________________________ +int CrearPerfilSoftware(TRAMA*trama,TRAMA*nwtrama) +{ + int res=0; + char *wparticion=TomaParametro("par",trama->parametros); // Partición de donde se crear el perfil + char *widperfilsoft=TomaParametro("ifs",trama->parametros); // Perfil software a crear + char *widperfilhard=TomaParametro("ifh",trama->parametros); // Perfil hardware del ordenador + char *wnemonico=TomaParametro("nem",trama->parametros); // Nemónico del S.O. de la partición + + char *disco=(char*)ReservaMemoria(2); + sprintf(disco,"1"); // Siempre el disco 1 + + char pathperfil[250]; + sprintf(pathperfil,"%s/%s",HIDRACHEIMAGENES,wnemonico); // Path del perfil creado + + char fileperfil[64]; + sprintf(fileperfil,"PS%s_PH%s",widperfilsoft,widperfilhard); // Nombre de la imagen ( del perfil creado) + + char filemasterboot[64]; + sprintf(filemasterboot,"PS%s_PH%s.msb",widperfilsoft,widperfilhard); // Idem para el sector de arranque MBR + + int nem=Nemonico(wnemonico); + switch(nem){ + case 1: // MsDos + Log("Creando perfil software de un sistema MsDos ..."); + res=CrearPerfil(NULL,fileperfil,pathperfil,wparticion,Propiedades.iprepo); + break; + case 2:// Fat32 + Log("Creando perfil software de un sistema windows 98..."); + res=CrearPerfil(NULL,fileperfil,pathperfil,wparticion,Propiedades.iprepo); + break; + case 3:// NTFS (Windows 2000) + Log("Creando perfil software de un sistema windows 2000..."); + res=CrearPerfil(disco,fileperfil,pathperfil,wparticion,Propiedades.iprepo); + break; + case 4:// NTFS (Windows XP) + Log("Creando perfil software de un sistema windows XP..."); + res=CrearPerfil(disco,fileperfil,pathperfil,wparticion,Propiedades.iprepo); + break; + case 5: // Linux + Log("Creando perfil software de un sistema Linux..."); + res=CrearPerfil(disco,fileperfil,pathperfil,wparticion,Propiedades.iprepo); + break; + } + Log("Finalizada la creacion del perfil software"); + + int lon; + lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_CrearPerfilSoftware\r"); + lon+=sprintf(nwtrama->parametros+lon,"ifs=%s\r",widperfilsoft); + lon+=sprintf(nwtrama->parametros+lon,"ifh=%s\r",widperfilhard); + RespuestaEjecucionComando(trama,nwtrama,res); + + return(res); +} +//______________________________________________________________________________________________________ +// Función: CrearPerfil +// +// Descripción: +// Crea una imagen de una partición +// Parámetros: +// -disco Disco a clonar 1,2,3.. +// -fileimg Nombre de la imagen +// -pathimg Ruta de la imagen +// -particion Partición a clonar +// -iprepo Dirección IP del repositorio ( Si es la IP local el repositorio será la caché) +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//______________________________________________________________________________________________________ +int CrearPerfil(char* disco,char* fileimg,char* pathimg,char* particion,char*iprepo) +{ + int herror; + + sprintf(cmdshell,"%s/hidraCreateImageFromPartition",HIDRASCRIPTS); + sprintf(parametros," %s %s %s %s %s %s gzip","hidraCreateImageFromPartition",disco,particion,iprepo,"hdimages/pruebashidra/",fileimg); + + if(ndebug>3){ + sprintf(msglog,"Creando Perfil Software disco:%s, partición:%s, Repositorio:%s, Imagen:%s, Ruta:%s",disco,particion,Propiedades.iprepo,fileimg,"hdimages/pruebashidra"); + Log(msglog); + } + + herror=EjecutarScript(cmdshell,parametros,NULL); + if(herror){ + UltimoError(herror,"CrearPerfil()"); // Se ha producido algún error + return(false); + } + else + return(true); +} +//______________________________________________________________________________________________________ +// Función: Nemonico +// +// Descripción: +// Devuelve el código de un nemonico de S.O. +// Parámetros: +// -nem Nemonico del S.O. +// Devuelve: +// El código del nemónico +//______________________________________________________________________________________________________ +int Nemonico(char* nem) +{ + if(strcmp(nem,"MsDos")==0) + return(MsDos); + if(strcmp(nem,"Win98")==0) + return(Win98); + if(strcmp(nem,"Win2K")==0) + return(Win2K); + if(strcmp(nem,"WinXP")==0) + return( WinXP); + if(strcmp(nem,"Linux")==0) + return(Linux); + return(0); +} +//______________________________________________________________________________________________________ +// Función: RestaurarImagen +// +// Descripción: +// Restaura una imagen en una partición +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//______________________________________________________________________________________________________ +int RestaurarImagen(TRAMA*trama,TRAMA*nwtrama) +{ + int res=0; + char *wparticion=TomaParametro("par",trama->parametros); // partición de donde se crear el perfil + char *widimagen=TomaParametro("idi",trama->parametros); // Identificador de la imagen + char *widperfilsoft=TomaParametro("ifs",trama->parametros); // Perfil software a crear + char *widperfilhard=TomaParametro("ifh",trama->parametros); // Perfil hardware del ordenador + //char *widcentro=TomaParametro("idc",trama->parametros); // Identificador del Centro + //char *wtipopar=TomaParametro("tpa",trama->parametros); // Tipo de partición + char *wnemonico=TomaParametro("nem",trama->parametros); // Nemonico del S.O. contenido en la partición + //char *wswrestauraimg=TomaParametro("swr",trama->parametros); // Indica si la imagen a restaurar contiene un S.O. distinto al actual + char *widsoftincremental=TomaParametro("icr",trama->parametros); // Cadena con los identificadores de lsoftware incremental + char *wpathimagen=TomaParametro("pth",trama->parametros); // Indica si la imagen se descargar de la caché(cache) o del servidor(net) + if(wpathimagen=='\0') wpathimagen="1"; // Por defecto de caché + + char *disco=(char*)ReservaMemoria(2); + sprintf(disco,"1"); // Siempre el disco 1 + + char *compres=(char*)ReservaMemoria(10); + sprintf(compres,"gzip"); // Método de compresión + + char *mettran=(char*)ReservaMemoria(10); + sprintf(mettran,""); // Método de transferencia en blanco + + + int idxpath=atoi(wpathimagen); + if(!CACHEEXISTS) idxpath=2; // Sin no existe cache siempre desde el servidor + //if(wswrestauraimg=="O") + // res=reparticiona((int)wparticion,wtipopar); // Reparticiona si la imagen va a una partición distinta a la original + if(res==0){ + char pathperfil[250]; + if(idxpath==2){ + sprintf(pathperfil,"%s/%s",HIDRASRVIMAGENES,wnemonico); + } + else{ + if(idxpath==1){ + sprintf(pathperfil,"%s/%s",HIDRACHEIMAGENES,wnemonico); + } + } + char fileperfil[64]; + sprintf(fileperfil,"PS%s_PH%s",widperfilsoft,widperfilhard); // Nombre del fichero del perfil creado + char filemasterboot[64]; + sprintf(filemasterboot,"PS%s_PH%s.msb",widperfilsoft,widperfilhard); // Idem para el sector de arranque MBR + int nem=Nemonico(wnemonico); + switch(nem){ + case 1: + Log("Restaurando imagen MsDos..."); + //res=Restaurar_MSDos(fileperfil,pathperfil,wparticion); + break; + case 2: + Log("Restaurando imagen Windows 98..."); + char wgrupotrabajo[64]; + sprintf(wgrupotrabajo,"GrupoAula_%s",Propiedades.idaula); + //res=Restaurar_Windows9x(fileperfil,pathperfil,wparticion,Propiedades.nombreordenador,wgrupotrabajo); + break; + case 3: + Log("Restaurar imagen Windows 2000..."); + //res=Restaurar_WindowsNTFS(filemasterboot,fileperfil,pathperfil,wparticion,Propiedades.nombreordenador,"WINNT"); + if(widsoftincremental!="") + res=0; + //RestaurarIncrementales(wparticion,"WINNT",widsoftincremental,widperfilsoft,widperfilhard,wnemonico); + break; + case 4: + Log("Restaurar imagen Windows XP..."); + res=RestaurandoImagen(disco,compres,mettran,fileperfil,pathperfil,wparticion,Propiedades.iprepo); + //if(res){ + // RestaurandoMBR(disco,filemasterboot); + //if(res) + // ParcheandoWindows(Propiedades.nombreordenador,"WINDOWS"); + //} + break; + case 5: + Log("Restaurar imagen Linux..."); + //res=Restaurar_Linux(fileperfil, pathperfil,wparticion); + //if(wswrestauraimg=="O") + // cambiaFstab("disk://0:",wparticion,wparticion); + break; + } + // Toma la nueva configuración + char *parametroscfg=LeeConfiguracion(disco); + Log("Finalizada la restauracion de imagen"); + + int lon; + lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_RestaurarImagen\r"); + lon+=sprintf(nwtrama->parametros+lon,"cfg=%s\r",parametroscfg); + lon+=sprintf(nwtrama->parametros+lon,"idi=%s\r",widimagen); + lon+=sprintf(nwtrama->parametros+lon,"par=%s\r",wparticion); + RespuestaEjecucionComando(trama,nwtrama,res); + + return(true); + } + return(false); +} +//______________________________________________________________________________________________________ +// Función: RestaurandoImagen +// +// Descripción: +// Restaura na imagen en una partición +// Parámetros: +// -disco Disco a clonar 1,2,3.. +// -fileimg Nombre de la imagen +// -pathimg Ruta de la imagen +// -particion Partición a clonar +// -iprepo Dirección IP del repositorio ( Si es la IP local el repositorio será la caché) +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//____________________________________________________________________________________________________ +int RestaurandoImagen(char* disco,char* compres,char* mettran,char* fileimg,char* pathimg,char* particion,char*iprepo) +{ + int herror; + + sprintf(cmdshell,"%s/hidraRestorePartitionFromImage",HIDRASCRIPTS); + sprintf(parametros," %s %s %s %s %s %s.%s-%s%s","hidraRestorePartitionFromImage",disco,particion,iprepo,"hdimages/pruebashidra/",fileimg,compres,particion,mettran); + + if(ndebug>3){ + sprintf(msglog,"Restaurando Imagen disco:%s, partición:%s, Repositorio:%s, Imagen:%s.%s-%s%s Ruta:%s",disco,particion,Propiedades.iprepo,fileimg,compres,particion,mettran,"hdimages/pruebashidra/"); + Log(msglog); + } + + herror=EjecutarScript(cmdshell,parametros,NULL); + if(herror){ + UltimoError(herror,"RestaurandoImagen()"); // Se ha producido algún error + return(false); + } + else + return(true); +} + +//______________________________________________________________________________________________________ +// Función: ParticionaryFormatear +// +// Descripción: +// Modifica la tabla de particiones del sector de arranque master y formatea particiones +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//____________________________________________________________________________________________________ +int ParticionaryFormatear(TRAMA*trama,TRAMA*nwtrama) +{ + int res,i,parfor; + char* parametroscfg; + char ch[2],*parhdc[8]; + char *PrimaryPartitions=TomaParametro("ppa",trama->parametros); + char *LogicalPartitions=TomaParametro("lpa",trama->parametros); + char *HDCleanPartition=TomaParametro("hdc",trama->parametros); + + char *disco=(char*)ReservaMemoria(2); + sprintf(disco,"1"); // Siempre el disco 1 + + Log("Creando o modificando tabla de particiones"); + res=Particionar(disco,PrimaryPartitions,LogicalPartitions); // Creando las particiones + if(res){ + strcpy(ch,";"); // Caracter delimitador + parfor=SplitParametros(parhdc,HDCleanPartition,ch); + for(i = 0; iparametros,"nfn=RESPUESTA_ParticionaryFormatear\r"); + lon+=sprintf(nwtrama->parametros+lon,"cfg=%s\r",parametroscfg); + RespuestaEjecucionComando(trama,nwtrama,res); + + return(res); +} +//______________________________________________________________________________________________________ +// Función: Particionar +// +// Descripción: +// Modifica la tabla de particiones del sector de arranque master pero SIN formatear ninguna partición +// Parámetros: +// - PrParticion: Cadena con la sintaxis de particionado de las particiones primarias +// - LoParticion: Cadena con la sintaxis de particionado de las particiones secundarias +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//______________________________________________________________________________________________________ +int Particionar(char* disco,char* PrParticion,char* LoParticion) +{ + if (strlen(PrParticion)>0){ + if(Particionando(disco,PrParticion,"hidraCreatePrimaryPartitions")){ // Particiones Primarias + if (strlen(LoParticion)>0) + return(Particionando(disco,PrParticion,"hidraCreateLogicalPartitions")); // Particiones Logicas + else + return(true); + } + else + return(false); + } + if (strlen(LoParticion)>0) + return(Particionando(disco,PrParticion,"hidraCreateLogicalPartitions")); + else + return(false); +} +//______________________________________________________________________________________________________ +// Función: Particionando +// +// Descripción: +// Modifica la tabla de particiones del sector de arranque master pero SIN formatear ninguna partición +// Parámetros: +// - disco: Disco en el que se modificará la tabla de particiones 1,2,3.. +// - SintaxParticion: Cadena con la sintaxis de particionado de las particiones primarias +// - script: Nombre del script que se ejecutará +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +// Especificaciones: +// Esta función es auxiliar de la anterior y es llamda por esta en dos ocasiones, para las particiones Primarias y Lógicas +//______________________________________________________________________________________________________ +int Particionando(char* disco,char* stxParticion,char* script) +{ + int herror; + + sprintf(cmdshell,"%s/%s",HIDRASCRIPTS,script); + sprintf(parametros," %s %s %s",script,disco,stxParticion); + if(ndebug>1){ + sprintf(msglog,"Modificando tabla de particiones:%s disco:%s, cadena:%s",script,disco,stxParticion); + Log(msglog); + } + herror=EjecutarScript(cmdshell,parametros,NULL); + if(herror){ + UltimoError(herror,"Particionar()"); // Se ha producido algún error + return(false); + } + else + return(true); +} +//______________________________________________________________________________________________________ +// Función: Formatear +// +// Descripción: +// Formatea una partición +// Parámetros: +// - disco: Número del disco +// - particion: Número de partición a formatear +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +//______________________________________________________________________________________________________ +int Formatear(char* disco,char* particion) +{ + int herror; + + sprintf(cmdshell,"%s/hidraFormat",HIDRASCRIPTS); + sprintf(parametros," %s %s %s","hidraFormat",disco,particion); + herror=EjecutarScript(cmdshell,parametros,NULL); + if(herror){ + UltimoError(herror,"Formatear()"); // Se ha producido algún error + return(false); + } + return(true); +} +//______________________________________________________________________________________________________ +// Función: SetCachePartitionSize +// +// Descripción: +// Dimensiona el tamaño de la caché +// Parámetros: +// - t : Tamaño a asignar de la caché +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +// ________________________________________________________________________________________________________ +int SetCachePartitionSize(int t) +{ + return(true); +} +//___________________________________________________________________________________________________ +// +// +//______________________________________________________________________________________________________ +// Función: AutoClienteHidra +// +// Descripción: +// Ejecuta un fichero autoexec preparado para el cliente +// ________________________________________________________________________________________________________ +int AutoexecClienteHidra() +{ + sprintf(fileini,"/comandos/INI_%s",Propiedades.IPlocal); // Nombre del fichero autoexec + if(ExisteFichero(fileini)){ + if(LoadTextFile(fileini)){ // Lee fichero autoexec + GestionTramas(trama); // Analiza la trama + } + else{ + UltimoError(6,"AutoexecClienteHidra()"); + return(false); + } + } + return(true); +} +//______________________________________________________________________________________________________ +// Función: LeeConfiguracion +// +// Descripción: +// Recupera la configuración de particiones del ordenador +// Parámetros: +// disco: Disco a analizar 1,2,3.. +// Devuelve: +// Una cadena con la configuración del cliente (ver manual) +// ________________________________________________________________________________________________________ +char* LeeConfiguracion(char* disco) +{ + int herror; + char *cadenaparticiones; + char *nomso; + + cadenaparticiones=(char*)ReservaMemoria(LONGITUD_SCRIPTSALIDA); + sprintf(cmdshell,"%s/hidraListPrimaryPartitions",HIDRASCRIPTS); + sprintf(parametros," %s %s","hidraListPrimaryPartitions",disco); + herror=EjecutarScript(cmdshell,parametros,cadenaparticiones); + if(herror){ + UltimoError(herror,"LeeConfiguracion()"); // Se ha producido algún error + return(NULL); + } + struct s_Particiones *tbcfg[MAXPARTICIONES]; + char *duplasparticiones[MAXPARTICIONES],*duplaparticion[2]; + + int iPar=SplitParametros(duplasparticiones,cadenaparticiones," "); // Caracter separatorio de los elementos de un item + int i,j; + for( i = 0; itipopart,duplaparticion[0]); // Tipo de partición + strcpy(tbcfg[i]->tamapart,duplaparticion[1]); // Tamaño de partición + sprintf(tbcfg[i]->numpart,"%d",i+1); // Número de partición + + for(j=0;jtiposo,tiposos[j].tiposo); // Nombre S.O. + strcpy(tbcfg[i]->nombreso,nomso); // Nombre completo S.O. + } + else{ + strcpy(tbcfg[i]->tiposo,""); // Nombre S.O. + strcpy(tbcfg[i]->nombreso,""); // Nombre completo S.O. + } + break; + } + } + } + char *cfg=ReservaMemoria(LONGITUD_CONFIGURACION); + if(!cfg){ + UltimoError(1,"LeeConfiguracion()"); + return(NULL); + } + int lon=0; + for( i = 0; itiposo); + lon+=sprintf(cfg+lon,"tipopart=%s\n",tbcfg[i]->tipopart); + lon+=sprintf(cfg+lon,"tamapart=%s\n",tbcfg[i]->tamapart); + lon+=sprintf(cfg+lon,"numpart=%s\n",tbcfg[i]->numpart); + lon+=sprintf(cfg+lon,"nombreso=%s\t",tbcfg[i]->nombreso); + } + return(cfg); +} +//______________________________________________________________________________________________________ +// Función: TomaNomSO +// +// Descripción: +// Recupera el nombre del sistema operativo instalado en una partición +// Parámetros: +// disco: Disco 1,2,3.. +// particion: Número de la partición +// Devuelve: +// Una cadena con el nombre del S.O. +// ________________________________________________________________________________________________________ +char* TomaNomSO(char*disco,int particion) +{ + int herror,lon; + char *infosopar; + char* sover[2]; + char ch[2]; + + infosopar=(char*)ReservaMemoria(LONGITUD_SCRIPTSALIDA); // Información del S.O. de la partición + + sprintf(cmdshell,"%s/hidraOSVersion",HIDRASCRIPTS); + sprintf(parametros," %s %s %d","hidraOSVersion",disco,particion); + herror=EjecutarScript(cmdshell,parametros,infosopar); + + if(herror){ + UltimoError(herror,"TomaNomSO()"); // Se ha producido algún error + return(NULL); + } + if(strlen(infosopar)==0) return(NULL); // NO Existe S.O. en la partición + strcpy(ch,":");// caracter delimitador (dos puntos) + lon=SplitParametros(sover,infosopar,ch); + return(sover[1]); +} +//______________________________________________________________________________________________________ +// Función: InventarioHardware +// +// Descripción: +// Recupera la configuración de hardware del ordenador +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +// Especificaciones: +// Lo que se envía al servidor es una cadena con el formato de salida del script que ejecuta +// está función. (Vease scripts hidraHardwareInfo) +// ________________________________________________________________________________________________________ +int InventarioHardware(TRAMA *trama,TRAMA *nwtrama) +{ + int herror,res; + char *parametroshrd; + + parametroshrd=(char*)ReservaMemoria(LONGITUD_SCRIPTSALIDA); + sprintf(cmdshell,"%s/hidraHardwareInfo",HIDRASCRIPTS); + herror=EjecutarScript (cmdshell,NULL,parametroshrd); + if(herror){ + UltimoError(herror,"InventarioHardware()"); // Se ha producido algún error + } + res=(herror==0); // Si se ha producido algún error el resultado de la ejecución de error + + int lon; + lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_TomaHardware\r"); + lon+=sprintf(nwtrama->parametros+lon,"hrd=%s\r",parametroshrd); + RespuestaEjecucionComando(trama,nwtrama,res); + + return(res); +} +//______________________________________________________________________________________________________ +// Función: TomaConfiguracion +// +// Descripción: +// Toma la configuración de particiones de un ordenador +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +// ________________________________________________________________________________________________________ +int TomaConfiguracion(TRAMA *trama,TRAMA *nwtrama) +{ + char* parametroscfg; + + char *disco=(char*)ReservaMemoria(2); + sprintf(disco,"1"); // Siempre el disco 1 + + parametroscfg=LeeConfiguracion(disco); + + int lon; + lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_TomaConfiguracion\r"); + lon+=sprintf(nwtrama->parametros+lon,"cfg=%s\r",parametroscfg); + RespuestaEjecucionComando(trama,nwtrama,true); + + return(true); +} +//______________________________________________________________________________________________________ +// Función: ExecShell +// +// Descripción: +// Ejecuta un script de la Shell +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// Devuelve: +// true si el proceso fue correcto o false en caso contrario +// ________________________________________________________________________________________________________ +int ExecShell(TRAMA *trama,TRAMA *nwtrama) +{ + FILE* f; + long lSize; + int herror,res; + + char* wscript=TomaParametro("scp",trama->parametros); // Código del script + char* codigo=URLDecode(wscript); // Decodifica el código recibido con formato URLCode + + sprintf(filecmdshell,"%s/%s",HIDRASCRIPTS,"_hidrascript_"); + f = fopen(filecmdshell,"wt"); // Abre fichero de script + if(f==NULL) + res=false; // Error de apertura del fichero de configuración + else{ + lSize=strlen(codigo); + fwrite(codigo,1,lSize,f); // Escribe el código a ejecutar + fclose(f); + + sprintf(cmdshell,"/bin/chmod"); // Da permiso de ejecución al fichero + sprintf(parametros," %s %s %s","/bin/chmod","+x",filecmdshell); + + herror=EjecutarScript(cmdshell,parametros,NULL); + if(herror){ + UltimoError(herror,"ExecShell()"); // Se ha producido algún error + res=false; + } + else{ + sprintf(cmdshell,"%s",filecmdshell); // Ejecución el fichero de script creado + //int herror=EjecutarScript(cmdshell,NULL,NULL); + int herror=system(cmdshell); + if(herror){ + UltimoError(herror,"ExecShell()"); // Se ha producido algún error + res=false; + } + } + } + + char *disco=(char*)ReservaMemoria(2); + sprintf(disco,"1"); // Siempre el disco 1 + char* parametroscfg=LeeConfiguracion(disco); + int lon; + + lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_ExecShell\r"); + lon+=sprintf(nwtrama->parametros+lon,"cfg=%s\r",parametroscfg); + RespuestaEjecucionComando(trama,nwtrama,res); + + return(res); +} +//______________________________________________________________________________________________________ +// Función: URLDecode +// +// Descripción: +// Decodifica una cadena codificada con UrlEncode +// Parámetros: +// - src: La cadena a decodificar +// Devuelve: +// La cadena decodificada +// ________________________________________________________________________________________________________ +char* URLDecode(char *src) +{ + const char *p = src; + char code[3] = {0}; + unsigned long ascii = 0; + char *end = NULL; + char *dest,*cad; + + dest=(char*)ReservaMemoria(strlen(src)); // Reserva buffer para la cadena + cad=dest; + while(*p){ + if(*p == '%'){ + memcpy(code, ++p, 2); + ascii = strtoul(code, &end, 16); + *dest++ = (char)ascii; + p += 2; + } + else + *dest++ = *p++; + } + return(cad); +} +//______________________________________________________________________________________________________ +// Función: RespuestaEjecucionComando +// +// Descripción: +// Envia una respuesta a una ejecucion de comando al servidor Hidra +// Parámetros: +// - trama: Trama recibida con las especificaciones del comando +// - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede +// - res: Resultado de la ejecución (true si la ejecución es correcta y false en caso contrario) +// Devuelve: +// true si la respuesta se envía correctamente al servidor +// ________________________________________________________________________________________________________ +int RespuestaEjecucionComando(TRAMA* trama, TRAMA *nwtrama, int res) +{ + int idsuceso=0; + char *widsuceso=TomaParametro("ids",trama->parametros); + if(widsuceso) idsuceso=atoi(widsuceso); + int lon; + lon=strlen(nwtrama->parametros); + lon+=sprintf(nwtrama->parametros+lon,"ids=%d\r",idsuceso); // Identificador del suceso + char descrierror[250]; + if (res){ // Resultado satisfactorio + lon+=sprintf(nwtrama->parametros+lon,"res=%s\r","1"); // Resultado de la ejecucin del comando + sprintf(descrierror,"%s "," "); + lon+=sprintf(nwtrama->parametros+lon,"der=%s\r",descrierror); // Dscripcin del error si lo ha habido + } + else{ // Algún error + lon+=sprintf(nwtrama->parametros+lon,"res=%s\r","2"); // Resultado de la ejecucin del comando + sprintf(descrierror,"Error.-(%s) en modulo %s",e.msg,e.modulo); + lon+=sprintf(nwtrama->parametros+lon,"der=%s\r",descrierror); // Descripción del error si lo ha habido + } + if(AbreConexionTCP()){ + if(!EnviaTramasHidra(sock,nwtrama)){ + UltimoError(21,"RespuestaEjecucionComando()"); + return(false); + } + if(!RecibeTramasHidra(sock,trama)){ + UltimoError(22,"RespuestaEjecucionComando()"); + return(false); + } + CierraConexionTCP(); + GestionTramas(trama); // Analiza la trama + } + else{ + UltimoError(2,"RespuestaEjecucionComando()"); + return(false); + } + return(true); +} + +//*********************************************************************************************************************** +// PROGRAMA PRINCIPAL +//*********************************************************************************************************************** +int main(int argc, char *argv[]) +{ + //pid_t pid; + +/* + ndebug=3; + strcpy(szPathFileLog,"hidrac_0.0.0.0.log"); + sprintf(cmdshell,"/var/EAC/hidra/scripts/hidraCreatePrimaryPartitions"); + sprintf(parametros," %s %s %s","hidraCreatePrimaryPartitions","1","NTFS:3333333"); + char* retorno=(char*)ReservaMemoria(2000); + int herror=EjecutarScript(cmdshell,parametros,retorno); + Log(retorno); + exit(herror); +*/ + // Validación de argumentos y lectura del fichero de configuración + if(!ValidacionParametros(argc,argv)) + exit(EXIT_FAILURE); + else{ + if(!CrearArchivoLog(szPathFileLog)) + exit(EXIT_FAILURE); + else + if(!LeeFileConfiguracion(szPathFileCfg)){ // Toma parámetros de configuracion + UltimoError(13,"Main()"); + exit(EXIT_FAILURE); + } + } + // Guarda datos básicos del cliente + strcpy(Propiedades.servidorhidra,Servidorhidra); + strcpy(Propiedades.puerto,Puerto); + strcpy(Propiedades.idordenador,"0"); + if(!TomaIPlocal()){ // Error al recuperar la IP local + UltimoError(0,"Main()"); + exit(EXIT_FAILURE); + } + strcpy(Propiedades.IPlocal,IPlocal); + + Log("Abriendo sesión en el servidor Hidra"); + if(InclusionClienteHIDRA()){ // El cliente ha abierto sesión correctamente + if(strcmp(Propiedades.idordenador,"0")==0){ // Ha habido algún problema al inciar sesión + UltimoError(0,"Main()"); + exit(EXIT_FAILURE); + } + Log("Cliente hidra iniciado"); + Log("Ejecución de comandos Autoexec"); + if(!AutoexecClienteHidra()){ // Ejecución fichero autoexec + UltimoError(0,"Main()"); + exit(EXIT_FAILURE); + } + Log("Procesa comandos pendientes"); + ComandosPendientes(); // Bucle para procesar comandos pendientes + Log("Acciones pendientes procesadas"); + Log("Disponibilidad para comandos interactivos activada ..."); + ProcesaComandos(); // Bucle para procesar comando s interactivos + Log("Disponibilidad para comandos interactivos d esactivada..."); + } + else{ + UltimoError(0,"Main()"); + exit(EXIT_FAILURE); + } + exit(0); +} + + + + diff --git a/Hidra/hidrac/fuentes/hidrac.h b/Hidra/hidrac/fuentes/hidrac.h new file mode 100644 index 00000000..bb1e1b76 --- /dev/null +++ b/Hidra/hidrac/fuentes/hidrac.h @@ -0,0 +1,289 @@ +// *************************************************************************************************************************************** +// Aplicacin HIDRA (Gestin y Admistracin de aulas de informtica) +// Copyright 2003-2007 Jos Manuel Alonso. Todos los derechos reservados. +// Fichero: hidrax.h +// Descripcin: +// Fichero de cabecera de hidrax.cpp +// *************************************************************************************************************************************** +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LEER 0 +#define ESCRIBIR 1 + +#define LONGITUD_SCRIPTSALIDA 1024 // Longitud máima de la informacin devuelta por un script +#define LONGITUD_PARAMETROS 4048 // Longitud m?ima de la informacin de la trama (parametros) +#define LONGITUD_TRAMA LONGITUD_PARAMETROS+11 // Longitud m?ima de la trama completa +#define LONGITUD_CONFIGURACION 1024 // Longitud mxima de las configuraciones de particin +#define MAX_NUM_CSADDRS 20 +#define MAX_INTERFACE_LIST 20 +#define MAXCNX 5 // Mximos intentos de conexión al servidor HIDRA +#define MAXITEMS 100 +#define MAXHTMLMNU 4000 +#define MAXPARTICIONES 24 +#define MAXINFOSO 5 // Numero máximo de nemonicos enla inforamción del S.O. de una partición +#define MAXARGS 16 // Numero máximo de argumentos enviados a un scripts +#define LONSTD 512 // Longitud de memoria estandar +#define LONSTDC 256 // Longitud de memoria estandar corta + +#define PUERTOMINUSER 20000 +#define PUERTOMAXUSER 60000 + +#define TRUE 1 +#define FALSE 0 + +#define true 1 +#define false 0 + +#define SOCKET_ERROR (-1) +#define INVALID_SOCKET (SOCKET)(~0) + +typedef unsigned short WORD; +typedef int BOOL; +typedef char BYTE; +typedef int SOCKET; + +typedef struct{ // EstructUra de la trama recibida + char arroba; // cabecera de la trama + char identificador[9]; // identificador de la trama + char ejecutor; // ejecutor de la trama 1=el servidor hidra 2=el cliente hidra 3=el repositorio + char parametros[LONGITUD_PARAMETROS]; // Contenido de la trama (par?etros) +}TRAMA; + +TRAMA trama[1]; + +char IPlocal[20]; // Ip local +char Servidorhidra[20]; // IP servidor HIDRA +char Puerto[20]; // Puerto Unicode + +char szPathFileCfg[128]; +char szPathFileLog[128]; + +//___________________________________________________________________________________________________ +// Variables y estructuras +//___________________________________________________________________________________________________ + +char cmdshell[LONSTD]; +char parametros[LONSTD]; +char* argumentos[MAXARGS]; +char msglog[LONSTD]; +char msgcon[LONSTD]; +char filecmdshell[LONSTDC]; +char filemenu[LONSTDC]; +char fileitem[LONSTDC]; +char fileini[LONSTDC]; +char filecmd[LONSTDC]; + +struct excepcion { + int herror; + char msg[LONSTDC]; + char modulo[LONSTDC]; +}; +struct excepcion e; + +int ndebug=1; // Nivel de debuger por defecto + +// Nemónicos +int MsDos=1; +int Win98=2; +int Win2K=3; +int WinXP=4; +int Linux=5; + +BOOL PROCESO=true; // Indicador de la actividad del proceso principal +BOOL CACHEEXISTS; // Indica si existe cache + +char HIDRACHEIMAGENES[LONSTDC]; // Path al directorio donde están las imágenes (en la caché) +char HIDRASRVIMAGENES[LONSTDC]; // Path al directorio hidra donde están las imágenes (en el repositorio) +char HIDRASRVCMD[LONSTDC]; // Path del directorio del repositorio donde se depositan los comandos para el cliente hidra +char HIDRASCRIPTS[LONSTDC]; // Path al directorio donde están los scripts de hidra (en el cliente hidra) + +int HIDRAVER; // Versión Hidra +int TPAR ; // Tamaño de la particin + +SOCKET sock; // Socket + +struct s_CabMnu { + char resolucion[2]; // Resolucin de pantalla + char titulo[LONSTDC]; // Titulo del menu + char coorx[4]; // Coordenada x + char coory[4]; // Coordenada y + char modalidad[2]; // modalidad ( numero de items por linea ) + char scoorx[4]; // Coordenada x // Menu privado + char scoory[4]; // Coordenada y + char smodalidad[LONSTDC]; // modalidad ( numero de items por linea ) + char htmmenupub[64]; // Nombre del fichero que contiene el html del menu (público) + char htmmenupri[64]; // Nombre del fichero que contiene el html del menu (privado) +} CabMnu; // Estructura con los datos de los menús + +BOOL swmnu=false; // Indicador de menu asignado + +struct s_Item{ + char idaccionmenu[16]; // Identificador del item a ejecutar + char urlimg[64]; // Nombre de la imagen de fonfo del botn + char literal[LONSTDC]; // Literal del item + char tipoitem[2]; // Tipo de otem ( público o privado) + char tipoaccion[2]; // Tipo de accin que ejecuta el item +} ; + +struct s_Propiedades { + char idordenador[16]; // Identificador del ordenador + char nombreordenador[64]; // Nombre del ordenador + char idaula[16]; // Identificador del aula + char servidorhidra[64]; // IP del servidor HUDRA + char puerto[16]; // Puerto + char iprepo[16]; // Direción IP repositorio + char puertorepo[16]; // Puerto + char idperfilhard[16]; // Identificador del perfil hardware + char IPlocal[16]; // Ip local +} Propiedades; // Estructura con los datos del odenador + +struct s_Particiones{ + char tiposo[64]; // Tipo de sistema operativo + char tipopart[16]; // Tipo de particin + char tamapart[16]; // Tamao de la particin + char numpart[5]; // Nmero de la particin + char nombreso[64]; // Nombre del S.O. +}; + +struct s_Hardware{ + char nemonico[4]; // Tipo de sistema operativo + char tipo[45]; // Tipo de hardware + char codigovalor[256]; // Codigo o descripcion +} +; +struct tiposo { + char *tipopart; + char *tiposo; + char *nombreso; +}; +struct tiposo tiposos[] = { + {"BIGDOS", "MsDos","MsDos"}, + {"NTFS","Windows NT Platafom","Windows 2000,XP,2003"}, + {"FAT32","Windows","Windos 98,SE,Millenium"}, + {"EXT","Extendida","Extendida"}, + {"EXT3","Linux","Linux"}, + {"EXT2","Linux","Linux"}, + {"VFAT","VFAT","VFAT"}, + {"CACHE","CACHE","CACHE"}, + {"UNKNOWN","UNKNOWN","UNKNOWN"}, + {"EMPTY","Libre","Libre"}, + {"LINUX-SWAP","","Linux-swap"}}; + +int ntiposo = sizeof (tiposos) / sizeof (struct tiposo); + +struct s_Item tbMenu[MAXITEMS]; // Tabla con los items del menu +int contitems; // Contador items del menu + +BOOL PRCCMD; // Indicador de comandos interactivos +BOOL CMDPTES; // Indicador de comandos pendientes + +//char modulo[64]; // Nombre de la funcin donde se produce el error + +BOOL aut = false; // Variable para controlar el acceso al menu de administracion + + +char* tbErrores[]={"000-Se han generado errores. No se puede continuar la ejecución de este módulo",\ + "001-No hay memoria suficiente para el buffer",\ + "002-No se puede establecer conexión con el servidor Hidra",\ + "003-El fichero especificado no existe o bien no puede crearse o abrirse",\ + "004-Comando Error",\ + "005-El fichero est vacio",\ + "006-Error en la ejecución del fichero autoexec",\ + "007-Error en la recuperacion del Menu principal",\ + "008-No hay espacio reservado para la cache en este disco",\ + "009-Ha ocurrido algún error generando el perfil software",\ + "010-IPlocal, NO se ha definido este parámetro",\ + "011-IPhidra, NO se ha definido este parámetro",\ + "012-Puerto, NO se ha definido este parámetro",\ + "013-NO existe fichero de configuración o contiene un error de sintaxis",\ + "014-Fallo de sintaxis en los parámetros: Debe especificar -f nombre_del_fichero_de_configuración",\ + "015-No se ha podido crear socket para comunicación con el repositorio",\ + "016-No se ha podido comunicar con el repositorio",\ + "017-No existe Menu principal",\ + "018-No se ha podido recuperar la configuración hardware del ordenador",\ + "019-El cliente no se ha podido incluir en el sistema por un fallo en la conexión con el Servidor Hidra",\ + "020-No se ha podido crear la carpeta en el repositorio",\ + "021-Error en el envío de tramas al servidor Hidra",\ + "022-Error en la recepción de tramas desde el servidor Hidra",\ + "023-Error desconocido",\ + }; + +#define MAXERROR 23 // Error máximo cometido + +// Prototipos de funciones +char* Desencriptar(char *); +char* Encriptar(char *); +int ValidacionParametros(int,char**); +int CrearArchivoLog(char*); +int LeeFileConfiguracion(); +void Log(char*); +void UltimoError(int,char*); +void INTROaFINCAD(char*); +char* TomaParametro(char*,char*); +int SplitParametros(char**,char*, char*); + +int EjecutarScript (char*,char* ,char*); +char* ReservaMemoria(int); + +SOCKET TCPConnect(char *,char* ); +void TCPClose(SOCKET); +int AbreConexionTCP(void); +void CierraConexionTCP(void); +int EnviaTramasHidra(SOCKET,TRAMA*); +int RecibeTramasHidra(SOCKET,TRAMA*); +int TCPWrite(SOCKET ,TRAMA*); +int TCPRead(SOCKET ,TRAMA*); +SOCKET UDPConnect(); +int EnviaTramaRepo(SOCKET,TRAMA*,char*,char*); +int RecibeTramaRepo(SOCKET); + +long CreateTextFile(char*,char*); +int ExisteFichero(char*); +int RemoveFile(char *); +int LoadTextFile(char *); + +int ProcesaComandos(); +int DisponibilidadComandos(int); +int GestionTramas(TRAMA *); + +int Cortesia(); +int NoComandosPtes(); +int TomaIPlocal(); +int InclusionClienteHIDRA(); +int RESPUESTA_InclusionClienteHIDRA(TRAMA*); +int ComandosPendientes(void); +int Arrancar(TRAMA *,TRAMA *); +int Apagar(TRAMA*,TRAMA*); +int Reiniciar(TRAMA*,TRAMA*); +int Actualizar(); +int CrearPerfilSoftware(TRAMA*,TRAMA*); +int CrearPerfil(char*,char*,char*,char*,char*); +int Nemonico(char*); +int RestaurarImagen(TRAMA*,TRAMA*); +int RestaurandoImagen(char*,char*,char*,char*,char*,char*,char*); +int ParticionaryFormatear(TRAMA*,TRAMA*); +int Particionar(char*,char*,char* ); +int Particionando(char*,char*,char*); +int Formatear(char*,char*); +int SetCachePartitionSize(int); +int AutoexecClienteHidra(void); +char* LeeConfiguracion(char*); +char* TomaNomSO(char*,int); +int InventarioHardware(TRAMA *,TRAMA *); +int TomaConfiguracion(TRAMA *,TRAMA *); +int RespuestaEjecucionComando(TRAMA* , TRAMA *, int); +int ExecShell(TRAMA *,TRAMA *); +char* URLDecode(char*); diff --git a/Hidra/hidrarepos/fuentes/hidrarepos.cpp b/Hidra/hidrarepos/fuentes/hidrarepos.cpp new file mode 100644 index 00000000..cf2a7c5d --- /dev/null +++ b/Hidra/hidrarepos/fuentes/hidrarepos.cpp @@ -0,0 +1,1159 @@ +// ************************************************************************************************************* +// Aplicacin HIDRA +// Copyright 2003-2007 Jos Manuel Alonso. Todos los derechos reservados. +// Fichero: hidrarepos.cpp +// +// Descripcin: +// Este fichero implementa el servicio de repositorio de la aplicacin hidra. +// ************************************************************************************************************** +#include "hidrarepos.h" +#include "encriptacion.c" +// ________________________________________________________________________________________________________ +// Funcin�:RegistraLog +// +// Descripcin�: +// Esta funcin� registra los evento de errores en un fichero log +// Parametros: +// - msg : Mensage de error +// - swerrno: Switch que indica que recupere literal de error del sistema +// ________________________________________________________________________________________________________ +void RegistraLog(char *msg,int swerrno) +{ + time_t rawtime; + struct tm * timeinfo; + + time ( &rawtime ); + timeinfo = gmtime(&rawtime); + + FLog=fopen(szPathFileLog,"at"); + if(swerrno) + fprintf (FLog,"%02d/%02d/%d %02d:%02d ***%s:%s\n",timeinfo->tm_mday,timeinfo->tm_mon+1,timeinfo->tm_year+1900,timeinfo->tm_hour,timeinfo->tm_min,msg,strerror(errno)); + else + fprintf (FLog,"%02d/%02d/%d %02d:%02d ***%s\n",timeinfo->tm_mday,timeinfo->tm_mon+1,timeinfo->tm_year+1900,timeinfo->tm_hour,timeinfo->tm_min,msg); + fclose(FLog); +} + +//________________________________________________________________________________________________________ +// Funcinn: TomaConfiguracion +// +// Descripcinn: +// Esta funcinn lee el fichero de configuracinn del programa hidralinuxcli y toma los parametros +// Parametros: +// - pathfilecfg : Ruta al fichero de configuracinn +//________________________________________________________________________________________________________ +int TomaConfiguracion(char* pathfilecfg) +{ + long lSize; + char * buffer,*lineas[100],*dualparametro[2]; + char ch[2]; + int i,numlin,resul; + + if(pathfilecfg==NULL) exit(EXIT_FAILURE);; // Nombre del fichero en blanco + + Fconfig = fopen ( pathfilecfg , "rb" ); + if (Fconfig==NULL) exit(EXIT_FAILURE);; + fseek (Fconfig , 0 , SEEK_END); // Obtiene tamaño del fichero. + lSize = ftell (Fconfig); + rewind (Fconfig); + buffer = (char*) malloc (lSize); // Toma memoria para el buffer de lectura. + if (buffer == NULL) exit(EXIT_FAILURE);; + fread (buffer,1,lSize,Fconfig); // Lee contenido del fichero + fclose(Fconfig); + + //inicializar + IPlocal[0]=(char)NULL; + servidorhidra[0]=(char)NULL; + Puerto[0]=(char)NULL; + + strcpy(ch,"\n");// caracter delimitador ( salto de linea) + numlin=split_parametros(lineas,buffer,ch); + for (i=0;icliente.sin_addr))==0){ // Se trata del servidor hidra + pthread_mutex_unlock(&guardia); + return(true); + } + + // Abre conexion con base de datos + if(!db.Open(usuario,pasguor,datasource,catalog)){ // error de conexion + db.GetErrorErrStr(ErrStr); + pthread_mutex_unlock(&guardia); + return(false); + } + + sprintf(sqlstr,"SELECT ip FROM ordenadores WHERE ip='%s' ",inet_ntoa(trmInfo->cliente.sin_addr)); + if(!db.Execute(sqlstr,tbl)){ // Error al leer + db.GetErrorErrStr(ErrStr); + pthread_mutex_unlock(&guardia); + db.Close(); + return(false); + } + + if(tbl.ISEOF()){ // No existe el cliente + db.Close(); + pthread_mutex_unlock(&guardia); + return(false); + } + db.Close(); + pthread_mutex_unlock(&guardia); + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + return(true); +} +//___________________________________________________________________________________________________ +// Funcin: inclusion_REPO +// +// Descripcin: +// Abre una sesin en el servidor Hidra +//___________________________________________________________________________________________________ +int inclusion_REPO() +{ + TRAMA *trama; + SOCKET sock; + // Compone la trama + int lon; + + trama=(TRAMA*)malloc(LONGITUD_TRAMA); + if(!trama) + return(false); + lon=sprintf(trama->parametros,"nfn=inclusion_REPO\r"); // Nombre de la funcin a ejecutar en el servidor HIDRA + lon+=sprintf(trama->parametros+lon,"iph=%s\r",IPlocal); // Ip del ordenador + + sock=Abre_conexion(servidorhidra,puerto); + if(sock==INVALID_SOCKET) { + printf("Error de socket"); + return(false); +} + envia_tramas(sock,trama); + recibe_tramas(sock,trama); + close(sock); + RESPUESTA_inclusionREPO(trama); + return(true); +} +// ________________________________________________________________________________________________________ +// Funcin: Abre_conexion +// +// Descripcin: +// Crea un socket y lo conecta a un servidor +// Parmetros: +// - ips : La direccin IP del servidor +// - port : Puerto para la comunicacin +// Devuelve: +// - El socket o nulo dependiendo de si se ha establecido la comunicacin +// ________________________________________________________________________________________________________ +SOCKET Abre_conexion(char *ips,int wpuerto) +{ + struct sockaddr_in server; + SOCKET s; + // Crea el socket y se intenta conectar + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (s == INVALID_SOCKET){ + return (INVALID_SOCKET); + } + server.sin_family = AF_INET; + server.sin_port = htons((short)wpuerto); + server.sin_addr.s_addr = inet_addr(ips); + if (connect(s, (struct sockaddr *)&server, sizeof(server)) == INVALID_SOCKET) + return (INVALID_SOCKET); + return(s); // Conectado +} +//___________________________________________________________________________________________________ +// +// Enva tramas al servidor HIDRA +//___________________________________________________________________________________________________ +int envia_tramas(SOCKET s,TRAMA *trama) +{ + trama->arroba='@'; // cabecera de la trama + strcpy(trama->identificador,"JMMLCAMDJ"); // identificador de la trama + trama->ejecutor='1'; // ejecutor de la trama 1=el servidor hidra 2=el cliente hidra + + int nLeft,idx,ret; + Encriptar((char*)trama); + nLeft = strlen((char*)trama); + idx = 0; + while(nLeft > 0){ + ret = send(s,(char*)&trama[idx], nLeft, 0); + if (ret == 0) + break; + else + if (ret == SOCKET_ERROR){ + return(false); + } + nLeft -= ret; + idx += ret; + } + return(true); +} +//___________________________________________________________________________________________________ +// +// Recibe tramas desde el servidor HIDRA +//___________________________________________________________________________________________________ +int recibe_tramas(SOCKET s,TRAMA *trama) +{ + int ret; + + ret = recv(s,(char*)trama,LONGITUD_TRAMA,0); + if (ret == 0) // Conexin cerrada por parte del cliente (Graceful close) + return (false); + else{ + if (ret == SOCKET_ERROR){ + return (false); + } + else{ // Datos recibidos + Desencriptar((char*)trama); + trama->parametros[ret-11]=(char)NULL; // Coloca caracter fin de cadena en trama + return(true); + } + } +} +//_______________________________________________________________________________________________________________ +// +// Gestiona la conexion con un cliente que sea Hidra para el servicio de repositorio +//_______________________________________________________________________________________________________________ +LPVOID GestionaServicioRepositorio(LPVOID lpParam) +{ + TramaRepos *trmInfo=(TramaRepos *)lpParam; + + Desencriptar((char*)&trmInfo->trama); + if (strncmp(trmInfo->trama.identificador,"JMMLCAMDJ",9)==0){ // Es una trmInfo hidra + //if(ClienteExistente(trmInfo)) // Comprueba que se trata de un cliente Hidra + gestiona_comando(trmInfo); + } + free(trmInfo); + return(trmInfo); +} +//_______________________________________________________________________________________________________________ +// +// Gestiona la conexion con un cliente que sea Hidra para el servicio de repositorio +//_______________________________________________________________________________________________________________ +void NwGestionaServicioRepositorio(TramaRepos * trmInfo) +{ + Desencriptar((char*)&trmInfo->trama); + if (strncmp(trmInfo->trama.identificador,"JMMLCAMDJ",9)==0){ // Es una trmInfo hidra + //if(ClienteExistente(trmInfo)) // Comprueba que se trata de un cliente Hidra + gestiona_comando(trmInfo); + } + free(trmInfo); +} +//_______________________________________________________________________________________________________________ +// +// Gestiona la conexion con un cliente que sea Hidra para el servicio de repositorio +//_______________________________________________________________________________________________________________ +int gestiona_comando(TramaRepos *trmInfo) +{ + char* nombrefuncion; + int resul; + + INTROaFINCAD(trmInfo->trama.parametros); + nombrefuncion=toma_parametro("nfn=",trmInfo->trama.parametros); // Toma nombre funcin + + + resul=strcmp(nombrefuncion,"Arrancar"); + if(resul==0) + return(Arrancar(trmInfo)); + + resul=strcmp(nombrefuncion,"Apagar"); + if(resul==0) + return(RegistraComando(trmInfo)); + + resul=strcmp(nombrefuncion,"Reiniciar"); + if(resul==0) + return(RegistraComando(trmInfo)); + + resul=strcmp(nombrefuncion,"FicheroOperador"); + if(resul==0) + return(FicheroOperador(trmInfo)); + + resul=strcmp(nombrefuncion,"Actualizar"); + if(resul==0){ + return(RegistraComando(trmInfo)); + } + + resul=strcmp(nombrefuncion,"IconoItem"); + if(resul==0) + return(IconoItem(trmInfo)); + + resul=strcmp(nombrefuncion,"ExisteFichero"); + if(resul==0) + return(ExisteFichero(trmInfo)); + + resul=strcmp(nombrefuncion,"EliminaFichero"); + if(resul==0) + return(EliminaFichero(trmInfo)); + + resul=strcmp(nombrefuncion,"LeeFicheroTexto"); + if(resul==0) + return(LeeFicheroTexto(trmInfo)); + + resul=strcmp(nombrefuncion,"EnviaPerfilSoftware"); + if(resul==0) + return(EnviaPerfilSoftware(trmInfo)); + + resul=strcmp(nombrefuncion,"ExecShell"); + if(resul==0) + return(RegistraComando(trmInfo)); + + resul=strcmp(nombrefuncion,"TomaConfiguracion"); + if(resul==0) + return(RegistraComando(trmInfo)); + + resul=strcmp(nombrefuncion,"InventarioHardware"); + if(resul==0) + return(RegistraComando(trmInfo)); + + resul=strcmp(nombrefuncion,"RestaurarImagen"); + if(resul==0) + return(RegistraComando(trmInfo)); + + resul=strcmp(nombrefuncion,"CrearPerfilSoftware"); + if(resul==0) + return(RegistraComando(trmInfo)); + + resul=strcmp(nombrefuncion,"RecibePerfilSoftware"); + if(resul==0) + return(RecibePerfilSoftware(trmInfo)); + + resul=strcmp(nombrefuncion,"ParticionaryFormatear"); + if(resul==0) + return(RegistraComando(trmInfo)); + + return(false); +} +//_____________________________________________________________________________________________________________ +// Funcinn: RegistraComando +// +// Descripcinn: +// Crea un fichero de comando para cada cliente hidra +//_____________________________________________________________________________________________________________ +int RegistraComando(TramaRepos *trmInfo) +{ + char* ipes[MAXIMOS_CLIENTES]; + char ch[2]; + int i,numipes,lon; + char nomfilecmd[1024]; + FILE *Fcomandos; + + char *iph=toma_parametro("iph",trmInfo->trama.parametros); // Toma nombre funcin + if(!iph) return(false); + strcpy(ch,";");// caracter delimitador + numipes=split_parametros(ipes,iph,ch); + + FINCADaINTRO(trmInfo->trama.parametros,iph); + *(iph-4)=(char)NULL; + lon=strlen((char*)&trmInfo->trama); + + for(i=0;itrama,lon,1,Fcomandos); + fclose(Fcomandos); + } + return(true); +} +//_____________________________________________________________________________________________________________ +// Funcin: Arrancar +// +// Descripcinn: +// Esta funcinn enciende un ordenadores +// Parámetros de entrada: +// - parametros: Cadena con las mac de los ordenadores que se van a arrancar separadas por punto y coma +//_____________________________________________________________________________________________________________ +int Arrancar(TramaRepos *trmInfo) +{ + int i,nummacs; + char* macs[MAXIMOS_CLIENTES]; + char ch[2]; // Caracter delimitador + + char *mac=toma_parametro("mac",trmInfo->trama.parametros); // Toma Mac + strcpy(ch,";");// caracter delimitador + nummacs=split_parametros(macs,mac,ch); + for(i=0;itrama.parametros); // Toma operacion: Alta,o Baja + usu=toma_parametro("usu",trmInfo->trama.parametros); // Toma nombre del fichero de login de operador + psw=toma_parametro("psw",trmInfo->trama.parametros); // Toma login del fichero de login de operador + ida=toma_parametro("ida",trmInfo->trama.parametros); // Toma identificador del aula + strcpy(nomfilelogin,PathUsuarios); + strcat(nomfilelogin,usu); + ext=atoi(ida); + if(ext>0){ + strcat(nomfilelogin,"-"); + strcat(nomfilelogin,ida); + } + op=atoi(amb); + switch(op){ + case 1: + FLogin=fopen( nomfilelogin,"w"); + if(FLogin==NULL) + RegistraLog("PathComandos, NO existe el Path para el fichero de login de operador ",false); + Encriptar(psw); + fprintf (FLogin,"%s",psw); + fclose(FLogin); + break; + case 3: + strcpy(nomcmd,"rm -f "); + strcat(nomcmd,nomfilelogin); + resul=system(nomcmd); + break; + } + return(true); +} +//_____________________________________________________________________________________________________________ +// Funcinn: FicheroOperador +// +// Descripcinn: +// Crea un fichero para que un operador de aula o administrador de centro pueda entrar en el menú privado de los clientes rembo +// Parámetros de entrada: +// - parametros: Parámetros del comando +//_____________________________________________________________________________________________________________ +int IconoItem(TramaRepos *trmInfo) +{ + FILE *FIcono; + char *nii,*amb,*lii,*iit; + int lon,op,resul; + char nomfileicono[250]; + char nomcmd[260]; + + nii=toma_parametro("nii",trmInfo->trama.parametros); // Toma el nombre del fichero + amb=toma_parametro("amb",trmInfo->trama.parametros); // Toma operacion: Alta,o Baja + lii=toma_parametro("lii",trmInfo->trama.parametros); // Toma longitud del fichero de icono + iit=toma_parametro("iit",trmInfo->trama.parametros); // Toma contenido del fichero de icono + lon=atoi(lii); + op=atoi(amb); + strcpy(nomfileicono,PathIconos); + strcat(nomfileicono,nii); + switch(op){ + case 1: + FIcono=fopen( nomfileicono,"w"); + fwrite (iit,lon,1,FIcono); + fclose(FIcono); + break; + case 3: + strcpy(nomcmd,"rm -f "); + strcat(nomcmd,nomfileicono); + resul=system(nomcmd); + break; + } + return(true); +} +//_______________________________________________________________________________________________________________ +// +// Comprueba si existe un fichero +//_______________________________________________________________________________________________________________ +bool ExisteFichero(TramaRepos *trmInfo) +{ + FILE *f; + char swf[2]; + char pathfile[250]; + + char *nomfile=toma_parametro("nfl",trmInfo->trama.parametros); // Toma nombre funcin + sprintf(pathfile,"%s%s",PathHidra,nomfile); + + f = fopen(pathfile,"rt"); + if(f==NULL) + strcpy(swf,"0"); + else + strcpy(swf,"1"); + if(f) fclose(f); + return(respuesta_peticion(trmInfo,"Respuesta_ExisteFichero",swf,nomfile)); +} +//_______________________________________________________________________________________________________________ +// +// Envia respuesta a peticin de comando +//_______________________________________________________________________________________________________________ +bool respuesta_clienteHidra(TramaRepos *trmInfo) +{ + int ret; + //MandaRespuesta + Encriptar((char*)&trmInfo->trama); + ret=sendto(trmInfo->sck,(char*)&trmInfo->trama,strlen(trmInfo->trama.parametros)+11,0,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***sendto() fallo al enviar respuesta modulo respuesta_clienteHidra() :",true); + return(false); + } + return(true); +} +//_______________________________________________________________________________________________________________ +// +// Envia respuesta a peticin de comando +//_______________________________________________________________________________________________________________ +bool respuesta_peticion(TramaRepos *trmInfo,char *LitRes,char* swf,char*txt) +{ + int lon,ret; + TRAMA *trama=(TRAMA*)malloc(LONGITUD_TRAMA); + if(!trama){ + RegistraLog("No hay memoria suficiente para enviar la respuesta al comando",false); + return(false); + } + trama->arroba='@'; + strncpy(trama->identificador,"JMMLCAMDJ",9); + trama->ejecutor='1'; + lon=sprintf(trama->parametros,"nfn=%s\r",LitRes); + lon+=sprintf(trama->parametros+lon,"res=%s\r",swf); + lon+=sprintf(trama->parametros+lon,"txt=%s\r",txt); + //MandaRespuesta + Encriptar((char*)trama); + ret=sendto(trmInfo->sck,(char*)trama,lon+11,0,(struct sockaddr*)&trmInfo->cliente,trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***sendto() fallo al enviar respuesta a peticin de comando:",true); + return(false); + } + return(true); +} +//_______________________________________________________________________________________________________________ +// +// Comprueba si existe un fichero +//_______________________________________________________________________________________________________________ +bool EliminaFichero(TramaRepos *trmInfo) +{ + char swf[2]; + char cmdshell[512]; + int res; + char pathfile[250]; + + char *nomfile=toma_parametro("nfl",trmInfo->trama.parametros); // Toma nombre funcin + sprintf(pathfile,"%s%s",PathHidra,nomfile); + sprintf(cmdshell,"rm -f %s",pathfile); + res=system(cmdshell); + if(res==0) + strcpy(swf,"1"); + else + strcpy(swf,"0"); + return(respuesta_peticion(trmInfo,"Respuesta_EliminaFichero",swf,nomfile)); +} +//_______________________________________________________________________________________________________________ +// +// Comprueba si existe un fichero +//_______________________________________________________________________________________________________________ +bool LeeFicheroTexto(TramaRepos *trmInfo) +{ + char *texto; + long lSize; + FILE *f; + char pathfile[250]; + char swf[2]; + + char *nomfile=toma_parametro("nfl",trmInfo->trama.parametros); // Toma nombre funcin + sprintf(pathfile,"%s%s",PathHidra,nomfile); + + f = fopen(pathfile,"rt"); + if(!f){ // El fichero no existe + texto=(char*)malloc(2); + strcpy(texto," "); + strcpy(swf,"0"); + } + else{ + fseek(f,0,SEEK_END); + lSize=ftell(f); + texto=(char*)malloc(lSize); + if(!texto){ + texto=(char*)malloc(2); + strcpy(texto," "); + strcpy(swf,"0"); + } + else{ + rewind (f); // Coloca al principio el puntero de lectura + fread (texto,1,lSize,f); // Lee el contenido del fichero + strcpy(swf,"1"); + fclose(f); + } + } + return(respuesta_peticion(trmInfo,"Respuesta_LeeFicheroTexto",swf,texto)); +} +//_______________________________________________________________________________________________________________ +// +// Sincroniza netcat para creacion de perfil software +//_______________________________________________________________________________________________________________ +bool RecibePerfilSoftware(TramaRepos *trmInfo) +{ + char *nomfile; + int puertonetcat; + int res; + char cmdshell[250]; + + nomfile=toma_parametro("nfp",trmInfo->trama.parametros); // Toma nombre perfil software + + if(!TomaPuertoLibre(&puertonetcat)){ // Busca puerto libre para netcat + RegistraLog("***TomaPuertoLibre() fallo en modulo RecibePerfilSoftware()",true); + return(false); + } + // Envia puerto netcat al cliente + sprintf(trmInfo->trama.parametros," pnt=%d ",puertonetcat); + res= respuesta_clienteHidra(trmInfo); + if(!res){ + RegistraLog("***sendto() fallo en modulo RecibePerfilSoftware()",true); + return(false); + } + // Ejejcuta script nc de servidor + //sprintf(parametros," %s %d ",nomfile,puertonetcat); + //res=ejecutarscript(cmdshell, parametros,NULL); + sprintf(cmdshell,"/usr/local/hidra/scripts/RecibirImagenEnRepo %s %d ",nomfile,puertonetcat); + res=ExecShell(cmdshell,NULL); + if(!res){ + RegistraLog("*** fallo en modulo RecibePerfilSoftware()",true); + return(false); + } + return(true); +} +//_______________________________________________________________________________________________________________ +// +// Sincroniza netcat para creacion de perfil software +//_______________________________________________________________________________________________________________ +bool EnviaPerfilSoftware(TramaRepos *trmInfo) +{ + char *nomfile,*iph; + int puertonetcat; + int res; + char cmdshell[250]; + + nomfile=toma_parametro("nfp",trmInfo->trama.parametros); // Toma nombre perfil software + iph=toma_parametro("iph",trmInfo->trama.parametros); // Toma ip del cliente + + if(!TomaPuertoLibre(&puertonetcat)){ // Busca puerto libre para netcat + RegistraLog("***TomaPuertoLibre() fallo en modulo EnviaPerfilSoftware()",true); + return(false); + } + // Envia puerto netcat al cliente + sprintf(trmInfo->trama.parametros," pnt=%d ",puertonetcat); + res= respuesta_clienteHidra(trmInfo); + if(!res){ + RegistraLog("***sendto() fallo en modulo EnviaPerfilSoftware()",true); + return(false); + } + // Ejejcuta script nc de servidor + //sprintf(parametros," %s %d ",nomfile,puertonetcat); + //res=ejecutarscript(cmdshell, parametros,NULL); + sprintf(cmdshell,"/usr/local/hidra/scripts/EnviarImagenDesdeRepo %s %s %d ",nomfile,iph,puertonetcat); + res=ExecShell(cmdshell,NULL); + if(!res){ + RegistraLog("*** fallo en modulo EnviaPerfilSoftware()",true); + return(false); + } + return(true); +} + +//________________________________________________________________________________________________________ +// Funcin: ExecShell +// +// Descripcin: +// Ejecuta cdigo script +// ________________________________________________________________________________________________________ +int ExecShell(char* cod,char *salida) +{ + FILE* f; + long lSize; + int herror; + + sprintf(filecmdshell,"%s","/usr/local/hidra/scripts/_hidrascript_"); + f = fopen(filecmdshell,"wt"); + lSize=strlen(cod); + fwrite(cod,1,lSize,f); // Lee el contenido del fichero + fclose(f); + + sprintf(cmdshell,"chmod +x %s",filecmdshell); + herror=system(cmdshell); + if(herror){ + RegistraLog("*** fallo en modulo ExecShell() al cambiar de permisos el archivo de script",true); + return(false); + } + + herror=system(filecmdshell); + + if(herror){ + RegistraLog("*** fallo en modulo ExecShell()",true); + return(false); + } + return(true); +} +//_________________________________________________________________________________________________ +// Funcin: Buffer +// +// Descripcin: +// Reserva memoria +// Parmetros: +// - l: Longitud en bytes de la reserva +// Devuelve: +// Un puntero a la memoria reservada +//___________________________________________________________________________________________________ +char * Buffer(int l) +{ + char *buf; + buf=(char*)malloc(l); + if(buf==NULL){ + RegistraLog("*** fallo de reserva de memoria en modulo Buffer()",true); + return(false); + } + memset(buf,0,l); + return(buf); +} +//_____________________________________________________________________________________________________________ +// +// Funcin: ejecutarscript +// +// Descripcin: +// Esta función ejecuta un script creando un proceso hijo para ello +// +//_____________________________________________________________________________________________________________ + +int ejecutarscript ( char *script,char * parametros,char *salida) +{ + int descr[2]; /* Descriptores de E y S de la turbería */ + int bytesleidos; /* Bytes leidos en el mensaje */ + int resul=0; + pid_t pid; + // char mensaje[256]=""; /* Mensajes leído */ + // char *script="DetectarDiscos"; /* Script a ejecutar */ + + pipe (descr); + if((pid=fork())==0){ + /* Proceso hijo que ejecuta el script */ + close (descr[LEER]); + dup2 (descr[ESCRIBIR], 1); + close (descr[ESCRIBIR]); + resul=execl (script, script, parametros,NULL); + } + else { + if (pid ==-1) return(false); + /* Proceso padre que lee la salida del script */ + close (descr[ESCRIBIR]); + if(salida!=(char*)NULL){ + bytesleidos = read (descr[LEER], salida, 1000); + salida[bytesleidos]=(char)NULL; + } + close (descr[LEER]); + kill(pid,SIGQUIT); + return(0); + } + return(-1); +} +//_______________________________________________________________________________________________________________ +// +// Crea un socket en un puerto determinado para la conversacin UDP con el repositorio +// +//_______________________________________________________________________________________________________________ +int TomaPuertoLibre(int * puerto) +{ + SOCKET socket_c; // Socket para hebras (UDP) + struct sockaddr_in cliente; + int puertolibre; + + socket_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Crea socket para UDP + + if (socket_c == SOCKET_ERROR) + return (false); + + cliente.sin_addr.s_addr = inet_addr(IPlocal); // selecciona interface + cliente.sin_family = AF_INET; + puertolibre=PUERTOMINUSER; + while(puertolibre=PUERTOMAXUSER){ // No hay puertos libres + return(INVALID_SOCKET); + } + *puerto=puertolibre; + return(true); +} +//________________________________________________________________________________________________________ +// Funcinn: TomaRestoConfiguracion; +// +// Descripcinn: +// Esta funcinn lee la trama respuesta de inclusin del repositorio hidra + +//________________________________________________________________________________________________________ +int RESPUESTA_inclusionREPO(TRAMA *trama) +{ + + INTROaFINCAD(trama->parametros); + char* prm; + prm=toma_parametro("prp",trama->parametros); // Puero de comunicaciones + puertorepo=atoi(prm); + prm=toma_parametro("pth",trama->parametros); // Path al directorio base de Hidra + strcpy(PathHidra,prm); + + strcpy(PathUsuarios,PathHidra); + strcpy(PathIconos,PathHidra); + strcpy(PathComandos,PathHidra); + strcat(PathComandos,"/comandos"); + strcat(PathUsuarios,"/usuarios/"); + strcat(PathIconos,"/iconos/"); + + prm=toma_parametro("usu",trama->parametros); // usuario acceso B.D. + strcpy(usuario,prm); + prm=toma_parametro("pwd",trama->parametros); // Pasword + strcpy(pasguor,prm); + prm=toma_parametro("dat",trama->parametros); // Ip gestor de datos + strcpy(datasource,prm); + prm=toma_parametro("cat",trama->parametros); // Nombre B.D. + strcpy(catalog,prm); + + return(true); +} +//*************************************************************************************************************** +// PROGRAMA PRINCIPAL +//*************************************************************************************************************** +int main(int argc, char **argv) +{ + SOCKET socket_s; // Socket donde escucha el repositorio + TramaRepos *trmInfo; + struct sockaddr_in local; + int i,ret; + + + for(i = 1; i < argc; i++){ + if (argv[i][0] == '-'){ + switch (tolower(argv[i][1])){ + case 'f': + if (argv[i+1]!=NULL) + strcpy(szPathFileCfg, argv[i+1]); + else{ + RegistraLog("Fallo en los parmetros: Debe especificar el fichero de configuracin del servicio",false); + exit(EXIT_FAILURE); + } + break; + case 'l': + if (argv[i+1]!=NULL) + strcpy(szPathFileLog, argv[i+1]); + else{ + RegistraLog("Fallo en los parmetros: Debe especificar el fichero de log para el servicio",false); + exit(EXIT_FAILURE); + } + break; + default: + RegistraLog("Fallo de sintaxis en los parmetros: Debe especificar -f nombre_del_fichero_de_configuracin_del_servicio -l nombre_del_fichero_de_log_del_servicio",false); + exit(EXIT_FAILURE); + break; + } + } + } + if(!TomaConfiguracion(szPathFileCfg)){ // Toma parametros de configuracion + RegistraLog("NO existe fichero de configuracin o contiene un error de sintaxis",false); + exit(EXIT_FAILURE); + } + if(!inclusion_REPO()){ + RegistraLog("Ha habido algn problema al abrir sesin con el servidor Hidra",false); + exit(EXIT_FAILURE); + } + + RegistraLog("***Inicio de sesion***",false); + + socket_s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Crea socket para UDP + if (socket_s == SOCKET_ERROR){ + RegistraLog("***Error al crear socket para servicio de repositorio:",true); + exit(EXIT_FAILURE); + } + RegistraLog("***Creando Socket para comunicaciones***",false); + + local.sin_addr.s_addr = inet_addr(IPlocal);// selecciona interface + local.sin_family = AF_INET; + local.sin_port = htons(puertorepo); // Puerto + + // Enlaza socket + if (bind(socket_s,(struct sockaddr *)&local,sizeof(local)) == SOCKET_ERROR){ + RegistraLog("***Error al enlazar socket con interface para servicio de Repositorio Hidra",true); + exit(EXIT_FAILURE);; + } + RegistraLog("***Enlazado Socket para comunicaciones***",false); + while(true){ + trmInfo = (TramaRepos*)malloc(sizeof(TramaRepos)); // Crea estructura de control para hebra + if (trmInfo == NULL){ + RegistraLog("***Fallo al crear estructura de control para protocolo REPO",false); + exit(EXIT_FAILURE);; + } + // Inicializa trmInfo + memset(trmInfo,0,sizeof(struct TramaRepos)); + trmInfo->sockaddrsize = sizeof(trmInfo->cliente); + trmInfo->sck=socket_s; + // Espera trmInfos Repositorio + ret = recvfrom(trmInfo->sck,(char *)&trmInfo->trama, sizeof(trmInfo->trama),0,(struct sockaddr *)&trmInfo->cliente, &trmInfo->sockaddrsize); + if (ret == SOCKET_ERROR){ + RegistraLog("***Error al recibir mensaje de cliente hidra. Se para el servicio de repositorio",true); + exit(EXIT_FAILURE); + } + else{ + if (ret>0){ + /* + resul=pthread_create(&hThread,NULL,GestionaServicioRepositorio,(LPVOID)trmInfo); + if(resul!=0){ + RegistraLog("***Fallo al crear la hebra cliente de repositorio Hidra",false); + exit(EXIT_FAILURE); + } + pthread_detach(hThread); + */ + NwGestionaServicioRepositorio(trmInfo); + } + } + } + close(socket_s); + exit(EXIT_SUCCESS); +} diff --git a/Hidra/hidrarepos/fuentes/hidrarepos.h b/Hidra/hidrarepos/fuentes/hidrarepos.h new file mode 100644 index 00000000..2d0c11f8 --- /dev/null +++ b/Hidra/hidrarepos/fuentes/hidrarepos.h @@ -0,0 +1,131 @@ +// ************************************************************************************************************* +// Aplicacin HIDRA +// Copyright 2003-2007 Jos Manuel Alonso. Todos los derechos reservados. +// Fichero: hidrarepos.h +// +// Descripcin: +// Fichero de cabecera de hidrapxedhcp.cpp +// ************************************************************************************************************** +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Database.h" +#include "encriptacion.h" + +#define LONGITUD_PARAMETROS 4048 // Longitud m?ima de la informacin de la trama (parametros) +#define LONGITUD_TRAMA LONGITUD_PARAMETROS+8 // Longitud m?ima de la trama completa + +#define MAXIMOS_CLIENTES 4000 // M?imo numero de clientes rembo controlados por el servidor rembo +#define MAXCNX 5 // Mximos intentos de conexin al servidor HIDRA +#define PUERTO_WAKEUP 9 // Puerto por defecto del wake up + +#define PUERTOMINUSER 20000 +#define PUERTOMAXUSER 60000 + +#define LEER 0 +#define ESCRIBIR 1 + +#define TRUE 1 +#define FALSE 0 + +#define true 1 +#define false 0 + +#define SOCKET_ERROR (-1) +#define INVALID_SOCKET (SOCKET)(~0) + +typedef unsigned long DWORD; +typedef unsigned short WORD; +typedef int BOOL; +typedef char BYTE; +typedef int SOCKET; +typedef void* LPVOID; + +typedef struct{ // EstructUra de la trama recibida + char arroba; // cabecera de la trama + char identificador[9]; // identificador de la trama + char ejecutor; // ejecutor de la trama 1=el servidor rembo 2=el cliente rembo + char parametros[LONGITUD_PARAMETROS]; // Contenido de la trama (par?etros) +}TRAMA; + +// Estructura para trabajar en cada hebra con el cliente en cuestion +struct TramaRepos{ + SOCKET sck; + struct sockaddr_in cliente; + socklen_t sockaddrsize; + TRAMA trama; +}; +char szPathFileCfg[128],szPathFileLog[128]; +FILE *FLog,*Fconfig; +SOCKET sClient; + +char IPlocal[20]; // Ip local +char servidorhidra[20]; // IP servidor HIDRA +char Puerto[20]; // Puerto Unicode +int puerto; // Puerto + +char filecmdshell[250]; +char cmdshell[512]; + +char usuario[20]; +char pasguor[20]; +char datasource[20]; +char catalog[50]; +int puertorepo; // Puerto + +//______________________________________________________ +static pthread_mutex_t guardia; // Controla acceso exclusivo de hebras +//______________________________________________________ + +char PathHidra[1024]; // path al directorio base de Hidra +char PathComandos[1024]; // path al directorio donde se depositan los comandos para los clientes +char PathUsuarios[1024]; // path al directorio donde se depositan los ficheros de login de los operadores +char PathIconos[1024]; // path al directorio donde se depositan los iconos de los items de los mens + +// Prototipos de funciones +void RegistraLog(char *,int ); +int split_parametros(char **,char *, char * ); +int TomaConfiguracion(char* ); +void INTROaFINCAD(char* ); +void FINCADaINTRO(char*,char*); +char * toma_parametro(char* ,char *); +int ClienteExistente(TramaRepos *); +LPVOID GestionaServicioRepositorio(LPVOID); +int Actualizar(TramaRepos*); +int Arrancar(TramaRepos *); +int Wake_Up(SOCKET,char *); +void PasaHexBin( char *,char *); +int levanta(char *); +int FicheroOperador(TramaRepos *); +int IconoItem(TramaRepos *); + +bool ExisteFichero(TramaRepos *); +bool EliminaFichero(TramaRepos *); +bool LeeFicheroTexto(TramaRepos *); +int gestiona_comando(TramaRepos *); +bool respuesta_peticion(TramaRepos *,char*,char*,char*); +bool RecibePerfilSoftware(TramaRepos *trmInfo); +bool EnviaPerfilSoftware(TramaRepos *trmInfo); +SOCKET Abre_conexion(char *,int); +int envia_tramas(SOCKET,TRAMA *); +int recibe_tramas(SOCKET ,TRAMA *); +int inclusion_REPO(); +int RESPUESTA_inclusionREPO(TRAMA *); +int TomaRestoConfiguracion(TRAMA *); +int RegistraComando(TramaRepos *); +int Apagar(TramaRepos *); +char * Buffer(int ); +int TomaPuertoLibre(int *); +int ejecutarscript ( char *,char * ,char *); +void NwGestionaServicioRepositorio(TramaRepos *); +int ExecShell(char*,char *); diff --git a/Hidra/webhidra/barramenu.php b/Hidra/webhidra/barramenu.php index 82b45b09..0c83e1f7 100644 --- a/Hidra/webhidra/barramenu.php +++ b/Hidra/webhidra/barramenu.php @@ -1,11 +1,11 @@ - Administración web de aulas + Administraci� web de aulas - + @@ -43,7 +44,7 @@ $arbol=new ArbolVistaXML($arbolXML,0,$baseurlimg,$clasedefault,1,0,5); CreaArbolVistaXML(); // Crea árbol (HTML) a partir del XML +echo $arbol->CreaArbolVistaXML(); // Crea �bol (HTML) a partir del XML $flotante=new MenuContextual(); // Crea objeto MenuContextual // Crea contextual de los procedimientos @@ -77,9 +78,9 @@ include_once("../includes/iframecomun.php"); -Administración web de aulas +Administraci� web de aulas + @@ -78,12 +79,12 @@ function pintacomandos($cmd,$idprocedimientocomando){ $textambito=""; $urlimg=""; $auxVP=split(";",$rs->campos["visuparametros"]); // Parametros visualizables - $auxP=split(chr(13),$rs->campos["parametros"]); // Recorre parametros para visualizar los que así sean + $auxP=split(chr(13),$rs->campos["parametros"]); // Recorre parametros para visualizar los que as�sean for ($i=0;$i=0){ $auxtabla_parametros=$tabla_parametros[$posp][1]; $HTMLparametros.=''.chr(13);