Categorias
Linux

Convert e mogrify

ImageMagick é tão perene quanto a grama. Encontrado em algum script PHP para aplicações KDE, é uma biblioteca caracterizada pelo processamento e edição de imagens com um batalhão de pequenas ferramentas. Há aproximadamento 100 dessas ferramentas, e duas das mais úteis são convert e mogrify - comandos que rivalizam com recursos do Gimp. Ao usá-las, você pode redimensionar, esmaecer, cortar, ajustar e transformar uma imagem sem precisar olhá-la. A diferença entre convert e mogrify é que com a última você pode sobrescrever as imagens originais ao invés de criar um novo arquivo para a imagem modificada.

Apesar de todas as funcionalidades complicadas, uma das melhores razões para usar convert é a sua função mais óbvia, que é a de modificar o formato de uma imagem. Em sua mais simples, você precisa apenas incluir os nomes de arquivo fonte e destino, e o convert vai se encarregar dos detalhes. O exemplo a seguir converta um arquivo JPEG em um PNG:

convert pic.jpg pic.png

ImageMagick é perfeito para lotes de imagens, mas ele não utiliza coringas da maneira experada. convert *.jpg *.png não funciona, por exemplo. A resposta é usar um sintaxe levemente diferente e substituir o comando convert por mogrify. Ao invés de usar um coringa para o formato de destino, define-se o tipo de extensão que se deseja. Para converter um grupo de imagens JPEG para o formato PNG precisamos digitar apenas o seguinte:

mogrify -format png *.jpg

Esta proximidade pode ser usada com qualquer parâmetro de convert e mogrify. Você pode usar o formato substituto com crop ou scale em um lote de imagens, por exemplo, se você precisar escalar ou cortar um diretório inteiro de imagens.

Mais em Truques de linha de comando.

Categorias
Linux

Ganhando argumentos

Não podemos ensiná-los a ser vitorioso em cada debate, mas podemos mostrá-lo como ser mestre em outro tipo de argumento: os da linha de comando. Você provavelmente conhece como fornecer múltiplos argumentos a um programa, como por exemplo:

someprog file1 file2 file3

O que é muito bom quando informa comandos manualmente, mas e quando precisa usar uma lista gerada por outro programa? Digamos, por exemplo, que você deseja que o Gimp abra dez imagens grandes de um diretório. Você poderia usar ls -l para encontrar quais são os maiores e então ter o trabalho de informar cada nome de arquivo em gimp arquivo1 arquivo2... Ou poderia a mágica xargs (presente em todas as distribuições).

ls -S --color=never | head -n10 | xargs gimp

xargs monta operações complicadas de linha de comando usando lista de arquivos para que você não precise digitá-las manualmente. Passe uma lista de arquivos ao xargs e ele os arranjará como arquivo1 arquivo2 arquivo3... como vimos anteriormente. Faz sentido? Considere o exemplo acima. Primeiro usamos ls para gerar a lista de arquivos do diretório atual (tendo certeza de que desabilitamos os códigos coloridos já que eles produzem caracteres indesejáveis). Então, usando o bom e velho pipe (|), enviamos o resultado para o utilitário head, que separa as primeiras dez ocorrências.

Agora então temos uma lista de dez arquivos. Como informamos ao Gimp que queremos abrí-los? Não podemos enviar diretamente os resultados de head, pois o Gimp interpretaria como se fossem simples dados gráficos. É aqui que o uso de xargs salva o dia: ele garante que o program cujo nome está a a seguir usará os dados como uma lista de arquivos ao invés de tentar trabalhar diretamente com eles. No nosso exemplo acima, ele diz "pegue os dez primeiros da lista gerada pelo head e então passe para o Gimp no formato tradicional arquivo1 arquivo2 arquivo3...". Você pode fazer muitas coisas com xargs, tudo o que esperad uma lista de arquivos, separados por caracteres de nova linha ou espaços. Como outro exemplo, este apaga todos os arquivos com mais de dez dias (use com cautela!):

