blog do Zé

 
 

19 de August, 2008

O Globo: “Ayres Britto garante que ‘urnas são invioláveis’”

Filed under: Perl, Pleito eletronico, Segurança de Redes — jfonseca @ 6:25 pm

Em 2000 uma urna eletrônica na Flórida deu a Al Gore o total de 16022 votos NEGATIVOS.

Em reportagem do Globo de hoje, o Ministro Ayres Britto do TSE afirmou:
- É um blefe, uma bravata e um estelionato. O sistema é absolutamente inviolável. Disseram até que têm minha senha. Nem eu fiz ainda a minha assinatura digital. E de qualquer modo é impossível fraudar, entrar no programa ou desfigurá-lo. Fizemos um software que é inviolável e inacessível aos hackers. Se o programa é alterado, a urna se autodefende imediatamente - disse Britto.

Eu não ví a reportagem do JN citada, não sei o que exatamente a imprensa vem falando do assunto. Vamos analisar apenas o que disse o Ministro.

O sistema é absolutamente inviolável.
Citamos aqui, há algum tempo(veja links relacionados), que o TSE deve saber algo que a Nasa não sabe. Porque o orçamento da Nasa é quase equivalente ao PIB do Brasil e os softwares da Nasa vivem dando pane. A Nasa não faz mistério disso porque é uma Lei Científica, provada matematicamente, que não existe software perfeito.

A última pessoa que afirmou algo semelhante ao que disse o Ministro foi Larry Ellison, Presidente da Oracle. Em 2005, Ellison estava tão entusiasmado com a segurança do Oracle 9i que ele veio a público e fez o desafio-mór: afirmou que o Oracle “era inviolável”. Não durou nem 2 semanas, pesquisadores foram à Black Hat Conference e mostraram um festival de buracos no Oracle, para deleite de Bill Gates. Outro paralelo que podemos traçar é o fato da Oracle ter um orçamento bem maior que o TSE e milhares dos melhores programadores do mundo.

Fizemos um software que é inviolável e inacessível aos hackers.
Quando o Ministro fala em “hacker”, ao que se refere exatamente? A um cabeludo com seus 20epoucos anos, diante de uma tela preta com letras verdes, fumando cigarros Camel Light, ouvindo Dead Kennedys e tentando violar as urnas do quarto escuro de sua casa? Ou o Ministro fala de um vândalo institucional, corrupto, dentro do TSE, disposto pra entregar a urna e seus segredos em troca de uma pequena soma de dinheiro? Kevin Mitnick fez tudo o que quis com tecnologia e, segundo ele, a grande parte foi apenas usando engenharia social.

Quanto ao software ser inviolável e inacessível: Entendo que o Ministro tente tranquilizar as pessoas com esse tipo de superlativo, mas certas coisas podem se virar contra sua causa.

Urnas eletrônicas possuem um “pecado original”: ainda não foi inventado sistema eletrônico de votação que seja ao mesmo tempo seguro e anônimo. Ou é seguro, ou é anônimo. Ou você confia no TSE para não revelar seu voto, ou o TSE não sabe quem votou 2 vezes.

Se o programa é alterado, a urna se autodefende imediatamente - disse Britto.
A premissa apresentada pelo Ministro invalida a afirmação anterior. Se o “programa é alterado”, significa que houve violação do mesmo. Se houve violação, o software não é inviolável. Certo? Ou estou entendendo tudo errado?

Por fim, mesmo admitindo que a urna é vulnerável e que o software foi alterado, nesse caso o software não pode ser mais confiável pra completar a rotina de autodefesa. Como é que se pode confiar num software que foi alterado?

Se o TSE quiser melhorar o sistema basta obrigar a impressão dos votos. O ideal seria que a contagem dos votos demorasse mais um pouco, e que fosse feito através de um sistema mecânico um pouco mais tradicional.

Links relacionados:

  • O TSE é melhor que a NASA
  • O Teorema de Incompletude de Gödel prova que não existe software perfeito.
  • Seção sobre Pleito Eletrônico neste blog
  • JB: “Professor da UnB questiona segurança da urna eletrônica”
  • Bruce Schneier : Problemas vários tornam urnas eletrônicas imprecisas para eleições nos EUA
  • TODAS as urnas eletrônicas de um distrito de maioría negra param de funcionar
  • Oracle dragging heels on unfixed flaws, researcher says
  • Guru says Oracle’s 9i is indeed breakable

  • • • •
     

    27 de May, 2008

    Perl: Cuidado ao atualizar o DBD::mysql para versão 4.007

    Filed under: Dicas para Webmasters, Perl — jfonseca @ 1:51 pm

    Tem 25 horas que estou tentando descobrir por que o servidor Apache decidiu gerar falhas de segmentação e derrubar o serviço aparentemente sem motivos. Ontem, na maior tranquilidade, atualizei a minha biblioteca CPAN, rodei a rotina de sempre:
    # cpan
    cpan> install Bundle::CPAN
    cpan> install Bundle::LWP
    cpan> install DBI
    cpan> install DBD::mysql
    cpan> install Apache::SessionX

    E por aí vai….são 20 módulos que atualizo sempre.

    O que me passou desapercebido foi o upgrade do driver MySQL do 4.006 para 4.007. O próprio número de versão, lá na casa dos milésimos, indica uma versão de atualização simples, que não deveria causar maiores transtornos. Eu não poderia estar mais errado.

    Logo que atualizei, reiniciei o Apache para reler as bibliotecas do Perl. Como atualizei centenas de módulos(nos Bundle::CPAN e Bundle::LWP), não desconfiei do DBD::mysql de início.

    Verificava o log do httpd pai, e, desde ontem de manhã, eis o que encontrava:
    [Tue May 27 06:01:16 2008] [notice] child pid 14013 exit signal Segmentation fault (11)
    [Tue May 27 06:01:47 2008] [notice] child pid 13698 exit signal Segmentation fault (11)
    [Tue May 27 06:02:04 2008] [notice] child pid 13678 exit signal Segmentation fault (11)
    [Tue May 27 06:56:07 2008] [notice] child pid 13999 exit signal Segmentation fault (11)
    [Tue May 27 06:57:28 2008] [notice] child pid 14000 exit signal Segmentation fault (11)
    [Tue May 27 06:58:10 2008] [notice] child pid 14004 exit signal Segmentation fault (11)
    [Tue May 27 06:59:48 2008] [notice] child pid 14008 exit signal Segmentation fault (11)
    [Tue May 27 07:00:17 2008] [notice] child pid 14002 exit signal Segmentation fault (11)

    Esses aí já são de hoje, à partir de 6 AM…. (Vida de programador não é mole…mais uma noite virada….)

    Então comecei a luta pra encontrar a biblioteca que causava o SEGFAULT. Baixei o MySQL novo e compilei, em seguida recompilei o Apache com mod_perl 1.29 para buscar a nova versão de libmysqlclient.so.16 ao invés de .so.15, reinstalei o DBD::mysql para linkar com a nova versão, porém as falhas de segmentação continuavam. Volto tudo atrás, retorno ao MySQL 5.0.51a e reinstalo as bibliotecas. Recompilo o PHP para linkar com as .so.15 e também o DBD::mysql. Só nisso se foram 40 minutos, e a cada erro me custava quase uma hora.

    Em seguida baixei o Apache 1.3.41, recompilei e nada de solucionar….
    Recompilei o Apache com e sem o mod_gzip.c e nada…
    Instalei o Apache com e sem o PHP 5.2.4 e nada….
    Recompilei com e sem o mod_ssl e nada…
    Atualizei as versões das bibliotecas linkadas ao PHP, Freetype, GD….nada…

    Começou a bater o desespero….nunca tinha visto um caso desses. Cismei que era sistema de arquivos corrompido, me deu frio na barriga de pensar em atualizar a libc com apenas acesso SSH remoto….um erro e já era. Não arrisquei. Dei um reboot e torcí pra não ser problema de disco….

    Coloquei um ping para monitorar quando o servidor voltasse à vida….em alguns instantes tenho o retorno:

    64 bytes from ……

    Maravilha…o reboot funcionou. Verifico os logs do Apache e os Segmentation Fault continuam lá….

    Já eram 5 AM quando decidí começar tudo do zero, a lógica diz que se eu não errar nada no caminho então a pane é de hardware. Não deu pra consertar do modo rápido, então vamos pela força bruta!

    Aumentei o nível de debug do Apache sem qualquer resultado, até que cheguei à conclusão que seria inevitável enfiar a mão na massa e ir atrás do stack trace do httpd até achar a chamada que estava acessando memória não autorizada. Lá vamos nós….

    Primeiro precisamos compilar o Apache com os símbolos para debug. Só há vantagem em tirar os símbolos de binários compilados se você quiser ocultar o sistema de engenheiros reversos ou tornar o binário alguns bytes menor. No caso do Apache não estamos preocupados com isso, e hoje em dia esbanjamos discos rígidos de 1 Terabyte. Então precisamos adicionar a flag -g ao gcc e recompilar tudo….

    # cd apache_1.3.41
    # vi configure
    Vá até as cercanias da linha 282:
    :282
    Antes da linha “for var in CFLAGS LDFLAGS LIBS INCLUDES DEPS; do”
    Adicione
    CFLAGS=-g

    Rode o
    # ./configure

    No meu caso eu utilizo o Makefile.PL do mod_perl assim:

    # cd ../mod_perl-1.29/
    # perl Makefile.PL USE_APACI=1 APACHE_SRC=../apache_1.3.41/src DO_HTTPD=1 USE_APACI=1 EVERYTHING=1 APACI_ARGS=’–prefix=/usr/local/apache/ –activate-module=src/modules/php5/libphp5.a –enable-module=so –enable-module=ssl –enable-module=rewrite’

    Compilar:
    # make
    # make install

    OK, 2 minutos depois e temos um novo httpd em /usr/local/apache/bin/httpd

    Agora que temos um httpd recheado de símbolos, vamos dizer ao Apache onde jogar os core dumps.

    Edite o seu httpd.conf:
    # vi /usr/local/apache/conf/httpd.conf

    Adicione :
    # 2008-05-27 problema com segmentation fault
    CoreDumpDirectory /usr/local/apache/coredump/

    Salve(no vi é com :wq!) e reinicie o Apache

    # /usr/local/apache/bin/apachectl restart

    ( Veja a linha antes de CoreDumpDirectory, a deixei lá de propósito. É sempre bom comentar as alterações para, no futuro, você lembrar que nesse dia você apanhou um bocado ;). Falando sério: hoje você lembra por que editou o httpd.conf, mas daqui a 6 meses você talvez fique na dúvida de por que a diretiva de core dumps está alí. Por via das dúvidas, comente seus arquivos de configuração. Eu utilizo sempre o mesmo formato de datas aaaa-mm-dd para poder fazer buscas no futuro por anos ou meses aproximados. )

    Agora aguarde o servidor cair! No meu caso foi quase instantâneo. Vou até o diretório de core dumps e não encontro qualquer arquivo core apesar das falhas repetidas do servidor…. São os efeitos da falta de sono, esquecí de permitir os core dumps aumentando o ulimit -c. Como ulimit -c 0 os core dumps ficam desligados….

    # ulimit -c 10240

    Damos um ulimit de 10 MBytes para tamanho máximo de arquivos core. Agora reiniciamos o Apache, e não demora encontro lá os arquivos core.nnnn. Vamos examinar o core.1035 para ver onde foi a pane:

    # gdb ../bin/httpd -c core.1035
    GNU gdb 6.8
    Copyright (C) 2008 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type “show copying”
    and “show warranty” for details.
    This GDB was configured as “i686-pc-linux-gnu”…

    [... um apanhado de saída, até chegar em ....]

    Program terminated with signal 11, Segmentation fault.
    [New process 1045]
    #0 0×084b739c in Perl_av_undef ()

    OK, o que será que houve em Perl_av_undef() ??? Esse tempo todo desconfiando do MySQL e o culpado era o núcleo do Perl ???!

    A julgar pelo nome, Perl_av_undef() parece ser uma rotina de limpeza(undef) de arrays(AV = Array Value). Sem mais chutes pesquiso no Google e descubro que não se trata de um bug do Perl e sim de uma limitação imposta pelo sistema através do ulimit. Quando o Perl tenta limpar uma estrutura de dados complexa, arrays de arrayrefs contendo referências a objetos ou hashrefs, por exemplo, ele pode gerar uma grande quantidade de chamadas recursivas. A recursividade é uma ferramenta poderosa, mas que às vezes deve ser substituída por outras técnicas para poupar a pilha. A recursividade é quase sempre uma saída elegante, porém nem sempre a mais eficiente. A cada chamada o Perl empilha mais valores na stack, eventualmente estourando a pilha e causando uma Segmentation Fault(sinal 11). Quem derruba o programa é o próprio kernel, e isso não é um bug, é uma característica de sistemas que impedem processos de levarem a máquina toda consigo no caso de perda de controle.

    Então vamos verificar o tamanho atual da pilha. Vamos aproveitar e verificar outros valores-limite para sabermos em que chão estamos pisando.

    #ulimit -a
    core file size (blocks, -c) unlimited
    data seg size (kbytes, -d) unlimited
    file size (blocks, -f) unlimited
    pending signals (-i) 16253
    max locked memory (kbytes, -l) 32
    max memory size (kbytes, -m) unlimited
    open files (-n) 1024
    pipe size (512 bytes, -p) 8
    POSIX message queues (bytes, -q) 819200
    stack size (kbytes, -s) 10240
    cpu time (seconds, -t) unlimited
    max user processes (-u) 16253
    virtual memory (kbytes, -v) unlimited
    file locks (-x) unlimited

    Temos uma pilha de 10 MBytes, o que nem sempre é suficiente. Vamos exagerar um pouco para testar nossa tese, se aumentarmos para 100 MBytes teremos a chance de ver se os core dumps deixam de acontecer.

    # ulimit -s 102400

    Verificamos se deu certo com:

    # ulimit -s
    102400

    OK, temos 100 MB autorizados pro Perl fazer a festa na pilha. Vamos reiniciar o Apache e ver se funciona.

    # /usr/local/apache/bin/apachectl stop
    # /usr/local/apache/bin/apachectl start

    Prefiro o stop e start explícitos quando estou testando, para eliminar a possibilidade de alguma memória permanecer alocada do processo anterior. Pode ser só paranóia, mas vamos adiante. Temos que aguardar alguns instantes para testar a estabilidade do novo ambiente que demos ao Apache.

    OK, após 5 minutos verifico que os Segmentation Faults continuam acontecendo…só que, conforme veremos, desta vez o culpado não é mais o Perl_av_undef()

    Vamos examinar um dos novos arquivo core.nnnn para tentar descobrir quem é o culpado desta vez.

    # gdb /usr/local/apache/bin/httpd -c core.1047
    [... cortado ...]
    Program terminated with signal 11, Segmentation fault.
    [New process 1047]
    #0 0×00b9e46b in mysql_ping () from /usr/local/mysql//lib/mysql/libmysqlclient.so.15

    Opa! mysql_ping() ….estamos voltando ao principal suspeito, desde o início o servidor caía perto de alguma chamada ao MySQL no código Perl. Vamos ver o que ocorre logo antes do mysql_ping() usando o comando where do gdb.

    (gdb) where
    #0 0×00b9e46b in mysql_ping () from /usr/local/mysql//lib/mysql/libmysqlclient.so.15
    #1 0×004d99f2 in XS_DBD__mysql__db_ping (cv=0×94d2680) at mysql.xs:519
    #2 0×001edbf4 in XS_DBI_dispatch () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/DBI/DBI.so
    #3 0×084bfa43 in Perl_pp_entersub ()
    #4 0×084be32e in Perl_runops_standard ()
    #5 0×084ba15d in Perl_call_sv ()
    #6 0×0043ae8f in EMBPERL2_CallStoredCV () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/Embperl/Embperl.so
    #7 0×00453cf0 in embperl_Execute () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/Embperl/Embperl.so
    #8 0×0045a008 in ProviderEpRun_GetContentIndex () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/Embperl/Embperl.so
    #9 0×0045891a in Cache_GetContentIndex () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/Embperl/Embperl.so
    #10 0×00434a63 in ProcessFile () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/Embperl/Embperl.so
    #11 0×004355da in embperl_RunRequest () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/Embperl/Embperl.so
    #12 0×00435b8c in embperl_ExecuteRequest () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/Embperl/Embperl.so
    #13 0×0043233f in XS_Embperl__Req_ExecuteRequest () from /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/Embperl/Embperl.so
    #14 0×084bfa43 in Perl_pp_entersub ()
    #15 0×084be32e in Perl_runops_standard ()
    #16 0×084ba15d in Perl_call_sv ()
    #17 0×08371d3b in perl_call_handler (sv=0×96a8d20, r=0×9541c14, args=0×0) at mod_perl.c:1668
    #18 0×083723f9 in perl_run_stacked_handlers (hook=0×85ef03b “PerlHandler”, r=0×9541c14, handlers=0×96a8cb0)
    at mod_perl.c:1381
    #19 0×08373861 in perl_handler (r=0×9541c14) at mod_perl.c:904
    #20 0×08395497 in ap_invoke_handler (r=0×9541c14) at http_config.c:476
    #21 0×083acd2f in process_request_internal (r=0×9541c14) at http_request.c:1299
    #22 0×083ad1a0 in ap_internal_redirect (new_uri=0×951427c “/index.html”, r=0×9512ae4)
    at http_request.c:1440
    #23 0×00386fe4 in mod_gzip_redir1_handler () from /usr/local/apache/modules/mod_gzip.so
    #24 0×00385219 in mod_gzip_handler () from /usr/local/apache/modules/mod_gzip.so
    #25 0×08395497 in ap_invoke_handler (r=0×9512ae4) at http_config.c:476
    #26 0×083acd2f in process_request_internal (r=0×9512ae4) at http_request.c:1299
    #27 0×083acd8c in ap_process_request (r=0×9512ae4) at http_request.c:1315
    #28 0×083a2ef6 in child_main (child_num_arg=12) at http_main.c:4971
    #29 0×083a3227 in make_child (s=0×87be05c, slot=12, now=1211894763) at http_main.c:5150
    #30 0×083a32c2 in startup_children (number_to_start=23) at http_main.c:5178
    #31 0×083a3a66 in standalone_main (argc=3, argv=0xbfe95934) at http_main.c:5525
    #32 0×083a434f in main (argc=3, argv=0xbfe95934) at http_main.c:5883

    Lendo de baixo pra cima, o where nos dá um trace de pilha completo desde a função main() até o mysql_ping().

    Sem mais demora, jogo a consulta no Google e o resultado é que mais alguém acaba de ter o mesmo problema há apenas 1 semana!

    E o culpado é???? O DBD::mysql v. 4.007, que foi um dos primeiros módulos que atualizamos no servidor de produção ainda ontem! Confira o report do bug MySQL clicando aqui.

    Solução: regredir para a versão 4.006. Como fazer isso se o CPAN sempre busca a última versão? É simples.

    Vá até a página do DBD::mysql no endereço http://search.cpan.org/dist/DBD-mysql/.

    Na caixa “Other Releases” escolha a versão anterior(4.006) e clique em Goto.

    Quando a página recarregar, o link Download apontará para a versão escolhida. Baixe-a, extraia com

    # tar xzvf DBD-mysql-4.006.tar.gz
    # cd DBD-mysql-4.006
    # perl Makefile.PL
    # make
    # make install
    Reinicie o Apache para ler o DBD::mysql antigo
    # /usr/local/apache/bin/apachectl restart

    E, pelo menos até o momento, os problemas de segmentação acabaram.

    Conclusões

    1) Os módulos de um servidor que se propõe a ser padrão industrial tem que ser melhor testados. O bug é crasso, é primário. O módulo tenta executar um mysql_ping() e derruba o processo todo. A MySQL, recém comprada pela Sun, vai ter que efetuar um controle de qualidade mais eficiente.

    2) O apache 1.3 está sendo lentamente abandonado, porém ele poderia ter um sistema de gerenciamento de erros mais “civilizado”. Ninguém tem o luxo de passar 20 horas no GNU Debugger verificando stack traces, recompilando programas gigantescos e tentando montar quebra-cabeças.

    3) Não confie cegamente em updates. Efetue um update de cada vez e teste o sistema novamente. Se eu tivesse testado o sistema após o update do DBD::mysql, ao invés de atualizar o CPAN todo, eu saberia que o culpado era o DBD::mysql. Nunca tinha tido problemas com um módulo do CPAN, por isso deduzí logo se tratar de algum conflito de bibliotecas compartilhadas.

    4) Aumente a pilha para processos que irão rodar durante longos períodos. Apenas 10 MB de pilha para servidores Apache, MySQL ou Oracle é muito pouco. Vimos que o DBD::mysql não era o único culpado pelos Segmentation Faults do Apache. Aumentei o ulimit da pilha para 204800 KBytes(200 Megas) para garantir.

    5) Problemas entrelaçados, como a stack pequena e o bug do MySQL combinados, podem causar muita confusão. Quem imaginaria que os 2 ocorreriam ao mesmo tempo e se manifestariam da mesma forma?! As mensagens no log são idênticas, não há diferença. Se não tivesse me dado o trabalho de compilar o Apache com símbolos e estudado o stack trace no gdb, eu pensaria que os primeiros core eram problema do MySQL. Aliás, durante boa parte da resolução do problema eu achava que as bibliotecas MySQL eram as únicas culpadas.

    Já faz 1 hora e 30 minutos que restabelecí o serviço e não vejo qualquer SEGFAULT registrado. Agora vem a parte difícil, explicar pra minha chefe tudo isso…..

    • • •
     

    23 de April, 2008

    Resumo justo, isento e imparcial das principais linguagens de programação

    Filed under: Perl — jfonseca @ 4:04 am

    Todo programador sonha em criar uma linguagem de programação, e muitos assim o fazem. Algumas linguagens se mostram expressivas, práticas e, portanto, úteis. Essas linguagens se chamam Perl.

    A seguinte tabela lógica(de verdades) resume o que há em termos de linguagens no mercado hoje.

    Linguagem de Programação = Perl
    C = pai do Perl, veterano de 65535 guerras(0 derrotas)
    Máquina Virtual = Mustang 1966 conversível
    C++ = C cheio de encrenca
    (more…)

    • • •
     

    18 de January, 2008

    Aniversário : Vinte anos da linguagem Perl!

    Filed under: Perl — jfonseca @ 10:49 pm

    Larry Wall, criador da linguagem PerlHá 20 anos, Larry Wall dava ao mundo sua maior contribuicão em software : nascia a linguagem Perl. Quem programa sistemas Unix sabe que há um certo senso de comunidade nesse ramo. Os programadores Unix se unem em torno de projetos, mesmo que isso não lhes renda um centavo de lucro. O sistema operacional Linux, o servidor Apache(e outros projetos da fundacão Apache) e vários outros projetos nasceram desse grupo de hackers(no sentido correto da palavra hacker).

    Larry Wall é mais que um hacker comúm vindo do mundo Unix.

    Especialista em linguística e exímio programador, Wall decidiu pegar todas aquelas pequenas ferramentas de manipulacão de texto que ele utilizava no ambiente Unix e recriá-las organizadamente para terminar um trabalho de geracão de relatórios que lhe foi delegado por seu patrão na época.

    O resultado foi um sistema para automatizar a saída de centenas, milhares de páginas listradas de relatórios em barulhentas impressoras matriciais. Para isso era preciso fixar as colunas, extrair e tabular os dados de alguma fonte, preparar o formato e jogar a saída no dispositivo correto. O resultado foi a Linguagem Prática de Extracão e Relatórios, no inglês PERL.

    Diz a lenda que Larry Wall trabalhou no projeto Guerra nas Estrelas do governo de Ronald Reagan. Tenho certeza que o software desse projeto era impecável, porém não podemos dizer o mesmo do resto do SDI(o nome formal do Guerra nas Estrelas era “Strategic Defense Initiative”) visto que Reagan jogou fora trilhões de dólares e o sistema é incapaz de interceptar um mosquito de Febre Amarela. Esse tipo de projeto era onde havía bom dinheiro para programadores nos EUA nos anos 1980. Os melhores programadores da época eram ligados à area militar seja pelo trabalho com criptografía e área-fim do Pentágono ou para desenvolvimento de sistemas administrativos. Segundo diversos especialistas, era assim também na URSS.

    Enfim, foi nesse contexto que nasceu a linguagem Perl. O espírito da comunidade Unix foi preservado, e configura a maior vantagem dessa linguagem sobre tantas outras. As bibliotecas Perl são todas abertas e disponíveis para qualquer desenvolvedor. São centenas de milhares de módulos que fazem de tudo o que você imaginar.

    Nos Estados Unidos há mais de uma usina nuclear que utiliza Perl em seus sistemas de controle, o Yahoo e o Google utilizam Perl em diversos sistemas de grande porte, os livros de Perl aparecem entre os mais vendidos de informática de vez em quando na Amazon e por aí vai. Tudo isso comecou há 20 anos com o trabalho de um generoso programador que doou sua contribuicão ao mundo.

    • • •
     

    11 de November, 2007

    O operador -M e o cuidado necessário com $^T

    Filed under: Perl — jfonseca @ 11:54 pm

    Ontem reencontrei os amigos Sandro e Mariana que passam o fim de semana em Brasília. Combinamos uma sessão de “filme horrível” na casa do nosso querido Mateus Tormin e, acreditem, o filme que Mateus escolheu era deveras horrível. Bem, acontece que Sandro e eu fundamos o Perl Mongers Brasilia em 1999, que era na verdade uma desculpa pra tomar cerveja e falar de Perl, e ontem o Sandro chamou minha atencão porque há tempos neste blog, segundo ele, “você só fala em Hugo Chavez e CPMF e onde diabos está o Perl!!??”. Claro que ele está com a razão e hoje decidí tentar recomecar a secão Perl aqui do blog que tem apenas uns 3 posts….

    O assunto deste post é o operador de teste de arquivo -M

    Ao trabalhar com o operador -M $ARQUIVO para obter o número de dias desde que $ARQUIVO foi alterado, deve-se observar que a forma como Perl trabalha com esse operador não é exatamente intuitiva.

    Quando você testa um arquivo com -M, espera obter o tempo desde que foi alterado até o instante em que o operador -M é utilizado. Mas não é isso que acontece.

    Perl irá lhe retornar o tempo de modificacão do arquivo até o momento em que o programa foi executado.

    Se o seu programa utiliza o operador -M e é um servidor de rede, ou daemon local, ou qualquer processo que permaneca em funcionamento durante longos períodos, o resultado pode ser um desastre.

    Veja o seguinte exemplo:


    #!/usr/bin/perl

    $data = -M "/etc/passwd";
    print "$data\n";
    sleep(30);

    $data = -M "/etc/passwd";
    print "$data\n";

    Normalmente esperaríamos que a segunda chamada a -M, após 30 segundos, retornasse uma fracão do dia 30 segundos maior(lembre-se, -M não retorna segundos como time(), e sim o número de dias e a fracão do dia atual desde que o arquivo testado foi alterado).

    Rodando o programa acima vemos que os 30 segundos não influenciam em nada o resultado de -M


    root@clapton:~/perl# perl modificado.pl
    514.301099537037
    514.301099537037

    Vejamos alguns casos em que isso pode causar problemas:

    1) Voce utiliza -M para decidir se um arquivo de log deve ser arquivado e um novo criado(estilo logrotate). Neste caso o arquivo irá crescer infinitamente pois seu programa não verá qualquer diferenca na data de modificacão à partir do momento em que o programa é rodado.

    2) Você utiliza -M para verificar se arquivos de sistema sofreram vandalismo, algo estilo tripwire. Também não vai funcionar, pois se o arquivo de sistema sendo monitorado for modificado após o nosso programa monitor ser rodado o tempo entre o retornado por -M e a data de alteracão será negativo! O que não faria sentido. Seria um bug difícil de encontrar e remover.

    3) Você utiliza -M para decidir se deve, ou não, efetuar backup de um ou mais arquivos. Neste caso pode ocorrer o efeito da data negativa do exemplo 2 e seus backups de dados valiosos podem não ocorrer conforme planejado.

    Então, o que fazer?

    Claro que em programas quebra-galho, que rodam em minutos ou segundos, a não ser que se estejam organizando longas listas de arquivos por data de modificacão, provavelmente não será preciso se preocupar com isso.

    Já em programas de longa duracão será preciso ter cuidado. Como todos os problemas em Perl, há sempre mais de uma solucão.

    As duas solucões que conheco utilizando -M envolvem refrescar a data inicial à partir da qual -M efetua sua comparacão. E qual é essa data? É aquela gravada na variável especial $^T.

    A terceira solucão que encontrei é deixar de usar -M em favor de stat().

    Confira o seguinte programa:


    #!/usr/bin/perl

    print "$^T\n";
    sleep(30);
    print "$^T\n";

    Rodando, temos o seguinte resultado:


    root@clapton:~/perl# perl modificado2.pl
    1194827682
    1194827682

    Aí está o nosso culpado. -M utiliza $^T para determinar a data de modificacão dos arquivos mas $^T não muda durante o runtime de nosso programa. Assim, tenho em mente as seguintes solucões, crie a sua ou escolha a mais apropriada.

    Solucão 1 - refrescar $^T toda vez que usar -M.
    Exemplo:

    #!/usr/bin/perl

    $data = -M "/etc/passwd";
    print "$data\n";

    #..... PROCESSO DE LONGA DURACÃO .....

    # mais tarde...
    $^T = time();
    $data = -M "/etc/passwd";
    print "$data\n";

    Solucão 2 - criar um timer com signal handler que refresca $^T para voce periodicamente. Assim há menos risco de você esquecer de refrescar $^T antes de uma chamada.

    Exemplo:

    #!/usr/bin/perl

    # arma o relogio do SIGALARM
    $SIG{ALRM} = sub { $^T = time(); alarm 5; };

    # dispara a 1a vez, daqui a 5 segundos
    alarm 5;

    print "$^T\n";

    #..... PROCESSO DE LONGA DURACÃO .....

    # $^T deve estar atualizado, com um erro máximo de 5 segundos
    # ajuste o valor do tempo do alarm de acordo com a necessidade
    print "$^T\n";

    Rodando o código acima, substituindo #….. PROCESSO DE LONGA DURACÃO ….. por um sleep(30), obtemos:


    root@clapton:~/perl# perl modificado_alarm.pl
    1194828811
    1194828816

    Percebeu que o tempo inicial não é o tempo final menos 30 segundos? Lembre-se que o sleep() acima é apenas para ilustrar um processo demorado. O sinal ALRM interrompe o sleep() aos 5 segundos(tempo que escolhemos para o alarm()) e retorna na linha após ele. Tratar corretamente de sinais UNIX é assunto para outro artigo. Lembre-se que o sinal interrompe tudo que está acontecendo e retorna no procedimento seguinte ao que foi interrompido. Saiba mais clicando aqui(link em inglês, se você conhecer em português por favor indique nos comentários deste post, obrigado).

    Solucão 3 - use stat() no lugar de -M

    stat() sempre retorna as datas de modificacão em segundos, assim basta subtrair de time() e teremos sempre preciso o periodo desde que o arquivo foi modificado.

    Exemplo:

    #!/usr/bin/perl

    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("/etc/passwd");

    $modificado_segundos = time() - $mtime;
    print "$modificado_segundos\n";

    #..... PROCESSO DE LONGA DURACÃO .....
    sleep(30);

    $^T = time();
    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("/etc/passwd");

    $modificado_segundos = time() - $mtime;
    print "$modificado_segundos\n";

    Obtemos:


    root@clapton:~/perl# perl modificado_stat.pl
    44439213
    44439243


    Lembre-se que, utilizando stat(), você obtém o retorno em segundos. Se o seu programa utilizar o número de dias e fracão de dia retornada pelo -M você deve se lembrar de converter esse dado dividindo o valor retornado do time() - stat()[9] por 86400(número de segundos num dia).

    Como em todos os artigos aqui do blog, se tiver sugestões e outras solucões para este problema, envie através do campo de comentários aqui do blog. As melhores sugestões serão publicadas juntamente com o devido crédito ao autor.

    • • •
     

    26 de December, 2006

    Passando adiante o bastão do Brasilia.pm

    Filed under: Perl — jfonseca @ 8:01 am

    Por falar em Perl…

    Há alguns meses falei da politicagem que está tomando conta do software livre no Brasil. Virou moda, comecou a dar dinheiro, etc. Era de se esperar…e como estamos no Brasil esperava também que tivesse uma pitada de samba na coisa toda.

    Após aquele post tive muito pouco tempo para tocar o grupo Perl Mongers Brasilia.pm. Recebí o contato do administrador geral dos Perl Mongers novamente em Dezembro perguntando se eu desejava fazer algo com o grupo ou passá-lo adiante. Eu respondí que, desde que não fosse passado para um politiqueiro qualquer, que eu concordaría numa boa em transferí-lo.

    Resultado: passei o controle do grupo para a administracão Pm.org que, por sua vez, está transferindo o mesmo para o amigo que havía me pedido para assumir o controle lá em Agosto deste ano(e que eu havía negado pelos motivos explicados)…. Decidí não brigar desta vez, vou abrir mão, torcer muito e ver no que dá.

    À partir deste momento não sou mais o Czar do grupo Brasilia.pm - foram 7 ou 8 anos e tenho orgulho disso, e lá do início tenho boas memórias. Já no final não podía mesmo me dedicar tanto, é boa a hora para passar adiante o bastão do Brasilia.pm.

    Valeu Brasilia.pm! Boa sorte e longa vida ao grupo Perl da Capital do nosso Brasil!

    • • •
     

    postdandee - Filtro contra ataques baseados em dicionários para Postfix

    Filed under: Perl — jfonseca @ 7:34 am

    Um certo día em julho de 2005 percebí um nível de atividade acima da média em nossa rede… Não foi um alarme, foram os LEDs do switch 3Com que fica do meu lado direito que me chamaram a atencão. Acessei o painel de controle fornecido pela nossa então provedora de link dedicado e ví que durante as últimas horas a nossa porta de saída estava sendo utilizada em sua capacidade máxima. Era uma boa conexão, portanto me interessou ver se o aumento repentino era porque nosso site estava na capa de alguma revista semanal ou se era algum problema na rede(virus costumam se espalhar pela rede local causando um grande surto no tráfego, é sempre bom ficar de olho nesse tipo de coisa).

    A atividade nos servidores não estava fora do normal, mas a porta de 100mbits de um servidor de emails no switch chamou a nossa atencão e decidimos investigar. Resultado: um gente fina do outro lado do mundo, munido de uma conexão de alta velocidade, estava tentando enviar email utilizando TODOSOSNOMESPOSSIVEIS@traveler.com.br para “revezar” seus emails de vendas e SPAM através de nossos servidores. Isso é bastante comúm, e é fácil adivinhar enderecos válidos desse jeito; principalmente se o seu email for jose@qualquerlugar.com. Se voce alguma vez recebeu um email de algum amigo, e esse amigo te jura que não foi ele que mandou então provavelmente algum servidor de email no caminho sofreu esse ataque e o email de seu conhecido pode ter sido “sorteado” à partir de um dicionário de milhares de nomes.

    Decidí então escrever um script Perl para analisar o log de emails enviados, encontrar as tentativas desse tipo e retardar o trabalho dos espertos que tentam esse truque.

    O script analisa o log de emails de tempos em tempos e bloqueia os suspeitos durante um período, desbloqueando depois. A demora é calculada para tornar o ataque baseado em dicionários impraticável(imagine tentar 1000 nomes, um a cada 1 hora).

    O postdandee estava hospedado em outro servidor, mas decidí trazê-lo para o Traveler.com.br pois o outro estava fora do ar e não tive tempo para corrigir. O outro site era em inglês, então não reparem pois não traduzí ainda.

    Encontre a última versão do postdandee aquí.

    • • •
     

    31 de August, 2006

    Parem de usar Perl 3 !

    Filed under: Perl — jfonseca @ 7:15 pm

    Curtis Poe publicou um excelente artigo sobre os vícios do Perl 3 que ainda se perpetuam em sistemas Perl 5 nos días atuais.

    A versão 4 do Perl foi lancada em 1991 especialmente para que o livro Programming Perl(também conhecido como o “Livro do Camelo”), tratasse de uma versão específica do Perl.

    Três anos depois foi lancada a versão 5 da linguagem, trazendo melhor suporte a orientacão a objetos, mais estabilidade e diversas outras melhorías. Na minha opinião Perl 4 e Perl 5 são duas linguagens totalmente distintas, e não tenho dúvida que a nova versão é muito superior.

    12 anos mais tarde há gente que ainda utiliza sintaxe do Perl 3, o que cria problemas de compatibilidade e torna difícil a manutencão de código legado. O artigo é curto e cita poucos exemplos, mas vale a moral da história. Deixemos Perl 3 onde ele deve estar : na história das boas linguagens de programacão de sua época.

    Não arrisquei colocar uma traducão automática pois não seria de muita ajuda.

    • • •
     

    2 de August, 2006

    Arthur C. Clarke revisto

    Filed under: Perl — jfonseca @ 4:32 pm

    “Qualquer tecnología suficientemente avançada é indistinguível de um script Perl”

    - Larry Wall, Setembro de 1996 - Programando Perl, 2a Edição (EUA) rodapé da pág 301

    A frase é uma brincadeira do criador da linguagem Perl, Larry Wall, com uma das “3 leis de Clarke” publicadas em 1961 no livro “Perfís do Futuro”(Profiles from the Future) de autoría do escritor britânico Arthur C. Clarke (você o conhece pois ele escreveu “2001: Uma odisséia no espaço”).

    Arthur C. Clarke não conseguiu terminar o curso superior por falta de dinheiro, lutou na II Guerra Mundial  como operador de radares. Após a guerra Clarke voltou aos estudos e formou-se em matemática e física. Nos anos 50 Clarke publicou os clássicos de ficção científica da série “2001″, tornadas em cults históricos nos filmes de Stanley Kubrick.
    A versão original, e incompleta por não mencionar Perl, da frase clássica diz:

    “Qualquer tecnología suficientemente avançada é indistinguível de mágica”

    (Aparentemente o comentário foi removido na 3a edição de “Programming Perl”.)

    • • •
     

    Nasce a seção Perl

    Filed under: Perl — jfonseca @ 1:36 am

    Amigos, estou iniciando, à partir de agora, uma seção do blog dedicada à linguagem Perl. Perl é, de acordo com seu criador, a linguagem “patologicamente eclética, listadora de besteira “, ou, falando mais seriamente “practical extraction and report language”. Conforme publicar mais à respeito dela tudo isso ficará mais claro. Vale a pena conhecer sua história mesmo que você não seja tecnicamente inclinado ou deteste números.

    Nasce a Nomenklatura do Software Livre

    Recentemente fúi cobrado por um membro da comunidade Perl por não estar, como líder e fundador do grupo Perl Mongers de Brasilia desde 1998 (brasilia.pm.org) “publicando nada, nem organizando eventos, nem catequizando usuários de outras linguagens, nem medindo o número de usuários Perl de Brasilia”, nem reunindo a turma do Perl como fiz durante tanto tempo de 1998 pra cá. Enfim, o amigo me disse que eu “não faço nada”….

    Ele tem razão em parte: tenho tido pouco tempo realmente pra me dedicar como em 1998, não dá pra manter o ritmo de Carl Lewis da programação pra sempre…. Quando começamos a estudar Perl o software livre ainda não tinha a projeção de hoje. Era algo meio esotérico programar Perl no meio onde prevalescem outras excelentes linguagens como object pascal e, essa próxima não tão excelente assim(é minha opinião, não me fuzile por isso) : o velho Basic de Bill Gates. Tinha mais graça….éramos mais “especiais” por usarmos Perl!!! Mas, de hoje em diante, quero retomar a divulgação do Perl, acho que ainda posso dar minha contribuição.

    Quero, antes de começar, comentar algumas das afirmações que esse membro da comunidade Perl me fez via email hoje(editado 2/8 : que fique claro que penso isso de vários projetos de software livre, não é nada pessoal).

    Primeiro, e mais importante : Perl não é religião, e quem estiver tentando transformar uma ótima tecnología em religião está na verdade trabalhando para estragar tudo. Pode ser qualquer tecnología. Tem babaca pra tudo. Tem gente cuja profissão é “evangelista” de tal coisa. Fiquem longe de mim, isso é babaquice.

    Segundo: software livre não é ideología. Software livre é uma metodologia de trabalho que permite a rápida e eficiente compilação do conhecimento de centenas de milhares de pessoas para dar origem a algo bome bem feito. E nada além disso.

    Terceiro: software livre, e Perl, não estão em guerra com ninguém. Me disseram que eu, como “líder do grupo de Perl da capital do País”(não sou eu que digo, ouví com essas palavras, verbatim) tenho obrigação de trabalhar para evitar que a popularidade do Perl caia. São 10 quilos da mais pura bullshit. E ainda tive que ouvir o seguinte: “que as vendas de livros de Perl estão caindo, e isso significa que Perl está em baixa”. Se está, problema de quem não usa Perl, pois Perl é a linguagem mais poderosa que conheço. O espírito do software livre é que ele é melhor que o fechado, e ponto final. Não preciso provar nada sobre Perl para ninguém, nem estou numa cruzada para divulgar minha linguagem ou religião. Quem quiser saber mais sobre Perl terá sempre meu apoio, mas não passa disso.

    Tendo dito isso, quero falar de Perl para que todos compreendam. Quem teme os números e linguagens de computador poderão entender melhor o que é software livre e Perl. Perl é tão poderosa que funciona em usinas nucleares e em milhões de sites, alguns com milhões de hits diários como é o caso do Slashdot.org.

    Á, e a tal nomenklatura? A experiência que tenho tido com software livre me trouxe lembranças de uma história bem conhecida do século 20 - a da total deturpação de um belo conceito para produzir um instrumento de poder como jamais visto na história. A nomenklatura soviética nasceu da exploração de um sonho de milhões de pessoas, a sociedade que sería igualitária e justa passou a ter uma classe dominante e medíocre. Pessoas bem relacionadas com a nomenklatura tinham benefícios. É o que acontece hoje no mundo do software livre. Programadores de software livre viram ícones, viram ídolos. E quem se relaciona com eles passam a ter algum tipo de benefício….estranho isso. Não sei por que pensei nisso, vai ver é porque Fidel Castro está doente e toda essa coisa da guerra fria anda fresca na memória. Ou vai ver foi porque esse sujeito disse “eu conheço o líder do movimento Perl no Brasil e você não está fazendo o suficiente para divulgar a religião”…. É preciso impedir que software livre se torne instrumento político, pois já está virando e isso pode ser uma grande ameaça à liberdade e democracía do software aberto. O assunto veio à tona também pois hoje escutei bastante besteira sobre isso. Desculpe falar assim, mas é que realmente ouví besteira : “Perl é religião”, “você tem obrigação disso e daquilo”, “o site está fora do ar”, enfim…a coisa está virando uma máquina como outra qualquer…o software livre já virou cultura pop… Não há nada de errado com a cultura pop, mas temos que manter as devidas proporções, como dizía o sábio Fyodor Ulyanov Ermenerstróvskisastiusmensch.

    Enfim, se continuar assim eu saio do Perl Mongers de Brasilia. Ninguém poderá tirar de mim o que já está feito: quando Perl não era cultura pop e cientista político não se dava bronca em programadores de Linux e Perl(o tal sujeito é cientista político, nada contra os politicos e cientistas da área) e o “Dotô” Sandro Vitenti fundamos o grupo de Brasilia. Se alguém quiser fazer dele instrumento para cruzadas anti-Ruby ou Python, que faça. Mas eu estou fora desse barco…. Voltando ao Perl, desse barco eu não saio! Vejamos no que dá essa nova seção sobre a melhor linguagem do mundo!

    • • •