Estes fontes se referem a dois tutoriais, o de criptografia com QCA e o de bloqueio do sistema após inatividade do mouse e do teclado. main.cpp /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #include #include "fPrincipal.h"//Para a janela principal do aplicativo #include //Para leitura do arquivo de configuração #include #include //Para acesso ao banco de dados #include "fLogin.h"//Para a tela de login #include //QCA #include //Para o locale int main(int argc, char *argv[]) { QCA::Initializer init;//Todo aplicativo que usa QCA de ter este código aqui no main.cpp QTextCodec::setCodecForTr(QTextCodec:: codecForName ( "UTF-8"));//Para locale QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); QApplication app(argc, argv); QString caminho=QCoreApplication::applicationDirPath();//Acha o caminho do binario, no mesmo diretório esta o arquivo config.txt caminho.append("/config.txt"); QString database,host,databasename,linha; QSettings settings(caminho,QSettings::IniFormat);//Ler os parâmetros de conexão ao banco no config.txt database=settings.value("banco/database").toString(); host=settings.value("banco/hostname").toString(); databasename=settings.value("banco/databasename").toString(); if (database=="" || host=="" || databasename=="") { QMessageBox::information(0,"Iniciando o Sistema","Não foi possivel ler o arquivo de configuração"); return 1; } else { QSqlDatabase db = QSqlDatabase::addDatabase(database);//Instacia a conexão com os parametros. db.setHostName(host); db.setDatabaseName(databasename); db.setUserName("rodolfo");//Coloque aqui seu usuario no banco db.setPassword("%Zh*#u");//Coloque aqui sua senha bool ok = db.open(); if (ok) { fPrincipal* fTela_Prin = new fPrincipal(caminho);//Cria o objeto da classe fPrincipal e mostra na tela fTela_Prin->show(); bool testa_Login=false;//O endereço desta variavel é passado a tela de login para saber se o login foi correto(usuarios e senhas ok) int nivel_Acesso;//Para guardar o nivel de acesso do usuário no aplicativo fLogin* fAcesso=new fLogin(0,&testa_Login,&nivel_Acesso); fAcesso->exec(); if (testa_Login==false)//Se o login falhou, destroi os objetos criados e sai do sistema. { delete fAcesso; delete fTela_Prin; return 1; } else//Se o login foi correto, destroi a tela de login. { fTela_Prin->pega_Nivel(nivel_Acesso);//Passa a janela principal o nive de acessso, que por sua vez passara os demais cadastros. delete fAcesso; } } else { QMessageBox::information(0,"Iniciando o Sistema","Não foi possivel conectar-se ao banco de dados!"); return 1; } } return app.exec(); } fLogin.h /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * * * * * 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. * ***************************************************************************/ #ifndef FDESBLOQUEIA_LOGIN_H #define FDESBLOQUEIA_LOGIN_H #include "ui_fLogin_Parent.h" class QSqlQuery; class fLogin:public QDialog,private Ui::fLogin_Parent { Q_OBJECT public: fLogin(QObject *parent = 0,bool* login=false,int* nivel=0); ~fLogin(); private: QSqlQuery* query_Login; bool* login_2; int* niv_Acesso; void keyPressEvent(QKeyEvent* e); private slots: void botao_OK_Click(); protected: class pesq_Senha* testa_Senha; }; #endif fLogin.cpp /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * * * * 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. * ***************************************************************************/ #include "fLogin.h" #include #include #include //Para tabular com enter. #include #include "pesq_Senha.h" fLogin::fLogin(QObject *parent,bool* login,int* nivel) { setupUi(this); connect(botao_OK,SIGNAL(clicked()),this,SLOT(botao_OK_Click())); this->setFixedSize (this->size());//Para que não se possa redimensionar a janela QRect rect = QApplication::desktop()->availableGeometry(this);//para centralizar na tela. this->move(rect.center() - this->rect().center()); edit_Usuario->setFocus(); query_Login=new QSqlQuery; login_2=login; niv_Acesso=nivel; testa_Senha=new pesq_Senha;//Para as funções da QCA } fLogin::~fLogin() { delete query_Login; delete testa_Senha; } void fLogin:: botao_OK_Click() { QString senha=edit_Senha->text(); QByteArray senha_Hash; //Abre a tabela de usuários, o parâmetro da consulta é o nome digitado, por isso na tabela a um índice que não permite usuários duplicados. query_Login->prepare(" select " " a.id_usuarios," " a.nome," " a.senha," " a.nivel," " a.tipo_senha, " " b.codigo," " b.chave, " " b.vetor, " " b.tipo_hash " " from " " usuarios a," " codigos b " " where " " a.id_usuarios=b.id_codigos and " " a.nome=:nom"); query_Login->bindValue(":nom",edit_Usuario->text()); query_Login->exec(); query_Login->next(); if (query_Login->size()>0) { if (query_Login->value(4).toInt()==0)//Testa se a senha é hash ou criptografada. { senha=senha.append(query_Login->value(5).toString());//Recupera a string aleatória gerada no momento da gravação da senha, e concatena com a senha digitada. switch (query_Login->value(8).toInt())//Testa se o padrão do hash e md5 ou sha1. { case 0: { senha_Hash=testa_Senha->gera_hash_Senha(senha,0);//Gera o hash da senha digitada break; } case 1: { senha_Hash=testa_Senha->gera_hash_Senha(senha,1); break; } } if (senha_Hash==query_Login->value(2).toByteArray())//Compara o hash da senha digitada com a senha gravada { *login_2=true; *niv_Acesso=query_Login->value(3).toInt(); this->close(); } else//Se a senha for incorreta, nega o acesso. { edit_Senha->clear(); edit_Senha->setFocus(); QMessageBox::information(0,"Acesso ao Sistema","Senha incorreta!"); } } else if (query_Login->value(4).toInt()==1)//Senha criptografada { if (senha==testa_Senha->descriptografa(query_Login->value(2).toByteArray(),query_Login->value(6).toByteArray(),query_Login->value(7).toByteArray()))//Descriptografa a senha gravada e compara com a digitada.A rotina usa como parâmetros a senha gravada, a chave o vetor gerados e gravados no banco. { *login_2=true;//Acerta os valores de vivel de acesso e login correto. *niv_Acesso=query_Login->value(3).toInt(); this->close(); } else { edit_Senha->clear(); edit_Senha->setFocus(); QMessageBox::information(0,"Acesso ao Sistema","Senha incorreta!"); } } else QMessageBox::information(0,"Acesso ao Sistema","Tipo de senha desconhecido!"); } else { edit_Usuario->setFocus(); QMessageBox::information(0,"Acesso ao Sistema","Usúario não existe no banco de dados!"); } } void fLogin::keyPressEvent(QKeyEvent* e) { if ( e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return )//Tabula com enter. QApplication::focusWidget()->nextInFocusChain()->setFocus(); } fPrincipal.h /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #ifndef FPRINCIPAL_H #define FPRINCIPAL_H #include "ui_fPrincipal_Parent.h" class fPrincipal:public QMainWindow,private Ui::fPrincipal_Parent { Q_OBJECT public: fPrincipal(QString caminho=""); ~fPrincipal(); void pega_Nivel(int pegNivel);//Declara a função que pega o nivel de acesso. protected: class trava_Sistema* trava_Sis; class fCadClientes* fCadCli; class fCadUsuarios* fCadUs;//Declara o cadastro de usuários. private slots: void on_actionClientes_triggered(); void on_action_Usuarios_triggered();//Slot que ira instanciar o objeto da classe fCadUsuarios. private: void mouseMoveEvent(QMouseEvent * event); void keyPressEvent(QKeyEvent* e); int nivel; }; #endif fPrincipal.cpp /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #include "fPrincipal.h" #include #include "trava_Sistema.h" #include "fCadClientes.h" #include "fCadUsuarios.h" fPrincipal::fPrincipal(QString caminho) { setupUi(this); this->setAttribute(Qt::WA_DeleteOnClose,true);//para auto destruir o objeto e liberar a memoria. QRect rect = QApplication::desktop()->availableGeometry(this);//para centralizar na tela. this->move(rect.center() - this->rect().center()); this->setFixedSize (this->size());//Para que não se possa redimensionar a janela trava_Sis=new trava_Sistema(this,caminho);//Instancia um objeto da classe trava_Sistema, que tem os métodos para bloquear o sistema centralwidget->setMouseTracking(true);//Você deve colocar esta linha, pois no ui_fPrincipal_Parent.h, ele define centralwidget = new QWidget(fPrincipal_Parent); centralwidget->setObjectName(QString::fromUtf8("centralwidget")); Então quem responde por capturar corretamente o evento do mouse é centralwidget. } fPrincipal::~fPrincipal() { delete trava_Sis; } void fPrincipal::keyPressEvent(QKeyEvent* e) { trava_Sis->reinicia_Timer();//Ao usar o teclado, zera o timer } void fPrincipal::mouseMoveEvent ( QMouseEvent * event ) { trava_Sis->reinicia_Timer();//Ao mover o mouse, zera o timer } void fPrincipal::on_actionClientes_triggered() { fCadCli=new fCadClientes(this,trava_Sis);//Passa o objeto trava_Sis como parâmetro para o objeto instanciado, no caso um cadastro. fCadCli->show(); } void fPrincipal::on_action_Usuarios_triggered() { fCadUs=new fCadUsuarios(this,nivel);//Instancia o cadastro de usuários. fCadUs->show(); } void fPrincipal::pega_Nivel(int pegNivel) { nivel=pegNivel;//Acerta a variavel nivel com o valor de pegNivel que vem do main.cpp } fCadUsuarios.h /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #ifndef FCADUSUARIOS_H #define FCADUSUARIOS_H #include "ui_fCadUsuarios_Parent.h" class QSqlQuery; class QSqlQueryModel; class QSqlDatabase; class QSignalMapper; class fCadUsuarios:public QWidget,private Ui::fCadUsuarios_Parent { Q_OBJECT public: fCadUsuarios(QWidget* parent=0,int nivel=0); ~fCadUsuarios(); private: QButtonGroup* group_Tipo_Senha; QButtonGroup* group_Tipo_Hash; QSqlQuery* query_Usuarios;//Nossa query de trabalho. QSqlQueryModel* model_Usuarios;//Um grid para mostrar os dados int gera_Aleatorio(int min,int max,int semente);//Função C++ para gerar numeros aleatorios. QSignalMapper* signalMapper; private slots: void tipo_Senha(); void grava_na_Tabela(int tipo); void exclui_na_Tabela(); void limpa_Tela(); protected: class pesq_Senha* testa_Senha;//Declara um objeto da classe abstrata pesq_Senha que tem as funções da QCA. }; #endif fCadUsuarios.cpp /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #include "fCadUsuarios.h" #include #include #include #include #include #include #include #include "pesq_Senha.h" #include fCadUsuarios::fCadUsuarios(QWidget* parent,int nivel) { setupUi(this); this->setAttribute(Qt::WA_DeleteOnClose,true);//para auto destruir o objeto e liberar a memoria. QRect rect = QApplication::desktop()->availableGeometry(this);//para centralizar na tela. this->move(rect.center() - this->rect().center()); this->setFixedSize (this->size());//Para que não se possa redimensionar a janela if (nivel>1)//Bloqueia o acesso aos botões conforme o nivel do usuário. { botao_Incluir->setEnabled(false); botao_Alterar->setEnabled(false); botao_Excluir->setEnabled(false); } testa_Senha=new pesq_Senha;//Instancia um objeto da classe pesq_Senha. group_Tipo_Senha=new QButtonGroup(this);//cria o QbuttonGroup group_Tipo_Senha->setExclusive(true);//clicou em um, desmarcou o outro group_Tipo_Senha->addButton(botao_hash);//adiciona o RadioButton ao QbuttonGroup group_Tipo_Senha->setId(botao_hash,0);// indice do RadioButton dentro do QbuttonGroup group_Tipo_Senha->addButton(botao_Cripto); group_Tipo_Senha->setId(botao_Cripto,1); connect(group_Tipo_Senha,SIGNAL(buttonClicked(int)),this,SLOT(tipo_Senha())); group_Tipo_Hash=new QButtonGroup(this); group_Tipo_Hash->setExclusive(true);//clicou em um, desmarcou o outro group_Tipo_Hash->addButton(botao_sha1);//adiciona o RadioButton ao QbuttonGroup group_Tipo_Hash->setId(botao_sha1,0);// indice do RadioButton dentro do QbuttonGroup group_Tipo_Hash->addButton(botao_md5); group_Tipo_Hash->setId(botao_md5,1); signalMapper = new QSignalMapper(this);//Para que os botões incluir e alterar acessem o mesmo slot e se saiba qual botão esta acessando. signalMapper->setMapping(botao_Incluir, 1); signalMapper->setMapping(botao_Alterar, 2); connect(botao_Incluir,SIGNAL(clicked()),signalMapper,SLOT (map())); connect(botao_Alterar,SIGNAL(clicked()),signalMapper,SLOT (map())); connect(signalMapper, SIGNAL(mapped(int )),this,SLOT(grava_na_Tabela(int ))); connect(botao_Excluir,SIGNAL(clicked()),this,SLOT(exclui_na_Tabela())); connect(botao_limpar_Tela,SIGNAL(clicked()),this,SLOT(limpa_Tela())); query_Usuarios=new QSqlQuery; model_Usuarios=new QSqlQueryModel(this); model_Usuarios->setQuery("select * from usuarios order by id_usuarios"); model_Usuarios->setHeaderData(0, Qt::Horizontal, tr("Código")); model_Usuarios->setHeaderData(1, Qt::Horizontal, tr("Nome")); model_Usuarios->setHeaderData(2, Qt::Horizontal, tr("Senha")); model_Usuarios->setHeaderData(3, Qt::Horizontal, tr("Nivel")); tableView_Usuarios->setModel(model_Usuarios);//Conecta o model ao tableView para visualizarmos a tabela. tableView_Usuarios->setColumnWidth(0,40); tableView_Usuarios->setColumnWidth(1,80); tableView_Usuarios->setColumnWidth(2,270); tableView_Usuarios->setColumnWidth(3,40); tableView_Usuarios->show(); edit_Codigo->setFocus(); } fCadUsuarios::~fCadUsuarios() { delete group_Tipo_Senha; delete testa_Senha; delete group_Tipo_Hash; delete query_Usuarios; delete model_Usuarios; delete signalMapper; } void fCadUsuarios::tipo_Senha() { switch (group_Tipo_Senha->checkedId())//Bloqueia alternadamente as opções de hash e criptografada. { case 0: { group_hash->setEnabled(true); break; } case 1: { group_hash->setEnabled(false); break; } } } void fCadUsuarios::grava_na_Tabela(int tipo) { QString senha; senha=edit_Senha->text(); QByteArray senha_Cripto; QString complemento="0"; QByteArray* chave_Usuario=new QByteArray; QByteArray* vetor_Usuario=new QByteArray; switch (group_Tipo_Senha->checkedId())//Testa se a senha sera hash ou criptografada. { case 0: { int j,k; //gera uma sequencia de 10 numeros aleatorios, de 65 a 90, seus characters ASCII correspondestes são concatenados em uma string que por sua vez é concatenada à senha digitada.Isto serve para evitar senhas iguais. for (j=1;j<=10;j++) { k=gera_Aleatorio(65,90,j); complemento[j]=QChar(k); } QMessageBox::information(0,"Sistema de Criptografia",complemento); senha=senha.append(complemento); switch (group_Tipo_Hash->checkedId())//Testa se o hash é sha1 ou md5. { case 0: { senha_Cripto=testa_Senha->gera_hash_Senha(senha,0);//Gera o hash conforme o tipo. break; } case 1: { senha_Cripto=testa_Senha->gera_hash_Senha(senha,1); break; } } break; } case 1: { senha_Cripto=testa_Senha->criptografa(senha,chave_Usuario,vetor_Usuario);//Senha criptografada. break; } } bool gravou=false; QString erro; //Abaixo, o código que ira gravar a senha na tabela. O objeto QSqlQuery ira chamar uma procedure no banco(PostgreSql) que ira gravar nas duas tabelas, usuários e códigos, na tabela usuários sera gravada o nome, a senha, o tipo de senha, se hash ou criptografada, o nível de acesso dentro do sistema, na tabela códigos sera gravada o complemento e a chave e vetor no caso de senha criptografada. São duas procedures, uma para inserir e outra para alterar. if (tipo==1)//Testa se esta incluindo ou alterando. query_Usuarios->prepare("select insere_Usuario(:cod,:nom,:sen,:niv,:tp,:comp,:chv,:vet,:hash)"); else if (tipo==2) query_Usuarios->prepare("select altera_Usuario(:cod,:nom,:sen,:niv,:tp,:comp,:chv,:vet,:hash)"); query_Usuarios->bindValue(":cod", edit_Codigo->text());//Parâmetros. query_Usuarios->bindValue(":nom", edit_Nome->text()); query_Usuarios->bindValue(":sen",senha_Cripto); query_Usuarios->bindValue(":niv", combo_Nivel->currentIndex()+1); switch (group_Tipo_Senha->checkedId()) { case 0: { query_Usuarios->bindValue(":tp", 0); query_Usuarios->bindValue(":chv","0"); query_Usuarios->bindValue(":vet","0"); switch (group_Tipo_Hash->checkedId()) { case 0: { query_Usuarios->bindValue(":hash",0); break; } case 1: { query_Usuarios->bindValue(":hash",1); break; } } break; } case 1: { query_Usuarios->bindValue(":tp",1); query_Usuarios->bindValue(":chv",*chave_Usuario); query_Usuarios->bindValue(":vet",*vetor_Usuario); query_Usuarios->bindValue(":hash",0); break; } } query_Usuarios->bindValue(":comp",complemento); gravou=query_Usuarios->exec(); if (! gravou) { erro=query_Usuarios->lastError().text(); QMessageBox::critical(0,"Sistema de Criptografia",erro,QMessageBox::Cancel); } delete chave_Usuario; delete vetor_Usuario; /*bool gravou,gravou2=false; QSqlDatabase::database().transaction(); QString erro; //Aqui é auto evidente o que o codigo faz, grava na tabela. query_Usuarios->prepare(" insert into usuarios (id_usuarios,nome,senha,nivel,tipo_senha) values (:cod,:nom,:sen,:niv,:tp) "); query_Usuarios->bindValue(":cod", edit_Codigo->text());//Parâmetros. query_Usuarios->bindValue(":nom", edit_Nome->text()); query_Usuarios->bindValue(":sen",senha); query_Usuarios->bindValue(":niv", 1); switch (group_Tipo_Senha->checkedId()) { case 0: { query_Usuarios->bindValue(":tp", 0); break; } case 1: { query_Usuarios->bindValue(":tp", 1); break; } } gravou=query_Usuarios->exec(); if (! gravou) { erro=query_Usuarios->lastError().text(); erro.append(" "); } QSqlQuery* query_Complemento=new QSqlQuery; query_Complemento->prepare(" insert into codigos (id_codigos,codigo,chave) values (:id,:cod,:chv) "); query_Complemento->bindValue(":id", edit_Codigo->text()); query_Complemento->bindValue(":cod",complemento); switch (group_Tipo_Senha->checkedId()) { case 0: { query_Usuarios->bindValue(":chv","0"); break; } case 1: { query_Usuarios->bindValue(":chv",*chave_Usuario); break; } } gravou2=query_Complemento->exec(); if (gravou && gravou2) QSqlDatabase::database().commit(); else { QSqlDatabase::database().rollback(); erro.append(query_Complemento->lastError().text()); QMessageBox::critical(0,"Sistema de Criptografia",erro,QMessageBox::Cancel); }*/ model_Usuarios->setQuery("select * from usuarios order by id_usuarios");//Atualiza o grid tableView_Usuarios->show(); limpa_Tela(); } void fCadUsuarios::exclui_na_Tabela() { query_Usuarios->prepare("delete from usuarios where id_usuarios=:cod"); query_Usuarios->bindValue(":cod", edit_Codigo->text()); if (!query_Usuarios->exec()) QMessageBox::critical(0,"Sistema de Criptografia",query_Usuarios->lastError().text(),QMessageBox::Cancel); model_Usuarios->setQuery("select * from usuarios order by id_usuarios"); tableView_Usuarios->show(); limpa_Tela(); } void fCadUsuarios::limpa_Tela() { //Limpa os campos de edição. edit_Codigo->clear(); edit_Nome->clear(); edit_Senha->clear(); edit_Codigo->setFocus(); } int fCadUsuarios::gera_Aleatorio(int min,int max,int semente) { int r; if(!semente) { srand((unsigned)semente); } r=min+rand()%(max-min+1); return r; } pesq_Senha.h /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #ifndef PESQ_SENHA_H #define PESQ_SENHA_H class QString; class QByteArray; class pesq_Senha { public: pesq_Senha(); ~pesq_Senha(); QByteArray gera_hash_Senha(QString senha,int tipo_Hash); QString descriptografa(QByteArray senha,QByteArray chave_Usuario,QByteArray vetor_Usuario); QByteArray criptografa(QString senha,QByteArray* chave_Usuario,QByteArray* vetor_Usuario); }; #endif pesq_Senha.cpp /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #include "pesq_Senha.h" #include #include #include pesq_Senha::pesq_Senha() { } pesq_Senha::~pesq_Senha() { } QByteArray pesq_Senha::gera_hash_Senha(QString senha,int tipo_hash) { QByteArray result=""; QCA::SecureArray arg = senha.toAscii(); int meio=arg.size()/2; switch (tipo_hash) { case 0: { if( !QCA::isSupported("sha1") ) QMessageBox::information(0,"Sistema de Criptografia","SHA1 não suportado"); else { QCA::Hash senha_hash("sha1"); senha_hash.update(senha.toAscii()); result=senha_hash.final().toByteArray(); } break; } case 1: { if( !QCA::isSupported("md5") ) QMessageBox::information(0,"Sistema de Criptografia","MD5 não suportado"); else { QCA::SecureArray part1(arg.toByteArray().left(meio)); QCA::SecureArray part2(arg.toByteArray().mid(meio)); QCA::Hash hashObject("md5"); hashObject.update(part1); hashObject.update(part2); QCA::SecureArray resultArray = hashObject.final(); result = resultArray.toByteArray(); break; } } } return result; } QString pesq_Senha::descriptografa(QByteArray senha,QByteArray chave_Usuario,QByteArray vetor_Usuario) { QString result=""; if(!QCA::isSupported("aes128-cbc-pkcs7")) QMessageBox::information(0,"Sistema de Criptografia","Método AES128-CBC não suportado"); else { QByteArray chave=chave_Usuario; QCA::SymmetricKey key(chave); QByteArray vetor=vetor_Usuario; QCA::InitializationVector iv(vetor); QCA::Cipher cipher(QString("aes128"),QCA::Cipher::CBC,QCA::Cipher::DefaultPadding,QCA::Encode,key,iv); cipher.setup( QCA::Decode, key, iv ); QCA::SecureArray cipherText = senha; QCA::SecureArray plainText = cipher.update(cipherText); if (!cipher.ok()) { QMessageBox::information(0,"Sistema de Criptografia","Update falhou"); } plainText = cipher.final(); if (!cipher.ok()) { QMessageBox::information(0,"Sistema de Criptografia","Final falhou"); } result=plainText.data(); } return result; } QByteArray pesq_Senha::criptografa(QString senha,QByteArray* chave_Usuario,QByteArray* vetor_Usuario) { QByteArray result; QCA::SymmetricKey key(16); *chave_Usuario=key.toByteArray(); QCA::InitializationVector iv(16); *vetor_Usuario=iv.toByteArray(); QCA::SecureArray arg=senha.toAscii(); QCA::Cipher cipher(QString("aes128"),QCA::Cipher::CBC,QCA::Cipher::DefaultPadding,QCA::Encode,key,iv); QCA::SecureArray u = cipher.update(arg); if (!cipher.ok()) { QMessageBox::information(0,"Sistema de Criptografia","Update falhou"); result=""; } else { QCA::SecureArray f = cipher.final(); if (!cipher.ok()) { QMessageBox::information(0,"Sistema de Criptografia","Final falhou"); result=""; } else { QCA::SecureArray cipherText = u.append(f); result=cipherText.toByteArray(); } } return result; } fCadClientes.h /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #ifndef FCADCLIENTES_H #define FCADCLIENTES_H #include "ui_fCadClientes_Parent.h" class trava_Sistema; class fCadClientes:public QWidget,private Ui::fCadClientes_Parent { Q_OBJECT public: fCadClientes(QWidget* parent=0,trava_Sistema* tr_Sis=0); ~fCadClientes(); protected: class trava_Sistema* trava_Sis; private: void mouseMoveEvent(QMouseEvent * event); void keyPressEvent(QKeyEvent* e); }; #endif fCadClientes.cpp /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #include "fCadClientes.h" #include #include "trava_Sistema.h" fCadClientes::fCadClientes(QWidget* parent,trava_Sistema* tr_Sis) { setupUi(this); this->setAttribute(Qt::WA_DeleteOnClose,true);//para auto destruir o objeto e liberar a memoria. QRect rect = QApplication::desktop()->availableGeometry(this);//para centralizar na tela. this->move(rect.center() - this->rect().center()); this->setFixedSize (this->size());//Para que não se possa redimensionar a janela trava_Sis=tr_Sis;//Passa o endereço do objeto da classe trava_Sistema instanciado na tela principal para a variavel tr_Sis. } fCadClientes::~fCadClientes() { } void fCadClientes::mouseMoveEvent(QMouseEvent * event) { trava_Sis->reinicia_Timer();//reseta o objeto QTimer e o inicia de novo, assim que o mouse é movimentado. } void fCadClientes::keyPressEvent(QKeyEvent* e) { trava_Sis->reinicia_Timer();//reseta o objeto QTimer e o inicia de novo, assim que o teclado é usado. } fDesbloqueia_Sistema.h /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #ifndef FDESBLOQUEIA_SISTEMA_H #define FDESBLOQUEIA_SISTEMA_H #include "ui_fLogin_Parent.h" class QSqlQuery; class fDesbloqueia_Sistema:public QDialog,private Ui::fLogin_Parent { Q_OBJECT public: fDesbloqueia_Sistema(QObject *parent=0,bool* login=0); ~fDesbloqueia_Sistema(); private: void closeEvent ( QCloseEvent * event ); bool senha_Correta; QSqlQuery* query_Login; void keyPressEvent(QKeyEvent* e); private slots: void botao_OK_Click(); protected: class pesq_Senha* testa_Senha; }; #endif fDesbloqueia_Sistema.cpp /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * rodolfo@Programador * * * * 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. * ***************************************************************************/ #include "fDesbloqueia_Sistema.h" #include #include #include #include #include "pesq_Senha.h" fDesbloqueia_Sistema::fDesbloqueia_Sistema(QObject *parent,bool* login) { setupUi(this); this->setAttribute(Qt::WA_DeleteOnClose,true); senha_Correta=false; connect(botao_OK,SIGNAL(clicked()),this,SLOT(botao_OK_Click())); this->setFixedSize (this->size());//Para que não se possa redimensionar a janela QRect rect = QApplication::desktop()->availableGeometry(this);//para centralizar na tela. this->move(rect.center() - this->rect().center()); edit_Usuario->setFocus(); query_Login=new QSqlQuery; testa_Senha=new pesq_Senha; } fDesbloqueia_Sistema::~fDesbloqueia_Sistema() { delete query_Login; delete testa_Senha; } void fDesbloqueia_Sistema:: botao_OK_Click() { QString senha=edit_Senha->text(); QByteArray senha_Hash; //Abre a tabela de usuários, o parâmetro da consulta é o nome digitado, por isso na tabela a um índice que não permite usuários duplicados. query_Login->prepare(" select " " a.id_usuarios," " a.nome," " a.senha," " a.nivel," " a.tipo_senha, " " b.codigo," " b.chave, " " b.vetor, " " b.tipo_hash " " from " " usuarios a," " codigos b " " where " " a.id_usuarios=b.id_codigos and " " a.nome=:nom"); query_Login->bindValue(":nom",edit_Usuario->text()); query_Login->exec(); query_Login->next(); if (query_Login->size()>0) { if (query_Login->value(4).toInt()==0)//Testa se a senha é hash ou criptografada. { //hash senha=senha.append(query_Login->value(5).toString());//Recupera a string aleatória gerada no momento da gravação da senha, e concatena com a senha digitada. switch (query_Login->value(8).toInt())//Testa se o padrão do hash e md5 ou sha1. { case 0: { senha_Hash=testa_Senha->gera_hash_Senha(senha,0);//Gera o hash da senha digitada break; } case 1: { senha_Hash=testa_Senha->gera_hash_Senha(senha,1); break; } } if (senha_Hash==query_Login->value(2).toByteArray())//Compara o hash da senha digitada com a senha gravada { senha_Correta=true; this->close(); } else { edit_Senha->clear(); edit_Senha->setFocus(); QMessageBox::information(0,"Acesso ao Sistema","Senha incorreta!"); } } else if (query_Login->value(4).toInt()==1)//Senha criptografada { if (senha==testa_Senha->descriptografa(query_Login->value(2).toByteArray(),query_Login->value(6).toByteArray(),query_Login->value(7).toByteArray()))//Descriptografa a senha gravada e compara com a digitada.A rotina usa como parâmetros a senha digitada, a chave o vetor gerados e gravados no banco. { senha_Correta=true; this->close(); } else { edit_Senha->clear(); edit_Senha->setFocus(); QMessageBox::information(0,"Acesso ao Sistema","Senha incorreta!"); } } else QMessageBox::information(0,"Acesso ao Sistema","Tipo de senha desconhecido!"); } else { edit_Usuario->setFocus(); QMessageBox::information(0,"Acesso ao Sistema","Usúario não existe no banco de dados!"); } } void fDesbloqueia_Sistema::keyPressEvent(QKeyEvent* e) { if ( e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return )//Tabula com enter. QApplication::focusWidget()->nextInFocusChain()->setFocus(); } void fDesbloqueia_Sistema::closeEvent( QCloseEvent * event ) { if (senha_Correta)//Não deixa fechar se a senha é incorreta. event->accept(); else event->ignore(); } trava_Sistema.h /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * * * * 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. * ***************************************************************************/ #ifndef TRAVA_SISTEMA_H #define TRAVA_SISTEMA_H #include #include "fDesbloqueia_Sistema.h" class QTimer; class trava_Sistema:public QObject { Q_OBJECT public: trava_Sistema(QWidget *parent = 0,QString caminho=""); ~trava_Sistema(); public slots: void reinicia_Timer(); private: QTimer* timer; int tempo; private slots: void chama_Login(); protected: class fDesbloqueia_Sistema* fDestrava_Sis; }; #endif trava_Sistema.cpp /*************************************************************************** * Copyright (C) 2009 by Rodolfo Ribeiro Machado * * * * * 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. * ***************************************************************************/ #include "trava_Sistema.h" #include #include "fDesbloqueia_Sistema.h" #include trava_Sistema::trava_Sistema(QWidget *parent,QString caminho) { QSettings settings(caminho,QSettings::IniFormat); tempo=settings.value("timer/tempo").toInt();//Lê no arquivo config.txt o valor de tempo para bloquear o sistema. timer=new QTimer; timer->start(tempo); connect(timer,SIGNAL(timeout()),this,SLOT(chama_Login())); } trava_Sistema::~trava_Sistema() { delete timer; } void trava_Sistema::reinicia_Timer() { timer->stop(); timer->start(tempo); } void trava_Sistema::chama_Login() { timer->stop();//Ao chamar a tela de login, para de correr o tempo. bool login=false; fDestrava_Sis=new fDesbloqueia_Sistema(this,&login);//Instancia e abre a tela de login. connect(fDestrava_Sis,SIGNAL(destroyed()),this,SLOT(reinicia_Timer()));//Quando a tela de login se fecha, o tempo começa a correr de novo. fDestrava_Sis->show(); } Script para gerar o banco: create language plpgsql; create table usuarios( id_usuarios int primary key, nome varchar(20) unique not null check (nome <> ''), senha bytea not null, nivel int not null check (nivel >= 1), tipo_senha integer not null check (tipo_senha >= 0 and tipo_senha<=1)); create table codigos( id_codigos int primary key, codigo varchar(100) not null check (codigo <> ''), chave bytea not null, vetor bytea not null, tipo_hash integer not null check (tipo_hash >= 0 and tipo_hash <=1)); alter table codigos add FOREIGN KEY (id_codigos) references usuarios(id_usuarios); CREATE OR REPLACE FUNCTION deleta_Complemento() RETURNS trigger AS $deleta_Complemento$ BEGIN delete from codigos where id_codigos=old.id_usuarios; return OLD; END; $deleta_Complemento$ LANGUAGE plpgsql; CREATE TRIGGER deleta_Complemento BEFORE DELETE ON usuarios FOR EACH ROW EXECUTE PROCEDURE deleta_Complemento(); CREATE OR REPLACE FUNCTION insere_Usuario(integer,varchar(20),bytea,integer,integer,varchar(100),bytea,bytea,integer) RETURNS void AS ' insert into usuarios (id_usuarios, nome, senha, nivel, tipo_senha) values ($1,$2,$3,$4,$5); insert into codigos (id_codigos, codigo, chave, vetor, tipo_hash) values ($1,$6,$7,$8,$9); ' LANGUAGE SQL; CREATE OR REPLACE FUNCTION altera_Usuario(integer,varchar(20),bytea,integer,integer,varchar(100),bytea,bytea,integer) RETURNS void AS ' update usuarios set nome=$2, senha=$3, nivel=$4, tipo_senha=$5 where id_usuarios=$1; update codigos set codigo=$6, chave=$7, vetor=$8, tipo_hash=$9 where id_codigos=$1; ' LANGUAGE SQL; arquivo config.txt: [banco] database = QPSQL hostname = localhost databasename = teste_senha [timer] tempo =100000