find . -mtime +10 | xargs rm

Mais em Truques de linha de comando.

Categorias
PHP

Segurança no PHP II

Requisito 4: Sem erros para o usuário

Falaremos aqui de outro ponto importantíssimo na questão de segurança que é freqüentemente ignorado pelos desenvolvedores: as mensagens de erro.

As mensagens de erro foram feitas para que o desenvolvedor possa trabalhar de forma mais prática e descobrir o que ele está fazendo de errado. Observem, entretando, que, quando uma aplicação atinge maturidade suficiente para "entrar em produção", torna-se imperativo que o usuário não visualize mensagens de erro.

A razão disso é muito simples: as mensagens de erro freqüentemente trazem informações sensíveis. Observe como exemplo uma típica mensagem de falha de conexão com a base de dados:

Warning: mysql_connect() [function.mysql-connect]:
Access denied for user 'foo'@'localhost' (using password: YES)
in /usr/local/apache/htdocs/script.php on line 2

Note, através das partes destacadas, que esta mensagem me informa:

  1. O tipo de RDBMS: mysql
  2. O usuário de conexão com a base: foo
  3. Que este usuário está tentando uma conexão de dentro do servidor: localhost
  4. O caminho absoluto da raiz web: /usr/local/apache/htdocs
  5. O nome do script: script.php

É por isso que, quando colocamos uma aplicação em produção, ocultamos as mensagens de erro e as gravamos diretamente em um arquivo de log. Isto é muito simples de implementar:

Exemplo:

display_errors = Off
log_errors = On
error_log = /log/php_errors.log

Requisito #5: Esconda do servidor web o que ele não precisa acessar

Quantos de nós não usamos em nossas aplicações um arquivo, tipicamente chamado de config.php ou setup.php, onde guardamos, por exemplo, usuário e senha da base de dados?

Não há nada de errado nisso, mas cuidado: se este arquivo não gera saída de informação em HTML, por que deixá-lo acessível via web?

Para esclarecermos o problema, vamos definir 3 coisas:

  1. minha raiz web é: /usr/local/apache/htdocs
  2. meu arquivo de configuração fica localizado em /usr/local/htdocs/config/config.php
  3. este é um código típico que usa este arquivo:

require_once("/urs/local/htdocs/config/config.php");
/ bla bla bla /

Observe que o erro neste caso é confundir interpretador PHP e servidor web. O Apache (ou IIS, Xitami etc) não precisa saber onde está este arquivo. Isto é responsabilidade do interpretador.

Outro problema é que se arquivo fica desnecessariamente exposto, afinal de contas basta eu abrir um navegador e digitar:

http://www.meusite.com.br/config/config.php

Não faz sentido. Por mais que você possa argumentar que não há forma de ler o código-fonte deste arquivo, ainda assim, isto não muda o fato de que ele está desnecessariamente exposto.

A solução é simples: movemos o arquivo para fora da raiz web:

/usr/local/config/config.php

E depois apenas acertamos as permissões e corrigimos nosso código:

require_once("/urs/local/config/config.php");
/ bla bla bla /

A partir de agora nosso arquivo de configuração só pode ser lido por quem precisa dele: o interpretador PHP.

Requisito #6: Use criptografia

Dados sigilosos são chamados assim por um motivo. Quando tratamos especificamente de senhas é impressionante a quantidade de aplicações web que gravam senhas em texto puro na base de dados.

Ora, se a senha possui a importância que tem e quem a escolhe é o usuário, por que alguém mais precisa ler essa senha?

Se a senha possui este peso em nossa aplicação, não podemos nos dar o luxo de fazer com que ela trafegue pela aplicação totalmente exposta.

PHP implementa criptografia de várias formas, mas eu sugiro - para quem puder usar, pois exige instalação e configuração extra - a utilização da função mcrypt.

Os hashes MD5 e SHA-1 são opções válidas, mas o problema é a sua fragilidade: para o MD5 existe até dicionário de dados, enquanto o SHA-1 foi recentemente "quebrado" por um pesquisador chinês.

Conclusão

A implementação de regras básicas de segurança depende apena da boa vontade do desenvolvedor. Você deve ter percebido como a maior parte das soluções aqui apresentadas significam simples mudanças de hábito.

É mais do que tempo de nós, desenvolvedores PHP, deixarmos de lado nossos antigos vícios e começarmos a implementar boas práticas de programação.

Ganha o profissional, ganha a sua aplicação, ganha o seu cliente, ganha o mercado. Só quem perde nessa situação é quem tenta se aproveitar de nossa aplicação.

Referências e links sugeridos

[PHP Security Consortium] - http://phpsec.org/

Er Galvão Abbott trabalha há mais de dez anos com programação de websites e sistemas corporativos com interface web. Autodidata, teve seu primeiro contato com a linguagem HTML em 1995, quando a internet estreava no Brasil. Atualmente, além de lecionar em diversos cursos, tem se dedicado ao desenvolvimento de sistemas baseados na web, tendo nas linguagens PHP, Perl e JavaScript suas principais paixões.

Parte I

Categorias
Linux

Uma lição de history

Enquanto o autocompletar de comandos é um dos aspectos mais usados e adminirados do Bash, uma característica igualmente poderosa normalmente é ignorada. O armazenador de histórico, comumente usado para navegar para trás e para frente pela lista de comandos já executados, oferece muito mais possibilidades que  se pode imaginar. Enquanto é bem simples navegar pela lista, algumas vezes o comando desejado pode estar tão atrás no histórico que acaba sendo inviável. O comando history pode imprimir tudo o que está armazenada na tela. O uso mais óbvio para isso é redirecionar a saída do comando para o grep a fim de encontrar uma parte do comando a lembrar.

history | grep "command"

Se o comando ainda estiver no armazenador ele será mostrado em seguida com a posição que ocupa. O comando pode ser reexecutado através do seu número prefixado com o ponto de exclamação para marcar a posição. Por exemplo, !1016 executaria o comando no ponto 1016 do histórico do Bash. Outro truque é seguir o ponto de exclamação com uma parte do comando executado. O histórico será procurado e quando uma correpondência ocorrer, ela será executada.

!cd executaria o último comando cd que está no buffer. Infelizmente, os comandos não se adicionam ao histórico do buffer, então sua execução recursiva não é possível. Outra maneira de acessar o histórico de comandos é através da função de busca acessa ao pressionar Ctrl-R no terminal. Após pressionar a seqüência você será apresentado a um terminal de busca. Ao digitar o termo de buscar o primeiro comando que corresponder ao critério será exibido e ao pressionar Enter o comando será executado. O cursos esquerda ou direita insere o comando para o terminal, enquanto acima e abaixo lhe direcionam para o comando anterior e posterior, como usual.

Mais em Truques de linha de comando.

Categorias
Linux

Chaves seguras

Dependemos da encriptação para manter nossos dados seguros, mas isto significa ter várias chaves e senhas que devemos nos preocupar. Uma chave GPG tem uma senha para protegê-lo, mas e as chaves do seu sistema de arquivos ou chaves de autenticação SSH? Manter cópias em dispositivos USB parecem uma boa idéia até que você perde o dispositivo e todas as suas chaves se tornam de domínio público. Até mesmo a chave GPG não fica seguro já que é óbvio que ela significa e a senha pode ser quebrada com ataque de dicionário.

Um arquivo encriptado dos seus dados mais sensíveis tem inúmeras vantagens: tudo fica protegido com uma senha (adicionando uma segunda camada de encriptação no caso de uma chave GPG) e disfarça o conteúdo do arquivo. Alguém que encontre o seu dispositivo USB encontraria dados sem conseguir identificar o significado do seu conteúdo. O Ccrypt (http://ccrypt.sourceforge.net) é uma boa opção para fazer isso, pois possui uma encriptação forte e pode ser usado para encriptar fluxos tar, como em

tar -c file1 file2... | ccencrypt >stuff

e extrair com

ccdecrypt <stuff | tar x

Se você realmente quer ocultar seus dados, use o Steghide (http://steghide.sourceforge.net) para esconder os dados com outro arquivos, como uma foto ou arquivo de música

If you really want to hide your data, use Steghide (http://steghide.sourceforge.net) to hide the data within another file, such as a photo or music file

steghide embed --embedfile stuff --coverfile img_1416.jpg

e extrair com

steghide extract --stegofile img_1416.jpg

Mais em Truques de linha de comando.

Categorias
PHP

Enviando mensagens com o PHPMailer

O PHPMailer é um componente de envio de e-mail para servidores que exigem autenticação ou para um desenvolvedor que deseje configurações mais avançadas para a rotina de e-mail pelo php que o a função mail() não possua. É importante percebermos que um servidor que exige autenticação o faz por razões de segurança, para que o mesmo não caia nas listas negras caracterizado como um servidor de Spams.

A seguir, um exemplo de código para envio de e-mail pelo PHPMailer (para páginas de Contato ou Fale Conosco, por exemplo).

Obs: O ideal é que você baixe o PHPMailer e coloque no seu próprio servidor, deixando com que o seu domínio sempre tenha independência e rapidez no envio de mensagens através das suas páginas.

Categorias
PostGreSQL

Substituir conteúdo win1252 para utf-8

Não devo ser o primeiro a precisar exportar dados de um banco PostGreSQL instalado em Windows com codificação win1252 para um banco com codificação em utf-8 (no meu caso, em servidor Linux).

Não basta transformar o arquivo de importação para utf-8, pois os caracteres do win1252 (aspas duplas à esquerda, aspas duplas à direita, aspa simples e travessão) estarão lá, com um valor esquisito no seu banco. A minha solução foi importar assim mesmo e depois realizar um update usando uma função para corrigir.

Os exemplos de código a seguir são para: 1 - transformar para caracteres HTML; 2 - transformar para os caracteres simples.

HTML:

Simples:

Não se preocupe com os quadrados que aparecem. Se você copiar para um bom editor de texto, verá que possuem valores diferentes.

Categorias
Linux

Matando os zumbis

Se você passa algum tempo olhando para a sua lista de processos, cedo ou tarde vai se deparar com um processo chamado 'defunto' (defunct). Antes de explicar o que é um processo defunto e como removê-lo, segue um resumo de como consultar a tabela de processos usando o comando ps.

Digitar ps ux listará todos os processos atribuídos ao usuário atual e é possível especificar outro nome de usuário com ps U username. Um dos usos mais comuns para ps é de listagem de todos os processos que estão sendo executados no sistema através de ps aux. Quebrando o comando por partes, o a lista todos os processos ao invés de somente os de um único usuário, o u é o nível de detalhes retornados por cada processo e x lista os processos executados pelo daemon não executados por um terminal.

Um processo defunto é um processo iniciado por outro processo (o pai), mas que foi finalizado antes que o processo pai tenha sido completado. Isso pode acontecer se o processo pai ficou pendurado ou quebrado.

Os processos defuntos são também conhecidos por zumbis e listados com status 'Z' na saída do ps. Eles não são tão destrutivos quanto os mortos-vivos, já que eles não consomem quase recurso do sistema, mas em um sistema que está sempre ativo, como um servidor, eles podem se tornar distrativos. O segredo para matar um processo defunto é primeiro matar o pai, que estará listado na saída do ps adicionado de -l para grandes retornos. Os processos pais podem ser identificados através da coluna PPID ao invés da coluna PID, a coluna com o ID do processo. Esses são identificadores anexados a cada processo executado no seu sistema. Eles podem ser mortos usando outro comando no shell, kill -9, seguido do PPID. Obviamente, isto irá parar a tarefa pai, então se certifique primeiro de que a tarefa não é essencial. Uma vez que a tarefa pai tenha sido morto, o processo init do sistema deverá enviar o sinal correto aos processos defuntos, que devem terminar automaticamente.

Mais em Truques de linha de comando.

Categorias
Linux

Melhor que navegador

Se você precisa freqüentemente recuperar páginas da internet e achá-lo com um navegador é como usar uma marreta para quebrar um ovo, então o wget é para você. A página de informação descreve soberbamente a utilidade para download não-interativo de arquivos da internet; mas o que eles querem dizer é que às vezes ele funciona melhor do que um navegador. Você pode usar o wget num código para fazer download de páginas ou arquivos e ele é perfeito para sincronizar aquivos locais da web. Você não precisa nem utilizá-lo a partir de um script - ele funciona muito bem quando executado diretamente do terminal (http://wget.sunsite.dk).

O mais simples uso do wget é para baixar um arquivo pela URL:

wget http://localhost/somefile.tar.gz

Isto deve mostrar uma barra de download em formato texto. Infelizmente, se o site usar o protocolo HTTP, wget não suportará coringas, então, você não pode usar *.gz para fazer download múltiplo de arquivos (mas pode usar se o site é acessado por FTP). wget é bastante usado para espelhar um site inteiro. Por exemplo:

wget --mirror -p --html-extension --convert-links http://localhost

Wget atravessa todo o site e baixa o conteúdo no diretório atual. O argumento mirror habilita opções adequadas para espelhar um site - em particular, recursão por atravessar a árvore completo do site. htmlextension é usada para sites que usam também scripts CGI para gerar HTML, ou arquivos ASP que precisam ser renomeados depois de baixados. Se wget reconhecer o conteúdo, ele apenas acrescenta a extensão HTML.

Terminada a transferência, wget varre todos os arquivos locais para trocar qualquer referência remota para que o site possa ser visto desconectado.

Mais em Truques de linha de comando

Categorias
Linux

Evitando múltiplos terminais – Trabalhando com telas

Terminais virtuais são como crianças: ter um, dois ou até três trazem alegria à sua vida, mas mais do que isso põem tensão nos seus recursos. Quando trabalhando remotamente, algumas pessoas se vêem sem a possibilidade de abrir múltiplos terminais, então simplesmente abrem várias conexões SSH na mesma máquina. Isto não é apenas um desperdício de tráfego, mas também um sinal de que você é um iniciante - o que você não é, certo? Veteranos sabem que há uma maneira muito melhor para abrir múltiplos terminais e isso vem na forma do programa de telas GNU. Para começar, abra um terminal, digite screen e tecle Enter. Seus terminal será substituído por um console vazio e você pode pensar que nada aconteceu, mas na verdade aconteceu - como você verá.

Digite qualquer comando que quiser, ex: uptime, e tecle Enter. Agora pressione Ctrl+a depois c e você poderá ver outro terminal em branco. Não se preocupe, seu antigo terminal ainda está lá e ainda ativo; este é um novo. Digite outro comando, ex: ls.

Agora pressione Ctrl+a depois 0 (zero) - você verá seu terminal original novamente. Como você pode ver, Ctrl+a é a combinação que sinaliza que um comando está para vir - Ctrl+a depois c cria um novo terminal e Ctrl+c depois um número o leva ao respectivo terminal. Você pode usar Ctrl+a depois Ctrl+a para trocar para a janela selecionada anteriormente, Ctrl+a depois Ctrl+n para trocar para a próxima janela ou Ctrl+a depois Ctrl+p para trocar para a janela anterior. Para fechar janelas apenas digite exit.

Quando sua última janela fechar você também sairá do screen e será impresso na tela 'screen is terminating' para lhe lembrar. Como alternativa - e isto é o melhor coisa sobre tela - você pode pressionar Ctrl+a depois d para desanexar sua sessão de tela. Depois, de outro computador mais tarde, utilizar screen -r para recuperar de onde deixou com todos os programas e saídas intactos - mágico!

Mais em Truques de linha de comando