Instalando leitores de impressão digital modelo Digital Persona no Linux

Liberdade! Por muito tempo os produtos da Digital Persona funcionaram somente sobre a plataforma Windows. Com o passar do tempo surgiram alternativas proprietárias. Mas agora a comunidade pode contar com um driver de código aberto para Linux, desenvolvido sobre análise de tráfego na porta USB na plataforma proprietária.

[ Hits: 118.965 ]

Por: Alessandro de Oliveira Faria (A.K.A. CABELO) em 17/05/2006 | Blog: http://assuntonerd.com.br


Introdução



Não entrarei em detalhes sobre o assunto biometria em geral, pelo simples fato de existir um excelente texto publicado aqui no Viva O Linux pelo membro Jonilson:
O principal objetivo deste documento é facilitar a instalação dos leitores produzido pela Digital Persona em sistema operacional Linux. Pois até então a instalação destes equipamentos só eram possíveis em plataformas Microsoft.

Daniel Drake desenvolveu um driver para os leitores da Digital Persona baseando-se em análise de tráfego USB na plataforma Windows. Quando o driver estiver 100% concluído, será submetido para a inclusão no Kernel do Linux.

Abaixo a lista dos leitores com compatíveis e algumas especificação:


Microsoft Optical Desktop with Fingerprint Reader keyboard


Microsoft Wireless IntelliMouse Explorer with Fingerprint Reader


Microsoft Fingerprint Reader


Digital Persona U.are.U 4000/ 4000B

Os leitores de impressão digital u.are.u são amplamente utilizados no mercado brasileiro. Seu modelo se enquadra na categoria tipo ótico, possui um prisma translúcido ou um acrílico sobre o qual você coloca o dedo. Este modelo produz imagens de melhor qualidade comparados aos outros modelos.

Os leitores da Digital Persona U.are.U possuem 512 DPI e suportam USB 2.0. Já o modelo Microsoft Fingerprint Reader, que também é produzido pela Digital Persona (qualidade similar e um menor preço), só poderia ser utilizado no Windows XP.

    Próxima página

Páginas do artigo
   1. Introdução
   2. Preparação de ambiente (kernel 2.6.26-6)
   3. Download dos componentes
   4. Compilação e instalação do driver
   5. Compilação da biblioteca e aplicação
Outros artigos deste autor

Acessibilidade: Movimentos do mouse com a face (eViacam)

Criando aplicativos para o iPhone no Linux (sem Xcode e MacOS X)

KDE-Edu e Gcompris: Software Livre a serviço da educação

Stella: Crie o seu próprio arcade ATARI 2600

Conectando com Bco Interbase/Firebird em Java

Leitura recomendada

Instalação da impressora Canon Image Runner 1023n no Ubuntu

Linux, 100% compatível!

Regulando o desktop para trabalhar em máxima performance

Configure seu modem SmartAx MT810 no Ubuntu

Placas de vídeo que já perderam o suporte no Linux

  
Comentários
[1] Comentário enviado por removido em 17/05/2006 - 17:05h

Artiguh expectacular e bastante interessante...
5*'s!!!!!! =P

[2] Comentário enviado por asmith em 18/05/2006 - 10:05h

Otimo artigo...
Vou tirar o meu uareu 4000 do bau!!!

[]'s =]

[3] Comentário enviado por lexemail em 18/05/2006 - 12:15h

Não to conseguindo baixar os trio :(
* Driver do sensor (módulo do kernel);
* Script para download e extração do firmware;
* Biblioteca para o desenvolvimento de aplicações.

Talvez o site esteja indisponivel ou fora do ar. Alguem aí já conseguiu??
Se puderem mandar pra mim por email, eu fico grato :)

[4] Comentário enviado por CABELO em 18/05/2006 - 14:45h

Caro Lexemail...

Envie o seu e-mail para envio dos pacotes..

Abraços

[5] Comentário enviado por drausio em 19/05/2006 - 11:24h

Esse é o cara!!!

Abraçaum

Drausio

