Protheus como Servidor de FTP

Introdução

Quando eu comentei um pouco sobre as capacidades do Servidor de Aplicação Protheus Server, em um post mais antigo, eu mencionei que ele não apenas servia a conexões do SmartClient para rodar aplicações AdvPL, mas também que ele poderia ser um servidor de HTTP, com páginas estáticas e dinâmicas — usando AdvPL ASP — bem como TELNET e FTP. No post de hoje, vamos explorar o que a gente puder sobre como usar um Protheus Server como servidor de FTP.

Configuração Mínima

Imagine que você quer usar um Protheus Server como um FTP Server, com acesso anônimo — sem criticar usuário e senha — e apenas disponibilizar uma estrutura de pastas para Download. Neste caso, a configuração mínima para este serviço, seria acrescentar no arquivo de configuração do Protheus (appserver.ini) a seção [FTP], com as seguinte chaves:

[ftp]
Enable=1
Port=21
Path=c:\Protheus12LG\EnvLight\ftp
CanAcceptAnonymous=1

Especificamos a porta padrão (21), o acesso anônimo habilitado, e o path raiz do FTP, a partir do qual as conexões terão acesso de Download. Dentro da pasta configurada em “path”, eu coloquei um arquivo chamado leiame.txt, vamos ver este acesso através de um cliente FTP nativo do Windows, usando o comando “ftp” em linha de comando.

C:\Users\siga0>ftp -A localhost
Connected to NOTE-JULIOW-SSD.
220 Connected to FTP server
331 Anonymous access allowed
502 Command not implemented
331 Anonymous access allowed, send email name as PASS
220 Logon successful
230 Welcome to Application Server FTP!
Anonymous login succeeded for siga0@NOTE-JULIOW-SSD
ftp> dir
250 PORT command successful
150 Opening ASCII mode data connection
-r-xr-x--- 1 owner group 39 Nov 04 20:10 leiame.txt
226 Transfer Complete
ftp: 74 bytes received in 0.00Seconds 37.00Kbytes/sec.
ftp> ls
250 PORT command successful
150 Opening ASCII mode data connection
leiame.txt
226 Transfer Complete
ftp: 15 bytes received in 0.00Seconds 15.00Kbytes/sec.
ftp>

Através do parâmetro “-A” na linha de comando, informamos ao cliente FTP que o Login deverá ser anônimo. Caso este parâmetro não seja especificado, você deve entrar manualmente com o usuário “anonymous“. Uma senha deve ser informada, mas não será validada — pode ser qualquer coisa, inclusive “anonymous”.

Após feito o login, executamos os comandos “ls” e “dir” para recuperar a lista de arquivos e pastas disponíveis para download. Vamos então fazer o download do arquivo “leiame.txt”:

ftp> get leiame.txt
250 PORT command successful
150 RETR command started
226 Transfer Complete
ftp: 39 bytes received in 0.00Seconds 39000.00Kbytes/sec.
ftp>

De dentro do FTP Client do Windows, podemos executar um comando do sistema operacional, prefixando ele com o sinal de exclamação. Por exemplo, para verificarmos  o conteúdo do arquivo na pasta local após o Download, vamos executar o comando “type”.

ftp> !type leiame.txt
Exemplo de Configuraτπo Mφnima de FTP
ftp>

No caso, o texto do arquivo justamente é “Exemplo de Configuração Mínima de FTP”. Porém, como a página de código do Prompt de Comando está com o CodePage 437 (CodePage original do IBM-PC, também conhecido por OEM-US, CP437 ou DOS Latin US), a acentuação é mostrada com outros caracteres. Para ver o arquivo da forma correta, ele pode ser aberto pelo NOTEPAD ou qualquer outro editor de textos, OU você deve digitar no Prompt de Comando a instrução abaixo, antes de abrir o cliente FTP:

mode con cp select=1252

Com isso, o seu Prompt de Comando vai usar o CodePage do Windows, CP1252, que também é o CodePage usado pelo Protheus. Para ver a lista de instruções implementadas na camada interna do FTP Server, use o comando remotehelp

ftp> remotehelp
214-The following commands are implemented
USER PASS ACCT QUIT PORT RETR
STOR DELE RNFR PWD CWD CDUP
MKD RMD NOOP TYPE MODE STRU
LIST HELP
214 HELP command successful
ftp>

Caso você tente fazer um upload no FTP nesta conexão, a operação será negada.

ftp> put upload.txt
250 PORT command successful
550 Access is denied
ftp>

Usando outros clientes FTP

Normalmente basta desligar o “Passive Mode” na configuração do programa que você usa como Cliente de FTP (SCP, WINSCP, etc.) que a conexão e operações são realizadas sem maiores problemas.

Implementando mais controles

Na configuração mínima, o FTP está totalmente aberto para download de qualquer arquivo colocado a partir da pasta configurada na chave PATH, para qualquer cliente que conecte usando a identificação “anonymous” — ou seja, sem autenticação alguma. No máximo, usando por exemplo um recurso externo, como um Firewall, você pode permitir por exemplo apenas receber conexões FTP na porta 21 a partir de um ou mais endereços de rede, e apenas isso.

Para atender a necessidade de permitir ou restringir operações por usuário, existe a necessidade de desligar o acesso anônimo, configurar algumas chaves adicionais na seção [FTP], e criar algumas funções AdvPL no repositório para serem acionadas por estas chaves. Vamos direto para o exemplo completo:

[ftp]
Enable=1
Port=21
Path=c:\Protheus12LG\EnvLight\ftp
RPCEnv=envlight
CheckPassword=U_FTPPASS
GetUserPath=U_FTPPATH
CheckUserOper=U_FTPOPER

Primeiramente, removemos o acesso anônimo. Então, criamos uma chave chamada RPCENV, onde colocamos o nome  do environment (ambiente) existente neste Protheus Server, responsável por executar as funções AdvPL que serão colocadas para validar algumas operações do FTP.

Configuração CHECKPASSWORD

Quando um usuário conectar no FTP e informar o usuário e senha, será chamada a função U_FTPPASS(), que receberá como parâmetros o usuário e senha informados pelo cliente de FTP. Se esta função retornar .T., o Protheus Server responde ao cliente de FTP que o login foi aceito, caso contrário responde uma mensagem de erro e nega o acesso. Vejamos o exemplo abaixo:

User Function FTPPass(cUser,cPass)
cUser := lower(cUser)
if ( cUser == "root" )
  if( cPass == "root" )
    Return .T.
  Endif
Endif
Return .F. 

Neste exemplo, permitimos apenas um usuário chamado “root”, com a senha “manager”  a entrar no FTP.

Configuração GETUSERPATH

Imagine que, eu quero fornecer, por exemplo, uma pasta raiz de FTP diferenciada para alguns usuários. Para isso, eu crio uma função AdvPL — no nosso exemplo, USER FUNCTION FTPPATH(), que recebe como parâmetros o usuário e senha informados no login. A função deve retornar um PATH completo no servidor onde está sendo executado o Protheus Server, e esta pasta será o diretório raiz de FTP. Vamos ao exemplo:

User Function FTPPath(cUser,cPass)
cUser := lower(cUser)
If cUser == "siga0984"
  return "C:\Protheus12LG\ftp"
Endif
Return "C:\Protheus12LG\ftp\anonymous"

Neste caso, quando o usuário de FTP for “siga0984“, ele têm acesso à pasta raiz do FTP, quando qualquer outro usuário somente terá acesso a partir da pasta “anonymous”.

Configuração CHECKUSEROPER

Caso você queira permitir UPLOAD de arquivos no FTP, ou outras operações que modifiquem conteúdo, como apagar arquivo, criar ou apagar uma pasta, é necessário implementar uma função AdvPL para ser chamada pelo Protheus Server para autorizar estas operações, usando a configuração CheckUserOper — no nosso exemplo, vamos implementar a função U_FTPOPER(). Ela recebe três parâmetros: O usuário de login no FTP Server, a senha utilizada, e o comando enviado pelo Cliente do FTP.

Apenas alguns comandos são desviados para esta função, por exemplo STOR <arquivo>, DELE <arquivo>, MKD <pasta>,  RMD <pasta>, e dois comandos não implementados para renomear arquivo (RNFR e RNTO).

  • STOR = Upload de arquivo
  • DELE = Apagar arquivo
  • MKD = Criar pasta 
  • RMD = Remover pasta
  • RNFR <arquivo1> e RNTO <arquivo2> — Renomar arquivo1 para arquivo2

Caso a função AdvPL retorne .T., a operação é autorizada. Caso contrário, negada. Vamos ao nosso exemplo:

User Function FTPOPER(cUser,cPass,cOper)
Local cCmd
cUser := lower(cUser)
If cUser == 'root'
  cCmd := left(cOper,4)
  If cCmd $ "STOR,DELE"
    Return .T.
  Endif
Endif
Return .F.

No exemplo acima, permitimos apenas ao usuário “root” a possibilidade de fazer upload ou mesmo de apagar um arquivo remotamente.

Resultados dos Testes

Os testes realizados mostraram que alguns clientes de FTP, por exemplo o WINSCP, usou uma sintaxe para a troca de pasta (comando CWD) que o FTP Server do Protheus não entendeu, mas funcionou adequadamente com o cliente FTP nativo do Windows em linha de comando, e um cliente de FTP do Altap(r) Salamander.

Mesmo com as implementações em AdvPL, o objetivo de ter um servidor nativo de FTP no servidor Protheus é atender a necessidade de integrações entre sistemas, normalmente em ambientes restritos — ou fechados. Ele não oferece logs de utilização nativos, não permite interceptar outros comandos para implementar por exemplo restrição de acesso de usuário para uma pasta ou arquivo, etc.

Devido a questões ligadas a implementação do FTP em múltiplas plataformas, é recomendado usar os nomes de arquivos sem espaços em branco, sem acentuação, e com letras minúsculas, e utilizar sub-pastas se e somente se realmente necessário. Qualquer demanda maior, que exija mais controles, como um FTP publicado na Internet para clientes e parceiros ter acesso a múltiplos arquivos, eu pessoalmente recomendo a utilização de uma aplicação especializada em ser Servidor de FTP, que vai lhe oferecer nativamente muito mais controles do que o Protheus Server como FTP Server.

Conclusão

Para cada tamanho de problema, existe uma solução adequada. O Protheus como servidor de FTP não foi criado para competir com um FTP Server de mercado, mas apenas para ter uma alternativa simples e nativa para integração entre sistemas, onde não são necessários níveis muito avançados de controle. Porém, para o que ele se propõe, ele dá conta do recado.

Em um próximo post, vamos explorar a classe client de FTP do Protheus Server —  chamada TFTPCLIENT() — para conectar e realizar operações de Cliente de FTP conectando-se em um FTP Server configurado também no Protheus.

Agradeço novamente a audiência, e desejo a todos TERABYTES DE SUCESSO !!!

Referências

 

 

Anúncios