Problemas para conectar cliente/servidor tunneling SSH

Iniciado por Oscar34, 14 Noviembre 2012, 13:27 PM

0 Miembros y 1 Visitante están viendo este tema.

Oscar34

Hola a todos,
Estoy intentando realizar un servidor SFTP de archivos mediante sockets y tunneling SSH... el tema es que al conectar el cliente con el servidor me da un problema en la conexion... a la hora de hacer el connect, y no se si es debido a algún problema con la forma de establecer el túnel, hacíendolo por labit301.. (una pagina de la universidad...)
Os dejo parte del código cliente y los pantallazos que me da...
El servidor únicamente queda a la escucha, pero nunca llega el cliente...
Si me podéis echar un cable, al menos para que tenga una idea de que puede fallar... muchas gracias.

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include<netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
//#include<strings.h>
#include <fcntl.h>
#include<getopt.h>

#define PUERTO 4000
#define MAX 1024

int main(int argc, char*argv[]){

// Declaracion de variables   
   int sockC,conexionSFTP;
   struct sockaddr_in serveraddr;
   char buffer[MAX];
   int opcion,get,put,i;
   char *modo=NULL;
   char *fichero_remoto=NULL;
   char *direccionIPsv=NULL;
   char *fichero_local=NULL;
   char cierre[22];
   FILE *archivo;
   pid_t hijo;

//Creamos el socket del cliente
   bzero(&serveraddr,sizeof(serveraddr));
   sockC=socket(AF_INET,SOCK_STREAM,0);
   if(sockC<0){
      printf("Error en la creacion del socket cliente.\n");
      exit(-1);
   }
   else{
      printf("Socket cliente creado.\n");
   }
   serveraddr.sin_family=AF_INET;
   serveraddr.sin_port=htons(PUERTO);
   serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1");

   bzero(buffer,sizeof(buffer));


printf("ENTRA_1\n");


//Una vez crado el socket, recogemos los parametros de entrada de la linea de caracteres
   while(1){
      if((opcion=getopt(argc,argv,"m:r:h:l:"))==-1)
         break;
   printf("ENTRA_2\n");
      switch(opcion){
         case 'm':
            modo=optarg;
            break;
         case 'r':
            fichero_remoto=optarg;
            break;
         case 'h':
            direccionIPsv=optarg;
            break;
         case 'l':
            fichero_local=optarg;
            break;
         case '?':
            printf("Uno de los valores introducidos no es correcto.\n");
            printf("Recuerde: \n"
                  "\n"
                  "-m modo get o put\n"
                  "-r fichero remoto\n"
                  "-h direccion IP del servidor\n"
                  "-l fichero local\n"
                  "\n");
            break;
      }//swtich
   } //while
   if(optind<argc){
      printf("elementos de qrgv que no son opciones.\n");
      while(optind<argc)
         printf("%s",argv[optind++]);
      printf("\n");
   }

//Creamos el proceso hijo para ejecutar el SSH

   if((hijo=fork())==0){

printf("ENTRA_3\n");

      execl("/usr/bin/ssh","ssh","-L","4000:labit301.upct.es:3000",direccionIPsv,"-f","sleep","15",NULL);
   exit(-1);
   }

printf("ENTRA_4\n");

//esperamos para introduciir el password ssh
   sleep(10);
   printf("1\n");
//Conectamos con el servidor SFTP
   conexionSFTP=connect(sockC,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
   if(conexionSFTP<0){
      printf("Error al establecer la conexion con el servidor.\n");
      exit(-1);
   }

   write(sockC,modo,MAX);
   printf("3\n");
//Comprobamos si la accion introducida por el usuario es un GET o un PUT
   if((get=strcmp(modo,"get"))==0){
      write(sockC,fichero_remoto,MAX);
      while((read(sockC,buffer,MAX))!=0){      //para ver si el servidor nos envia el cierre...
         for(i=0;1<22;i++){
            cierre=buffer;
         }
         if((strcmp(cierre,"fin_de_la_transmision"))==0)
            break;
         else{
            archivo=fopen(fichero_local,"a+");
            fprintf(archivo, "%s\n",buffer);
            fclose(archivo);
         }
      }
   }

//Si por el contrario es un PUT
   if((put=strcmp(modo,"put"))==0){
      write(sockC,fichero_remoto,MAX);
      archivo=fopen(fichero_local,"r");
      if(archivo==NULL){
         printf("No se ha podido encontrar el fichero local de nombre: %s\n",fichero_local);
         write(sockC,"No existe ese fichero que ha solicitado.\n",MAX);
      }
      else{
         while((fscanf(archivo,"%s",buffer))!=EOF){
            write(sockC,buffer,MAX);
         }
      }
      fclose(archivo);
   }
   close(sockC);
}
      


y al ejecutar el cliente:

oscar@oscar-VirtualBox:~/Escritorio/PRUEBAS PRACTICAS$ ./client -m put -r prueba.txt -h lsc30@labit301.upct.es -l prueba1.txt
Socket cliente creado.
ENTRA_1
ENTRA_2
ENTRA_2
ENTRA_2
ENTRA_2
ENTRA_4
ENTRA_3
1
Error al establecer la conexion con el servidor.
oscar@oscar-VirtualBox:~/Escritorio/PRUEBAS PRACTICAS$ ssh: connect to host labit301.upct.es port 22: Connection timed out
..
Disculpar si no es la forma mas adecuada de preguntar... pero estoy empezando..
MUCHAS GRACIAS de antemano :)

C_1^N

Hola Oscar34!
te convendria usar la funcion perror para marcar los errores de creacion de socket, bind, conexion, etc ya que te devolveria el error detallado de lo que esta pasando, tal vez asi te des cuenta en que esta fallando.

Saludos!
La gestión manual de bloques de memoria en C es como hacer malabarismos con pastillas de jabón en la ducha de la prisión: todo diversión hasta que cometes un fallo

0xDani

Cita de: C_1^N en 14 Noviembre 2012, 20:59 PM
Hola Oscar34!
te convendria usar la funcion perror para marcar los errores de creacion de socket, bind, conexion, etc ya que te devolveria el error detallado de lo que esta pasando, tal vez asi te des cuenta en que esta fallando.

Saludos!

Si, es una buena costumbre poner comprobaciones despues de cada funcion para saber que esta fallando. Y tambien usar etiquetas GeSHi, para que el codigo sea legible  ;)
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

Oscar34

Hola,
1) Muchas gracias por contestar y por la ayuda  ;D

He aplicado lo que me decías del perror, ( y con las GeSHI ...mucho mas bonito, donde va a parar) ... modificado un poco el programa,creo que ahora reside en la conexion en si ...en el port-forwarding (bastante probable jeje) o en el servidor labit301, que es de mi universidad y no se si tiene que estar abierto o algo asi..,ya que  ahora me da el siguiente mensaje:

oscar@oscar-VirtualBox:~/Escritorio/PRUEBAS PRACTICAS/cl$ ./client -m get -r ejemplo.txt -h lsc4@labit301.upct.es -l ejm.txt
Socket cliente creado.
ENTRA_1
ENTRA_2
ENTRA_2
ENTRA_2
ENTRA_2
ENTRA_4
ENTRA_3
ENTRA_5
Error al establecer la conexion con el servidor.
connect: Connection refused
oscar@oscar-VirtualBox:~/Escritorio/PRUEBAS PRACTICAS/cl$ ssh: Could not resolve hostname labit301.upct.es: Name or service not known

...

y el servidor que lanzo no me reconoce como que llega ningun cliente, sigue esperando eternamente el pobre :)

otra duda que tengo, en cuanto a los ficheros remoto y local... si hago un get al servidor, se supone que estoy pidiendo "ejemplo.txt" (que debo tenerlo en mi servidor.. lo que puesto en la misma carpeta que este) y almacenandolo en el cliente como "ejm.txt"    ¿?
..
poco a poco :) muchas gracias por la ayuda.




   
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include<netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include<getopt.h>

#define PUERTO 4000
#define MAX 1024

int main(int argc, char*argv[]){

// Declaracion de variables
int sockC,conexionSFTP;
struct sockaddr_in serveraddr;
char buffer[MAX];
int opcion,get,put,i;
char *modo=NULL;
char *fichero_remoto=NULL;
char *direccionIPsv=NULL;
char *fichero_local=NULL;
char cierre[22];
FILE *archivo;
pid_t hijo;

//Creamos el socket del cliente
bzero(&serveraddr,sizeof(serveraddr));
sockC=socket(AF_INET,SOCK_STREAM,0);
if(sockC<0){
printf("Error en la creacion del socket cliente.\n");
perror("socket");
exit(-1);
}
else{
printf("Socket cliente creado.\n");
}
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(PUERTO);
serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1");

bzero(buffer,sizeof(buffer));


printf("ENTRA_1\n");


//Una vez crado el socket, recogemos los parametros de entrada de la linea de caracteres
while(1){
if((opcion=getopt(argc,argv,"m:r:h:l:"))==-1)
break;
printf("ENTRA_2\n");
switch(opcion){
case 'm':
modo=optarg;
break;
case 'r':
fichero_remoto=optarg;
break;
case 'h':
direccionIPsv=optarg;
break;
case 'l':
fichero_local=optarg;
break;
case '?':
printf("Uno de los valores introducidos no es correcto.\n");
printf("Recuerde: \n"
"\n"
"-m modo get o put\n"
"-r fichero remoto\n"
"-h direccion IP del servidor\n"
"-l fichero local\n"
"\n");
break;
}//swtich
} //while
if(optind<argc){
printf("elementos de qrgv que no son opciones.\n");
while(optind<argc)
printf("%s",argv[optind++]);
printf("\n");
}

//Creamos el proceso hijo para ejecutar el SSH

if((hijo=fork())==0){

printf("ENTRA_3\n");

execl("/usr/bin/ssh","ssh","-L","4000:labit301.upct.es:3000",direccionIPsv,"-f","sleep","30",NULL);
exit(-1);
}

printf("ENTRA_4\n");

//esperamos para introduciir el password ssh
sleep(25);
printf("ENTRA_5\n");
//Conectamos con el servidor SFTP
conexionSFTP=connect(sockC,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr));
if(conexionSFTP<0){
printf("Error al establecer la conexion con el servidor.\n");
perror("connect");
exit(-1);
}

write(sockC,modo,MAX);
printf("ENTRA_6\n");
//Comprobamos si la accion introducida por el usuario es un GET o un PUT
if((get=strcmp(modo,"get"))==0){
printf("Entra en buble get\n");
write(sockC,fichero_remoto,MAX);
printf("ENTRA_7\n");
while((read(sockC,buffer,MAX))!=0){ //para ver si el servidor nos envia el cierre...

printf("ENTRA_8\n");


for(i=0;1<22;i++){
cierre[i]=buffer[i];

}
if((strcmp(cierre,"fin_de_la_transmision"))==0)
break;
else{
printf("ENTRA_9\n");
archivo=fopen(fichero_local,"a+");
fprintf(archivo, "%s\n",buffer);
fclose(archivo);
}
}
}

//Si por el contrario es un PUT
if((put=strcmp(modo,"put"))==0){
printf("Entra en bucle put\n");
write(sockC,fichero_remoto,MAX);
printf("ENTRA_10\n");
archivo=fopen(fichero_local,"r");
printf("ENTRA_11\n");
if(archivo==NULL){
printf("No se ha podido encontrar el fichero local de nombre: %s\n",fichero_local);
write(sockC,"No existe ese fichero que ha solicitado.\n",MAX);
}
else{
printf("ENTRA_12\n");
while((fscanf(archivo,"%s",buffer))!=EOF){
write(sockC,buffer,MAX);
}
}
fclose(archivo);
}
close(sockC);
}

Oscar34

Hola, sigo poco a poco avanzando con mi pequeño pograma, me da el siguiente error..

channel 3: open failed: connect failed: Connection refused

¿Alguien podria decirme donde esta el fallo?.. que significa channel 3?..el problema es que el servidor del tunneling no este conectado?
Gracias de antemamo.