[6] Comentário enviado por lexemail em 20/05/2006 - 19:19h

Caro Cabelo...

Obrigado por responder :)

Hoje consultando o link, colocaram dois servidores e consegui baixar.

Pô, esqueci de comentar, Cabelo seus artigos são show de bola, valeu por mais esse :)

[7] Comentário enviado por mtec em 07/06/2006 - 13:11h

10... muito bom o artigo!!!!

[8] Comentário enviado por hellwalker em 07/06/2006 - 21:05h

Eu tinha entrado em contato com a digitalpersona no final do ano passado. E eles responderam que estavam terminando o desenvolvimento do driver para o kernel 2.4 e que o lançariam no começo do ano, depois entrei em contato novamente com eles e falaram que havia sido adiado para março e até agora nada. Cabelo, parabens pelo artigo. Nao vejo a hora de fazer ele funcionar.

[9] Comentário enviado por ale_pira em 09/06/2006 - 11:05h

Ótimo artigo! Vou tentar instalar no linux e desenterrar meu msfingerprint reader....

Cabelo, tenho só uma dúvida: Todas as bibliotecas windows falam em limitação de velocidade entre versões free (pra desenvolvimento) e na versão paga. Porém (mesmo na paga) fala-se em 'comparações por segundo'. Por acaso não se trata de uma leitura extensiva do arquivo, registro a registro né?

Eu acho que só se tem performance com uma boa indexação, e se o algoritmo for consistente a ponto de gerar sempre uma mesma id-chave para uma digital (acho que nem pode ser diferente!), pode-se indexar o campo e buscar a digital diretamente; ou eu entendi errado e estou pensando besteira??

Obrigado!

[10] Comentário enviado por julianometal em 30/06/2006 - 07:56h

Primeiramente gostaria de parabenizá-lo por mais esse ótimo artigo!

Por acaso trabalho em uma empresa que vende o Digital Persona.
Aqui no serviço uso o Debian e inicialmente havia seguido todos os passos, porém sem sucesso.
Simplesmente ao plugar o digital persona não carregava o firmware.
Então dei o comando:

#apt-cache search hotplug


Dentre os resultados veio o aplicativo "fxload", que tem a seguinte descrição:

"fxload is a program which downloads firmware to USB devices"

Traduzindo (toscamente):

"fxload é um programa que carrega o firmware para dispositivos USB"

Que neste caso foi necessário.

Então o instalei com o comando:

#apt-get install fxload

E então sucesso!

Espero que os próximos que tentarem não esbarrem na mesma coisa que eu (risos).

Um grande abraço a todos que vivem a realidade Linux!

[11] Comentário enviado por testas em 20/11/2006 - 15:35h

Boas amigos
Gostei muito dos artigos que aqui estao, estava mais interessado em criar uma mysql database para realizar a autenticação e um user e dar acesso ou autorização a abrir um trinco de garagem com o fingerprint que aqui referem, como poderei dar os proximos passos , gostaria de ter algumas sugestões vossas.
Cump.
Testas

[12] Comentário enviado por ChArLeS_TI_MG em 15/02/2007 - 11:17h

Bom dia todos,

Estou instalando o sistema aqui e encontrei o seguinte erro na hora de compilar a biblioteca:

charles@ti-teste:~/Desktop/libdpfp-0.1.1$ sudo ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... configure: error: C compiler cannot create executables
See `config.log' for more details.

Estou usando o Ubuntu na sua ultima versão, nos demais passos deu tudo certo.

[13] Comentário enviado por nat_ram2002 em 13/04/2007 - 11:05h

tenho uma leitora digital Fingerprint Reader da Microsoft mais nao tenho o solftware com aficha de cadastro alguem conhece algum downloads de gerenciador de cadastro gratis.

[14] Comentário enviado por amadeujr em 04/06/2007 - 14:34h

Aeew meu povo. Para quem precisar usar o sensor mas odeia que o dispositivo seja criado com as permissões para o root basta criar um arquivo em /etc/udev/rules.d/z99dpfp_devices.rules com o seguinte conteúdo:

# udev rules file for UAREU 4000 devices
#
ACTION!="add", GOTO="biometric_end"
KERNEL=="dpfp[0-9]", MODE="0660", GROUP="plugdev"
LABEL="biometric_end"

Vejam que deixei definido para o grupo plugdev, que é o mesmo grupo que pode ler automaticamente dispositivos USB como pendrive. Logo deve abarcar a maioria dos usuários. Caso precise setar para algum grupo específico mudem. Ou então deixem a permissão 0666, que qualquer usuário poderá usar o device.

Abraços !

Amadeu Jr :: http://twiki.dcc.ufba.br/~AmadeuJunior

[15] Comentário enviado por geraldoms em 20/09/2007 - 11:07h

Opa, achei o artigo muito bom, mas esta dando uns erros quando utilizo o Script para download e extração do firmware e não saco muito de script, se alguem ai puder me dar uma força.. hehe... estou usando o kernel versão: 2.6.17-10 e o SO ubuntu

Esta dando este erro:

Download complete.
Extracting drdrv224-85.exe...
sh: cabextract: not found
Extract done
ERROR: Unable to find dpD00701.dll_XP.C9795C90_5A7C_44A3_8DBA_7E867BAFE6D0
Maybe this is an unsupported driver distribution?

[16] Comentário enviado por geraldoms em 21/09/2007 - 09:18h

O Artigo é muito bom valeu CABELO!!! Funcionou blz
Mas gostaria de saber se tem um sofware livre que possa me disponibilizar para que possa pegar a imagem da impressão digital e transforma-lá em número (identificação do usuário)

Se alguém puder me dar uma força...agradeço!!
Vlw

[17] Comentário enviado por alenquer em 27/09/2007 - 16:23h

Amigo, não consegui instalar no ubuntu 7.04. Na hora de compilar o driver, veja o que ocorre:
root@linux-servidor:/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2# make
make -C /lib/modules/`uname -r`/build M=`pwd`
make[1]: Entrando no diretório `/usr/src/linux-headers-2.6.20-15-generic'
CC [M] /home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.o
/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.c: In function ‘dpfp_set_mode_async’:
/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.c:222: warning: passing argument 7 of ‘usb_fill_control_urb’ from incompatible pointer type
/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.c: In function ‘dpfp_init_device’:
/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.c:469: error: ‘SLAB_ATOMIC’ undeclared (first use in this function)
/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.c:469: error: (Each undeclared identifier is reported only once
/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.c:469: error: for each function it appears in.)
/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.c:473: warning: passing argument 6 of ‘usb_fill_int_urb’ from incompatible pointer type
make[2]: ** [/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2/dpfp.o] Erro 1
make[1]: ** [_module_/home/alenquer/downloads/fingerprint/dpfp-driver-0.1.2] Erro 2
make[1]: Saindo do diretório `/usr/src/linux-headers-2.6.20-15-generic'
make: ** [module] Erro 2

[18] Comentário enviado por gmurilo em 13/11/2007 - 11:32h

Prezado alenquer o problema está em uma codificação global do driver, mas pode ser resolvida substituindo a instrução SLAB_ATOMIC por GFP_ATOMIC, no fonte do driver dpfp.c ou também você pode mudar na compilação do seu kernel a opção de General Setup -> SLAB allocator -> de SLUB para SLAB (o que eu não recomendo) e recompilar seu kernel

[19] Comentário enviado por evertjs em 04/02/2008 - 00:18h

olá por favor envie pra mim o firmware do microsoft fingerprint, sou usuário do openSUSE 10.2 e o comando ../dpfp-firmware-cutter -d uru4000 --from-web não funciona no meu terminal mesmo logado como root, há alguma depêndecia de algum pacote ou biblioteca, pois para compilar meu kernel foi preciso eu instalar os pacotes GCC, meu e-mail é sonda_de_radar@hotmail.com

[20] Comentário enviado por nevorah em 03/03/2008 - 05:14h

Evertjs

Libera a leitura e escrita em todas as portas usbs na pasta /dev

Aqui funcionou...

[21] Comentário enviado por nevorah em 09/04/2008 - 02:47h

make -C /lib/modules/`uname -r`/build M=`pwd`
make[1]: Entrando no diretório `/usr/src/linux-headers-2.6.22-14-generic'
CC [M] /root/dpfp-driver-0.1.2/dpfp.o
/root/dpfp-driver-0.1.2/dpfp.c: In function ‘dpfp_set_mode_async’:
/root/dpfp-driver-0.1.2/dpfp.c:222: warning: passing argument 7 of ‘usb_fill_control_urb’ from incompatible pointer type
/root/dpfp-driver-0.1.2/dpfp.c: In function ‘dpfp_init_device’:
/root/dpfp-driver-0.1.2/dpfp.c:469: error: ‘SLAB_ATOMIC’ undeclared (first use in this function)
/root/dpfp-driver-0.1.2/dpfp.c:469: error: (Each undeclared identifier is reported only once
/root/dpfp-driver-0.1.2/dpfp.c:469: error: for each function it appears in.)
/root/dpfp-driver-0.1.2/dpfp.c:473: warning: passing argument 6 of ‘usb_fill_int_urb’ from incompatible pointer type
make[2]: ** [/root/dpfp-driver-0.1.2/dpfp.o] Erro 1
make[1]: ** [_module_/root/dpfp-driver-0.1.2] Erro 2
make[1]: Saindo do diretório `/usr/src/linux-headers-2.6.22-14-generic'
make: ** [module] Erro 2

mesmo mundando SLAB_ATOMIC por GFP_ATOMIC ou melhor nem mudando pois ja estava como GFP... n~ao deu certo:(

[22] Comentário enviado por Kalunga em 21/05/2008 - 00:23h

Esse artigo me ajudou pra caralho, to desenvolvendo um sistema em linux mas que vai usar leitor biométrico, casou os dois.
Alguém sabe se o cabelo postou o artigo sobre os algoritmos de identificação ? Queria dar uma olhada, do tanto que cresceu sobre o assunto seria uma boa a gente criar uma biblioteca padrão :D

[23] Comentário enviado por marioplim em 25/05/2008 - 01:58h

tenho o mesmo problema que o geralms com o linux Kurumin, Red Hat e agora com o Ubuntu:
Esta dando este erro:

Download complete.
Extracting drdrv224-85.exe...
sh: cabextract: not found
Extract done
ERROR: Unable to find dpD00701.dll_XP.C9795C90_5A7C_44A3_8DBA_7E867BAFE6D0
Maybe this is an unsupported driver distribution?

não encontrei a resposta......Alguém poderia me ajudar?

Desculpe moçada, erro de principiante, foi só instalar o cabextract que deu certo:
apt-get install cabextract.
Agora estou com o mesmo erro do nevorah... com o SLA_ATOMIC

[24] Comentário enviado por globoleo em 11/08/2008 - 10:23h

cabelo, sequinte, trabalho numa empresa com 6 funcionarios, e presciso fazer o finger como ponto de horários, como procederia p/ tal feito, pode ser algo bem simples;

[25] Comentário enviado por jaisonn em 26/12/2008 - 17:33h

Alguém já conseguiu usar esse leitor no linux para, por exemplo... quando for ler a impressão digital de alguém, gerar um código da leitura ou associar essa impressão à um número e/ou código.. no meu caso preciso fazer para um sistema feito em PHP/MySQL de ponto de funcionários em uma empresa.. atualmente é feito por código de barras (cartão)... ainda não testei os drivers com as instruções, vou baixá-lo na empresa e colocar no servidor... estou apenas imaginando se alguém já fez tal coisa. Obrigado.

[26] Comentário enviado por rommelhc em 25/04/2009 - 13:50h

Cabelo, graaande post cara, me ajudou muito, consegui implantar um sistema de ponto eletronico, atráves do seu tópico, mas tive um probleminha, pequeno, a versão da lib, deve ser a mesma do driver..
instalei como você disse lib 0.1.1 e driver 0.1.2 e na hora de carregar o modulo.. ele não deixava, fui atrás do driver 0.1.1, instalei e ponto.. funcionou.
Não sei se é comum isso, mas se alguém sentir dificuldade, instale os dois na versão 0.1.1 :}

Valew ! excelente artigo.

[27] Comentário enviado por foguinho.peruca em 29/09/2009 - 11:02h

Cabelo,

Estou usando o ubuntu 9.04. Estou com dificuldade com o hotplug, pois não existe a pasta que você indicou (/usr/lib/hotplug/firmware). Como posso resolver isso?

Jeff

[28] Comentário enviado por foguinho.peruca em 29/09/2009 - 11:04h

Este script é uma atualização do script dpfp-firmware-cutter, funcionando corretamente agora.

#!/usr/bin/perl
# Tool to cut the Digital Persona Fingerprint Sensor firmware from a driver
# distribution.
# Version 0.1
#
# Copyright (C) 2005 Daniel Drake <dsd@gentoo.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#

use Digest::MD5;
use Getopt::Long;
use vars qw/ %opt /;

my $driver_path = $ARGV[0];
my $dll_path;
my $buffer;
my $md5;
my $cmd;
my $deletedir;
my $from_web = 0;
my $device_type;
my $driver_path;

GetOptions('from-web' => \$from_web, 'device=s' => \$device_type, 'path=s' => \$driver_path);

if (($driver_path eq '' && $from_web == 0) || $device_type eq '') {
print <<END;
dpfp-firmware-cutter: Extract the Digital Persona Fingerprint Reader firmware
from a driver distribution.

USAGE: dpfp-firmware-cutter -d <devicetype> -p <driverpath>
OR: dpfp-firmware-cutter -d <devicetype> --from-web

AVAILABLE DEVICE TYPES: uru4000, uru4000b
---> Microsoft devices require the uru4000b firmware. <---

For 'uru4000b' devices, driverpath can be either:
1. Path to the driver installer (DP_PM_10Eng.exe) available from microsoft
or 2. Path to where DP_PM_10Eng.exe has been extracted (e.g. by cabextract(1))
or 3. Path where driver CD has been mounted

For 'uru4000' devices, driverpath can be either:
1. Path to the driver installer (dpdrv224-85.exe) available from
digitalpersona.com
or 2. Path to where dpdrv224-85.exe has been extracted (e.g. by cabextract(1))

Instead of specifying a driver path, you can alternatively use the "--from-web"
option to download the firmware from the internet. The driver is downloaded
directly from the vendor, and since the URL may change, this mechanism is not
guaranteed to work.

This program extracts the firmware into a file which you
should place in your hotplug firmware directory (usually /lib/firmware). The
resultant filename is printed upon completion.
END
exit;
}

if ($device_type ne 'uru4000b' && $device_type ne 'uru4000') {
print "Unrecognised device type: $device_type\n";
print "Available types: uru4000b, uru4000\n";
exit;
}

if ($device_type eq 'uru4000b') {
$outfile = 'dpfp-uru4000b-001';
$seek = 0xE58C;
$readlen = 1268;
$reallen = 1904;
$dllmd5 = "2d590f24820b54487612e72163d349d3";

if ($from_web) {
#$cmd = 'wget "http://download.microsoft.com/download/3/9/e/39e93743-71c9-452f-b69c-90b227a57f1b/DP_PM_10Eng.exe"';
print "Downloading file...\n";
#$ret = `$cmd`;
print "Download complete.\n";
$driver_path = './DP_PM_10Eng.exe';
}
if (substr($driver_path, -15) eq "DP_PM_10Eng.exe") {
print "Extracting DP_PM_10Eng.exe...\n";
$cmd = 'cabextract -d __output__ "'. $driver_path . '"';
$ret = `$cmd`;
print "Extract done\n";
unlink($driver_path) if $from_web;
$driver_path = "./__output__";
$deletedir = 1;
}

if (-e $driver_path . "/dpD0Bx01.dll") {
$dll_path = $driver_path . "/dpD0Bx01.dll";
} elsif (-e $driver_path . "/Driver/dpD0Bx01.dll") {
$dll_path = $driver_path . "/Driver/dpD0Bx01.dll";
} else {
print "ERROR: Unable to find dpD0Bx01.dll\n";
print "Maybe this is an unsupported driver distribution?\n";
exit;
}
}

if ($device_type eq 'uru4000') {
$outfile = 'dpfp-uru4000-002';
$dllmd5 = "79fd7b411fe3e09f85e9eaaa2fcb4de2";
$seek = 0xFAAC;
$readlen = 1210;
$reallen = 1536;
$encryption_byte_offset = 0x3f7;

if ($from_web) {
$cmd = 'wget "http://www.digitalpersona.com/downloads/support-downloads/dpdrv224-85.exe"';
# $cmd = 'wget "http://www.digitalpersona.com/support/downloads/supportdownloads/dpdrv224-85.exe"';
print "Downloading file...\n";
$ret = `$cmd`;
print "Download complete.\n";
$driver_path = './dpdrv224-85.exe';
}

if (substr($driver_path, -15) eq "dpdrv224-85.exe") {
print "Extracting drdrv224-85.exe...\n";
$cmd = 'cabextract -d __output__ "'. $driver_path . '"';
$ret = `$cmd`;
print "Extract done\n";
unlink($driver_path) if $from_web;
$driver_path = "./__output__";
$deletedir = 1;
}

if (-e $driver_path . "/dpD00701.dll_XP.C9795C90_5A7C_44A3_8DBA_7E867BAFE6D0") {
$dll_path = $driver_path . "/dpD00701.dll_XP.C9795C90_5A7C_44A3_8DBA_7E867BAFE6D0";
} else {
print "ERROR: Unable to find dpD00701.dll_XP.C9795C90_5A7C_44A3_8DBA_7E867BAFE6D0\n";
print "Maybe this is an unsupported driver distribution?\n";
exit;
}
}

print "Found firmware container at $dll_path \n";
open(DLL, $dll_path) or die "Can't open !!";

open(OUT, '>'.$outfile) or die "Can't open outfile: $outfile";
binmode(DLL);

# Check md5sum
$md5 = Digest::MD5->new->addfile(*DLL)->hexdigest;
if ($md5 != $dllmd5) {
print "ERROR: Unrecognised md5sum.";
print "This probably means that you are using an unsupported driver version.\n";
exit;
}

# Grab the firmware
seek(DLL, $seek, 0);
$ret = read(DLL, $buffer, $readlen);
if ($ret != $readlen) {
print "File I/O error, could not read all $readlen bytes\n";
exit;
}

if ($encryption_byte_offset != 0) {
print "Disabling encryption bit\n";
$cur = substr($buffer, $encryption_byte_offset, 1);
$val = ord($cur);
$val = $val & 0xEF;
substr($buffer, $encryption_byte_offset, 1) = chr($val);
}

print OUT $buffer;

# Pad to required bytes
for ($i = 0; $i < ($reallen - $readlen); $i++) {
print OUT "{COMENTARIO}";
}

close OUT;
close DLL;


if ($deletedir) {
$cmd = 'rm -rf __output__';
$ret = `$cmd`;
}

print "\nFirmware written to ./$outfile\n";
print "You should place this file in your hotplug firmware directory\n";
print "(usually /lib/firmware)\n";

[29] Comentário enviado por alhaj em 07/09/2012 - 11:46h

Parabéns pelo artigo.
Estou tentando desenvolver um sistema de leiturade digitais através de Linux, PHP e do UareU 400B.
Gostaria de saber se há uma variavel em que as digitais são guardadas para posteriormente serem comparadas com as que ja estão inseridas no BD. E assim fazer a autenticação da digital.


Att,
Allan Pereira


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts