Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Internet
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

 
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 26-08-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
ftp Upload / Download (Aplicación)

Hace tiempo que no pongo código por aquí, al menos no código útil, así que vamos a ver que os parece esta pequeña herramienta.

Se trata de una aplicación de consola que permite subir o bajar un archivo de un servidor ftp, pero con la particularidad que lo cifra al subirlo y lo descifra al bajarlo. El cifrado que utiliza es AES de 256 bits, que nos permite usar contraseñas de hasta 32 caracteres, y es lo suficientemente seguro para que lo utilice el gobierno de los EE.UU.

Pero dije que este no era código inútil, así que vamos a buscarle alguna utilidad. La primera, y mas evidente, es subir un archivo:
Código:
ftpup --key=clave --local=archivo.txt --password=pass --user=user --remote=/archivo.txt --server=servidor.com
El comando anterior subiría el archivo "archivo.txt" al servidor "servidor.com", usando el nombre de usuario "user", el password "pass" y la clave de cifrado "clave". Hasta ahora nada que no se pudiera hacer con cualquier otro cliente de ftp, salvo el cifrado. Se me ocurre que puede servir para hacer una copia de seguridad de un documento privado, si lo combinamos, por ejemplo, con las tareas programadas de Windows.

Para bajarlo, nada mas sencillo que esto:
Código:
ftpup -d --key=clave --local=archivo.txt --password=pass --user=user --remote=/archivo.txt --server=servidor.com
Pero ya me conocéis, hay que buscar otro uso mas interesante a esto, darle otra vuelta de tuerca. Que os parece utilizarlo para guardar, y leer, anotaciones cifradas desde cualquier ordenador, sin dejar ningún rastro en el equipo. Pues vamos a probar, lo primero es decir que en el parámetro --local se puede usar un "." para decir que se utilice en vez de un archivo, la entrada y salida estándar. Sabiendo esto, podríamos hacer algo como esto:
Código:
echo Mensaje secreto | ftpup --key=clave --local=. --password=pass --user=user --remote=/archivo.txt --server=servidor.com
Y para leerlo algo como esto:
Código:
ftpup -d --key=clave --local=. --password=pass --user=user --remote=/archivo.txt --server=servidor.com
Y ya puestos, podríamos guardar cómodamente nuestras contraseñas en un archivo de texto, y desde nuestra casa subirlas al ftp. Así desde cualquier equipo en el que estemos podremos ver las contraseñas en pantalla, si necesidad de guardar ningún archivo en el disco.

Bueno, seguro que alguna utilidad mas se le puede sacar. Como siempre, criticas (constructivas) y sugerencias serán bien recibidas. Espero vuestros comentarios.

El código (es una aplicación de consola):
Código Delphi [-]
program ftpup;

{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils,
  Classes,
  WinInet,
  AES in 'AES.pas';

type
  EGetOptError = class(Exception);

var
  Options: record
    Download: Boolean; 
    Key: String;
    Local: String;
    Password: String;
    Port: Integer;
    Remote: String;
    Server: String;
    User: String;
  end;

function Starts(Sub, Str: String): Boolean;
begin
  Result:= SameText(Sub,Copy(Str,1,Length(sub)));
end;

procedure Getopt;
var
  i,j: Integer;
  Str: String;
begin
  FillChar(Options,Sizeof(Options),#0);
  for i:= 1 to ParamCount do
  begin
    Str:= ParamStr(i);
    if (Copy(Str,1,2) = '--') and (Length(Str) > 2) then
    begin
      if SameText(Str,'--Download') then
        Options.Download:= TRUE
      else if Starts('--Key=',Str) then
      begin
        if Options.Key = EmptyStr then
          Options.Key:= Copy(Str,Length('--Key=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end else if Starts('--Local=',Str) then
      begin
        if Options.Local = EmptyStr then
          Options.Local:= Copy(Str,Length('--Local=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end else if Starts('--Remote=',Str) then
      begin
        if Options.Remote = EmptyStr then
          Options.Remote:= Copy(Str,Length('--Remote=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end else if Starts('--Password=',Str) then
      begin
        if Options.Password = EmptyStr then
          Options.Password:= Copy(Str,Length('--Password=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end else if Starts('--Port=',Str) then
      begin
        if Options.Port = 0 then
          Options.Port:= StrToInt(Copy(Str,Length('--Port=') + 1,MAXINT))
        else
          raise EGetOptError.Create(Str);
      end else if Starts('--Server=',Str) then
      begin
        if Options.Server = EmptyStr then
          Options.Server:= Copy(Str,Length('--Server=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end else if Starts('--User=',Str) then
      begin
        if Options.User = EmptyStr then
          Options.User:= Copy(Str,Length('--User=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end else
        raise EGetOptError.Create(Str);
    end else if (Copy(Str,1,1) = '-') and (Length(Str) > 1) then
    begin
      Str:= UpperCase(Str);
      for j:= 2 to Length(Str) do
      begin
        if Str[j] = 'D' then
          Options.Download:= TRUE
        else
          raise EGetOptError.Create(Str);
      end;
    end else
    begin
      raise EGetOptError.Create(Str);
    end;
  end;
  if Options.Port = 0 then
    Options.Port:= 21;
end;

function ftpUpload(Stream: TStream; RemoteFile, Server: String; Port: Word;
  Username, Password: PChar; Key: TAESExpandedKey): Boolean;
var
  hNet: HINTERNET;
  hCon: HINTERNET;
  hFile: HINTERNET;
  Context: DWORD;
  Count: Cardinal;
  State, Temp: TAESState;
  Size: int64;
begin
  Result := FALSE;
  Context:= 0;
  hNet := InternetOpen('agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hCon:= InternetConnect(hNet,PChar(Server),Port,Username,Password,
      INTERNET_SERVICE_FTP,0,Context);
    if (hCon <> nil) then
    begin
      hFile:= FtpOpenFile(hCon,PChar(RemoteFile),GENERIC_WRITE,
        FTP_TRANSFER_TYPE_BINARY,Context);
      if hFile <> nil then
      begin
        try
          if Stream is TFileStream then
            Size:= Stream.Size
          else
            Size:= -1;
          if InternetWriteFile(hFile,@Size,Sizeof(Size),Count) and
            (Count = Sizeof(Size))  then
          begin
            FillChar(Temp,Sizeof(Temp),#0);
            FillChar(State,Sizeof(State),#0);
            Count:= Stream.Read(State,Sizeof(State));
            while  Count > 0 do
            begin
              XORState(State,Temp);
              AESEncrypt(State,Key);
              if not InternetWriteFile(hFile,@State,Sizeof(State),Count) then
                break;
              Temp:= State;
              FillChar(State,Sizeof(State),#0);
              Count:= Stream.Read(State,Sizeof(State));
            end;
            Result:= Count = 0;
          end;
          if not Result then
            Writeln(SysErrorMessage(GetLastError));
        except
          On E: Exception do
            Writeln(E.Message);
        end;
        InternetCloseHandle(hFile);
      end else Writeln(SysErrorMessage(GetLastError));
      InternetCloseHandle(hCon);
    end else Writeln(SysErrorMessage(GetLastError));
    InternetCloseHandle(hNet);
  end else Writeln(SysErrorMessage(GetLastError));
end;

function ftpDownload(Stream: TStream; RemoteFile, Server: String; Port: Word;
  Username, Password: PChar; Key: TAESExpandedKey): Boolean;
var
  hNet: HINTERNET;
  hCon: HINTERNET;
  hFile: HINTERNET;
  Context: DWORD;
  Count: Cardinal;
  State, Temp, Ant: TAESState;
  Size: int64;
begin
  Result := FALSE;
  Context:= 0;
  hNet := InternetOpen('agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hCon:= InternetConnect(hNet,PChar(Server),Port,Username,Password,
      INTERNET_SERVICE_FTP,0,Context);
    if (hCon <> nil) then
    begin
      hFile:= FtpOpenFile(hCon,PChar(RemoteFile),GENERIC_READ,
        FTP_TRANSFER_TYPE_BINARY,Context);
      if hFile <> nil then
      begin
        try
          if InternetReadFile(hFile,@Size,Sizeof(Size),Count) and
            (Count = Sizeof(Size))  then
          begin
            FillChar(Temp,Sizeof(Temp),#0);
            FillChar(State,Sizeof(State),#0);
            if InternetReadFile(hFile,@State,Sizeof(State),Count) then
            begin
              while  Count > 0 do
              begin
                Ant:= State;
                AESDecrypt(State,Key);
                XORState(State,Temp);
                if Stream.Write(State,Count) <> Integer(Count) then
                  break;
                Temp:= Ant;
                FillChar(State,Sizeof(State),#0);
                if not InternetReadFile(hFile,@State,Sizeof(State),Count) then
                  break;
              end;
              Result:= Count = 0;
            end;
            if (Stream is TFileStream) and (Stream.Size > Size)
              and (Size > 0 )then
              Stream.Size:= Size;
            if not Result then
              Writeln(SysErrorMessage(GetLastError));
          end;
        except
          On E: Exception do
            Writeln(E.Message);
        end;
        InternetCloseHandle(hFile);
      end else Writeln(SysErrorMessage(GetLastError));
      InternetCloseHandle(hCon);
    end else Writeln(SysErrorMessage(GetLastError));
    InternetCloseHandle(hNet);
  end else Writeln(SysErrorMessage(GetLastError));
end;

procedure Run;
var
  AESKey: TAESKey;
  ExKey: TAESExpandedKey;
  Stream: TStream;
begin
  FillChar(AESKey,Sizeof(AESKey),#0);
  if Length(Options.Key) > Sizeof(AESKey) then
    move(PChar(Options.Key)^,AESKey,Sizeof(AESKey))
  else
    move(PChar(Options.Key)^,AESKey,Length(Options.Key));
  AESExpandKey(ExKey,AESKey);
  if Options.Local = '.' then
  begin
    if Options.Download then
      Stream:= THandleStream.Create(GetStdHandle(STD_OUTPUT_HANDLE))
    else
      Stream:= THandleStream.Create(GetStdHandle(STD_INPUT_HANDLE));
  end else
  begin
    if Options.Download then
      Stream:= TFileStream.Create(Options.Local,fmCreate)
    else
      Stream:= TFileStream.Create(Options.Local,fmOpenRead or fmShareDenyNone);
  end;
  try
    if Options.Download then
      ftpDownload(Stream,Options.Remote,Options.Server,Options.Port,
        PChar(Options.User),PChar(Options.Password),ExKey)
    else
      ftpUpload(Stream,Options.Remote,Options.Server,Options.Port,
        PChar(Options.User),PChar(Options.Password),ExKey)
  finally
    Stream.Free;
  end;
end;

procedure Help;
begin
  Writeln;
  Writeln('Uso: ftpup [opciones]');
  Writeln('  --download -d');
  Writeln('    Baja el archivo del servidor');
  Writeln('  --key');
  Writeln('    Clave de cifrado, hasta 32 caracteres.');
  Writeln('  --local');
  Writeln('    Archivo local. Se puede utilizar un . para indicar la');
  Writeln('    entrada o salida estandar');
  Writeln('  --password');
  Writeln('    Clave de acceso al servidor ftp');
  Writeln('  --port');
  Writeln('    El puerto del ftp');
  Writeln('  --remote');
  Writeln('    Ruta del archivo remoto');
  Writeln('  --server');
  Writeln('    Direccion del servidor ftp');
  Writeln('  --user');
  Writeln('    Nombre de usuario del ftp');
  Writeln;
  Writeln('Ejemplos:');
  Writeln('  ftpup --key=clave --local=archivo.txt --password=pass ' +
    '--user=user --remote=/archivo.txt --server=servidor.com');
  Writeln('    Sube al servidor el archivo "archivo.txt".');
  Writeln('  ftpup -d --key=clave --local=. --password=pass ' +
    '--user=user --remote=/archivo.txt --server=servidor.com');
  Writeln('    Descarga el archivo "archivo.txt" y lo muestra por pantalla');
  Writeln;      
end;


begin
  try
    if ParamCount > 0 then
    begin
      GetOpt;
      Run;
    end else
      Help;
  except
    On E: EGetOptError do
    begin
      Writeln('Error en el parametro: ',E.Message);
      Help;
    end;
    On E: Exception do
      Writeln(E.Message);
  end;
end.
Archivos Adjuntos
Tipo de Archivo: zip ftpup.zip (8,7 KB, 56 visitas)

Última edición por seoane fecha: 26-08-2007 a las 12:49:42.
Responder Con Cita
 



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
upload masivo kayetano PHP 12 06-12-2006 16:45:39
UPLOAD de varios archivos por código HombreSigma .NET 3 04-12-2005 15:23:07
download periódico tcp_ip_es Internet 13 14-10-2005 17:00:27
como upload una bB.D. bdf con un form kassel PHP 4 22-01-2004 21:01:55
download delphi 5 Emiro Varios 2 26-10-2003 11:42:26


La franja horaria es GMT +2. Ahora son las 19:20:38.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi