changed encryption method of SecStrings from Rijndael to ArcFour (much faster)
git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@49 b624d157-de02-0410-bad0-e51aec6abb33
This commit is contained in:
parent
68f1d12d74
commit
f89372b0c5
|
@ -201,6 +201,7 @@ CEntry entry;
|
|||
return false; }
|
||||
|
||||
bRet = entry.ReadEntryField(FieldType,FieldSize,(Q_UINT8*)pField);
|
||||
|
||||
if((FieldType == 0xFFFF) && (bRet == true)){
|
||||
entry.sID=tmp_id++;
|
||||
Entries << entry;
|
||||
|
@ -272,14 +273,14 @@ if(paKey == NULL) return false;
|
|||
KeyLen = strlen(paKey);
|
||||
|
||||
if(KeyLen == 0) {
|
||||
SecString::overwrite(paKey,Password.length() + 1);
|
||||
SecString::overwrite((unsigned char*)paKey,Password.length() + 1);
|
||||
delete [] paKey;
|
||||
return false; }
|
||||
|
||||
sha256_starts(&sha32);
|
||||
sha256_update(&sha32,(unsigned char*) paKey, KeyLen);
|
||||
sha256_finish(&sha32,MasterKey);
|
||||
SecString::overwrite(paKey,Password.length() + 1);
|
||||
SecString::overwrite((unsigned char*)paKey,Password.length() + 1);
|
||||
delete [] paKey;
|
||||
return true;
|
||||
}
|
||||
|
@ -530,7 +531,6 @@ switch(FieldType)
|
|||
memcpyFromLEnd32(&ImageID, (char*)pData);
|
||||
break;
|
||||
case 0x0004:
|
||||
//Title=(char*)pData;
|
||||
Title=QString::fromUtf8((char*)pData);
|
||||
break;
|
||||
case 0x0005:
|
||||
|
@ -723,8 +723,9 @@ for(int i = 0; i < Entries.size(); i++){
|
|||
FieldSize = Entries[i].Password.length() + 1; // Add terminating NULL character space
|
||||
memcpyToLEnd16(buffer+pos, &FieldType); pos += 2;
|
||||
memcpyToLEnd32(buffer+pos, &FieldSize); pos += 4;
|
||||
memcpy(buffer+pos, Entries[i].Password.getString(),FieldSize); pos += FieldSize;
|
||||
Entries[i].Password.delRef();
|
||||
Entries[i].Password.unlock();
|
||||
memcpy(buffer+pos, Entries[i].Password.string(),FieldSize); pos += FieldSize;
|
||||
Entries[i].Password.lock();
|
||||
|
||||
FieldType = 0x0008;
|
||||
FieldSize = Entries[i].Additional.utf8().length() + 1; // Add terminating NULL character space
|
||||
|
@ -1225,8 +1226,12 @@ void assertEntriesEq(KPTestResults& results, CEntry* left, CEntry* right){
|
|||
kp_assert(results, left->UserName == right->UserName);
|
||||
size += sizeof(left->UserName);
|
||||
|
||||
kp_assert(results, left->Password.getString() == right->Password.getString());
|
||||
left->Password.unlock();
|
||||
right->Password.unlock();
|
||||
kp_assert(results, left->Password.string() == right->Password.string());
|
||||
size += sizeof(left->Password);
|
||||
left->Password.lock();
|
||||
right->Password.lock();
|
||||
|
||||
kp_assert(results, left->Additional == right->Additional);
|
||||
size += sizeof(left->Additional);
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2005-2006 by Tarek Saidi *
|
||||
* tarek.saidi@arcor.de *
|
||||
* *
|
||||
* 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 <QByteArray>
|
||||
#include "arcfour.h"
|
||||
|
||||
|
||||
static inline void swap_byte(unsigned char *a, unsigned char *b)
|
||||
{
|
||||
unsigned char swapByte;
|
||||
|
||||
swapByte = *a;
|
||||
*a = *b;
|
||||
*b = swapByte;
|
||||
}
|
||||
|
||||
void CArcFour::setKey(byte* key_data_ptr, int key_data_len){
|
||||
RawKey=QByteArray((const char*)key_data_ptr,key_data_len);
|
||||
}
|
||||
|
||||
void CArcFour::prepareKey(){
|
||||
unsigned char swapByte;
|
||||
unsigned char index1;
|
||||
unsigned char index2;
|
||||
unsigned char* state;
|
||||
short counter;
|
||||
|
||||
state = &key.state[0];
|
||||
for(counter = 0; counter < 256; counter++)
|
||||
state[counter] = counter;
|
||||
key.x = 0;
|
||||
key.y = 0;
|
||||
index1 = 0;
|
||||
index2 = 0;
|
||||
for(counter = 0; counter < 256; counter++)
|
||||
{
|
||||
index2 = (RawKey.at(index1) + state[counter] + index2) % 256;
|
||||
swap_byte(&state[counter], &state[index2]);
|
||||
index1 = (index1 + 1) % RawKey.size();
|
||||
}
|
||||
}
|
||||
|
||||
void CArcFour::encrypt(const byte* src, byte* dst,int length){
|
||||
//qDebug("Key:%s",RawKey.data());
|
||||
prepareKey();
|
||||
unsigned char x;
|
||||
unsigned char y;
|
||||
unsigned char* state;
|
||||
unsigned char xorIndex;
|
||||
short counter;
|
||||
|
||||
x = key.x;
|
||||
y = key.y;
|
||||
|
||||
state = &key.state[0];
|
||||
for(counter = 0; counter < length; counter ++)
|
||||
{
|
||||
x = (x + 1) % 256;
|
||||
y = (state[x] + y) % 256;
|
||||
swap_byte(&state[x], &state[y]);
|
||||
|
||||
xorIndex = (state[x] + state[y]) % 256;
|
||||
|
||||
dst[counter]=src[counter]^state[xorIndex];
|
||||
}
|
||||
key.x = x;
|
||||
key.y = y;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2005-2006 by Tarek Saidi *
|
||||
* tarek.saidi@arcor.de *
|
||||
* *
|
||||
* 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 _ARCFOUR_H_
|
||||
#define _ARCFOUR_H_
|
||||
|
||||
#ifndef byte
|
||||
#define byte unsigned char
|
||||
#endif
|
||||
|
||||
class CArcFour{
|
||||
public:
|
||||
void encrypt(const byte* src, byte* dst,int length);
|
||||
inline void decrypt(const byte* src, byte* dst,int length){encrypt(src,dst,length);} //just for readability
|
||||
void setKey(byte* key, int length);
|
||||
QByteArray RawKey;
|
||||
private:
|
||||
void prepareKey();
|
||||
|
||||
typedef struct rc4_key{
|
||||
byte state[256];
|
||||
byte x;
|
||||
byte y;}rc4_key;
|
||||
rc4_key key;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -77,9 +77,10 @@ setIcon(EntryIcons[entry->ImageID]);
|
|||
Edit_Title->setText(entry->Title);
|
||||
Edit_UserName->setText(entry->UserName);
|
||||
Edit_URL->setText(entry->URL);
|
||||
Edit_Password->setText(entry->Password.getString());
|
||||
Edit_Password_w->setText(entry->Password.getString());
|
||||
entry->Password.delRef();
|
||||
entry->Password.unlock();
|
||||
Edit_Password->setText(entry->Password.string());
|
||||
Edit_Password_w->setText(entry->Password.string());
|
||||
entry->Password.lock();
|
||||
if(!config.ShowPasswords)
|
||||
ChangeEchoMode();
|
||||
OnPasswordwLostFocus();
|
||||
|
@ -171,10 +172,10 @@ if(entry->URL!=Edit_URL->text())
|
|||
ModFlag=true;
|
||||
if(entry->Additional!=Edit_Comment->text())
|
||||
ModFlag=true;
|
||||
QString& passw=entry->Password.getString();
|
||||
if(passw!=Edit_Password->text())
|
||||
entry->Password.unlock();
|
||||
if(entry->Password.string()!=Edit_Password->text())
|
||||
ModFlag=true;
|
||||
entry->Password.delRef();
|
||||
entry->Password.lock();
|
||||
|
||||
entry->Expire=DateTime_Expire->dateTime();
|
||||
entry->LastAccess=QDateTime::currentDateTime();
|
||||
|
|
|
@ -92,15 +92,16 @@ for(int i=0;i<db->Entries.size();i++){
|
|||
else
|
||||
if(db->Entries[i].GroupID != group->ID)continue;
|
||||
}
|
||||
|
||||
|
||||
bool hit=false;
|
||||
if(checkBox_Title->isChecked()) hit=hit||search(db->Entries[i].Title);
|
||||
if(checkBox_Username->isChecked()) hit=hit||search(db->Entries[i].UserName);
|
||||
if(checkBox_URL->isChecked()) hit=hit||search(db->Entries[i].URL);
|
||||
if(checkBox_Comment->isChecked()) hit=hit||search(db->Entries[i].Additional);
|
||||
if(checkBox_Attachment->isChecked()) hit=hit||search(db->Entries[i].BinaryDesc);
|
||||
if(checkBox_Password->isChecked()) hit=hit||search(db->Entries[i].Password.getString());
|
||||
db->Entries[i].Password.delRef();
|
||||
db->Entries[i].Password.unlock();
|
||||
if(checkBox_Password->isChecked()) hit=hit||search(db->Entries[i].Password.string());
|
||||
db->Entries[i].Password.lock();
|
||||
if(hit)Hits.push_back(db->Entries[i].sID);
|
||||
}
|
||||
|
||||
|
@ -109,7 +110,7 @@ done(1);
|
|||
}
|
||||
|
||||
|
||||
bool CSearchDlg::search(QString& str){
|
||||
bool CSearchDlg::search(const QString& str){
|
||||
|
||||
if(regexp){
|
||||
QRegExp exp(txt,checkBox_Cs->isChecked());
|
||||
|
|
|
@ -41,7 +41,7 @@ private:
|
|||
CGroup* group;
|
||||
bool regexp;
|
||||
PwDatabase* db;
|
||||
bool search(QString& str);
|
||||
bool search(const QString& str);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,14 +69,31 @@ ContextMenu->popup(e->globalPos());
|
|||
|
||||
|
||||
void KeepassEntryView::updateItems(unsigned int GroupID){
|
||||
|
||||
clear();
|
||||
Items.clear();
|
||||
if(!db)return;
|
||||
if(!GroupID)return;
|
||||
EntryViewItem *tmp=NULL;
|
||||
for(int i=0;i<db->Entries.size();i++){
|
||||
CEntry* entry=&db->Entries[i];
|
||||
if(entry->GroupID==GroupID){
|
||||
if(db->Entries[i].GroupID==GroupID)
|
||||
setEntry(&db->Entries[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void KeepassEntryView::showSearchResults(QList<Q_UINT32>& results){
|
||||
clear();
|
||||
Items.clear();
|
||||
for(int j=0; j<results.size(); j++){
|
||||
for(int i=0; i<db->Entries.size();i++){
|
||||
if(db->Entries[i].sID == results[j])
|
||||
setEntry(&db->Entries[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeepassEntryView::setEntry(CEntry* entry){
|
||||
EntryViewItem* tmp=NULL;
|
||||
Items.push_back(tmp=new EntryViewItem(this));
|
||||
Items.back()->pEntry=entry;
|
||||
int j=0;
|
||||
|
@ -93,8 +110,9 @@ for(int i=0;i<db->Entries.size();i++){
|
|||
if(config.ListView_HidePasswords)
|
||||
tmp->setText(j++,"******");
|
||||
else{
|
||||
tmp->setText(j++,entry->Password.getString());
|
||||
entry->Password.delRef();}}
|
||||
entry->Password.unlock();
|
||||
tmp->setText(j++,entry->Password.string());
|
||||
entry->Password.lock();}}
|
||||
if(config.Columns[4]){
|
||||
tmp->setText(j++,entry->Additional.section('\n',0,0));}
|
||||
if(config.Columns[5]){
|
||||
|
@ -108,17 +126,6 @@ for(int i=0;i<db->Entries.size();i++){
|
|||
if(config.Columns[9]){
|
||||
tmp->setText(j++,entry->BinaryDesc);}
|
||||
Items.back()->setIcon(0,EntryIcons[entry->ImageID]);
|
||||
}}
|
||||
}
|
||||
|
||||
void KeepassEntryView::showSearchResults(QList<Q_UINT32>& results){
|
||||
updateItems(0);
|
||||
for(int j=0; j<results.size(); j++){
|
||||
for(int i=0; i<Items.size();i++){
|
||||
if(Items[i]->pEntry->sID == results[j])
|
||||
setItemHidden(Items[i],false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeepassEntryView::refreshItems(){
|
||||
|
@ -141,8 +148,9 @@ for(int i=0;i<Items.size();i++){
|
|||
if(config.ListView_HidePasswords)
|
||||
tmp->setText(j++,"******");
|
||||
else{
|
||||
tmp->setText(j++,entry->Password.getString());
|
||||
entry->Password.delRef();}}
|
||||
entry->Password.unlock();
|
||||
tmp->setText(j++,entry->Password.string());
|
||||
entry->Password.lock();}}
|
||||
if(config.Columns[4]){
|
||||
tmp->setText(j++,entry->Additional.section('\n',0,0));}
|
||||
if(config.Columns[5]){
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
vector<EntryViewItem*>Items;
|
||||
QMenu *ContextMenu;
|
||||
private:
|
||||
void setEntry(CEntry* entry);
|
||||
int CurrentGroup;
|
||||
protected:
|
||||
virtual void contextMenuEvent(QContextMenuEvent *event);
|
||||
|
|
|
@ -19,83 +19,89 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include "SecString.h"
|
||||
#include <qmessagebox.h>
|
||||
#include <iostream>
|
||||
#include "crypto/arcfour.h"
|
||||
#include "random.h"
|
||||
using namespace std;
|
||||
Q_UINT8 SecString::Key[32]={0};
|
||||
CArcFour SecString::RC4;
|
||||
|
||||
SecString::operator QString(){
|
||||
return string();
|
||||
}
|
||||
|
||||
SecString::SecString(){
|
||||
len=0;
|
||||
locked=true;
|
||||
}
|
||||
|
||||
int SecString::length(){
|
||||
return crypt.size();
|
||||
}
|
||||
|
||||
SecString::~SecString(){
|
||||
overwrite(plaintext);
|
||||
lock();
|
||||
}
|
||||
|
||||
void SecString::getString(QString & str){
|
||||
if(data.size()){
|
||||
Rijndael aes;
|
||||
int r=aes.init(Rijndael::CBC, Rijndael::Decrypt,Key,Rijndael::Key32Bytes);
|
||||
if(r){ cout << "AES error, code " << r << endl;
|
||||
exit(-1);}
|
||||
char* out=new char[len];
|
||||
r=aes.padDecrypt((unsigned char*)data.data(),data.size(),(unsigned char*)out);
|
||||
if(r!=len){ cout << "AES error in SecString::getString(), r!=length, r=" << r << endl;
|
||||
exit(-1);}
|
||||
str=QString::fromUtf8(out,len);
|
||||
overwrite(out,len);
|
||||
delete [] out;
|
||||
}
|
||||
void SecString::lock(){
|
||||
locked=true;
|
||||
overwrite(plain);
|
||||
plain=QString();
|
||||
}
|
||||
|
||||
QString& SecString::getString(){
|
||||
getString(plaintext);
|
||||
return plaintext;
|
||||
void SecString::unlock(){
|
||||
locked=false;
|
||||
plain=QString();
|
||||
if(!crypt.length()){return;}
|
||||
const unsigned char* buffer=new unsigned char[crypt.length()];
|
||||
SecString::RC4.decrypt((byte*)crypt.data(),(unsigned char*)buffer,crypt.length());
|
||||
plain=QString::fromUtf8((const char*)buffer,crypt.size());
|
||||
overwrite((unsigned char*)buffer,crypt.size());
|
||||
delete [] buffer;
|
||||
}
|
||||
|
||||
void SecString::delRef(){
|
||||
overwrite(plaintext);
|
||||
|
||||
const QString& SecString::string(){
|
||||
if(locked){
|
||||
printf("Error in function SecString::string(): string is locked\n");
|
||||
return QString(">SEC_STRING_ERROR<");
|
||||
}
|
||||
return plain;
|
||||
}
|
||||
|
||||
void SecString::setString(QString& str,bool DelSrc){
|
||||
Rijndael aes;
|
||||
int r=aes.init(Rijndael::CBC, Rijndael::Encrypt,Key,Rijndael::Key32Bytes);
|
||||
if(r){ cout << "AES error, code " << r << endl;
|
||||
exit(-1);}
|
||||
int il=str.length();
|
||||
char* input=new char[il];
|
||||
char* output=new char[il+16];
|
||||
memcpy(input,str.utf8(),il);
|
||||
r=aes.padEncrypt((unsigned char*)input,il,(unsigned char*)output);
|
||||
if(r<0){ cout << "AES error, code " << r << endl;
|
||||
exit(-1);}
|
||||
len=il;
|
||||
data=QByteArray(output,r);
|
||||
overwrite(input,il);
|
||||
delete [] input;
|
||||
if(DelSrc)overwrite(str);
|
||||
|
||||
void SecString::setString(QString& str,bool DeleteSource){
|
||||
QByteArray StrData=str.toUtf8();
|
||||
int len=StrData.size();
|
||||
unsigned char* buffer=new unsigned char[len];
|
||||
SecString::RC4.encrypt((const unsigned char*)StrData.data(),buffer,len);
|
||||
crypt=QByteArray((const char*)buffer,len);
|
||||
overwrite(buffer,len);
|
||||
overwrite((unsigned char*)StrData.data(),len);
|
||||
delete [] buffer;
|
||||
if(DeleteSource){
|
||||
overwrite(str);
|
||||
str=QString();}
|
||||
lock();
|
||||
}
|
||||
|
||||
void SecString::overwrite(char* str,int strlen){
|
||||
void SecString::overwrite(unsigned char* str,int strlen){
|
||||
if(strlen==0 || str==NULL)return;
|
||||
getRandomBytes(str,strlen,1,false);
|
||||
for(int i=0; i<strlen; i++){
|
||||
str[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
void SecString::overwrite(QString &str){
|
||||
if(str.length()==0)return;
|
||||
char* tmp=new char[str.length()];
|
||||
getRandomBytes(tmp,str.length(),1,false);
|
||||
str=tmp;
|
||||
delete [] tmp;
|
||||
for(int i=0; i<str.length(); i++){
|
||||
((char*)str.data())[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
int SecString::length(){
|
||||
return len;
|
||||
}
|
||||
|
||||
void SecString::generateSessionKey(){
|
||||
getRandomBytes(Key,32,1,false);
|
||||
}
|
||||
|
||||
CArcFour arc;
|
||||
unsigned char* sessionkey=new unsigned char[32];
|
||||
getRandomBytes(sessionkey,32,1,false);
|
||||
RC4.setKey(sessionkey,32);
|
||||
delete [] sessionkey;
|
||||
}
|
|
@ -23,28 +23,29 @@
|
|||
#include <QByteArray>
|
||||
#include <qstring.h>
|
||||
#include <qglobal.h>
|
||||
#include "crypto/rijndael.h"
|
||||
#include "crypto/arcfour.h"
|
||||
|
||||
class SecString{
|
||||
public:
|
||||
SecString(unsigned char* key);
|
||||
SecString();
|
||||
~SecString();
|
||||
|
||||
void getString(QString& str);
|
||||
QString& getString();
|
||||
void setString(QString& str, bool DelSrc=false);
|
||||
void delRef();
|
||||
static void overwrite(char* str,int len);
|
||||
static void overwrite(QString& str);
|
||||
void lock();
|
||||
void unlock();
|
||||
const QString& string();
|
||||
operator QString();
|
||||
int length();
|
||||
|
||||
static void overwrite(unsigned char* str,int len);
|
||||
static void overwrite(QString& str);
|
||||
static void generateSessionKey();
|
||||
|
||||
private:
|
||||
static Q_UINT8 Key[32];
|
||||
QString plaintext;
|
||||
QByteArray data;
|
||||
int len;
|
||||
bool locked;
|
||||
static CArcFour RC4;
|
||||
QByteArray crypt;
|
||||
QString plain;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -123,6 +123,8 @@ if(config.Language!="_DEUTSCH_"){
|
|||
DateTimeFormat=QObject::trUtf8("dd'.'MM'.'yy' 'hh':'mm");
|
||||
loadImages();
|
||||
|
||||
SecString::generateSessionKey();
|
||||
|
||||
KeepassMainWindow *mainWin = new KeepassMainWindow();
|
||||
mainWin->show();
|
||||
int r=app->exec();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Tarek Saidi *
|
||||
* Copyright (C) 2005-2006 by Tarek Saidi *
|
||||
* tarek.saidi@arcor.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
|
@ -303,9 +303,10 @@ void KeepassMainWindow::OnFileOpen(){
|
|||
if(FileOpen)
|
||||
if(!closeDatabase())return;
|
||||
QString filename=QFileDialog::getOpenFileName(this,trUtf8("Databank öffnen..."),QDir::homePath(),"*.kdb");
|
||||
if(filename!=QString::null)
|
||||
if(filename!=QString::null){
|
||||
openDatabase(filename);
|
||||
}
|
||||
}
|
||||
|
||||
void KeepassMainWindow::OnFileClose(){
|
||||
closeDatabase();
|
||||
|
@ -394,22 +395,26 @@ if(EntryView->selectedItems().size()!=1){
|
|||
|
||||
CEntry& entry=*((EntryViewItem*)(EntryView->selectedItems()[0]))->pEntry;
|
||||
QString str=trUtf8("<B>Gruppe: </B>%1 <B>Titel: </B>%2 <B>Benutzername: </B>%3 <B>URL: </B><a href=%4>%4</a> <B>Passwort: </B>%5 <B>Erstellt: </B>%6 <B>letzte Änderung: </B>%7 <B>letzter Zugriff: </B>%8 <B>gültig bis: </B>%9");
|
||||
str=str.arg(currentGroup()->Name).arg(entry.Title);
|
||||
//todo: a "CGroup* PwDatabase::getGroup(CEntry*)" method would be a good idea
|
||||
str=str.arg(db->Groups[db->getGroupIndex(entry.GroupID)].Name).arg(entry.Title);
|
||||
|
||||
if(!config.ListView_HideUsernames) str=str.arg(entry.UserName);
|
||||
else str=str.arg("****");
|
||||
|
||||
str=str.arg(entry.URL);
|
||||
|
||||
if(!config.ListView_HidePasswords) str=str.arg(entry.Password.getString());
|
||||
entry.Password.unlock();
|
||||
if(!config.ListView_HidePasswords) str=str.arg(entry.Password.string());
|
||||
else str=str.arg("****");
|
||||
|
||||
entry.Password.lock();
|
||||
|
||||
str=str.arg(entry.Creation.toString(Qt::LocalDate))
|
||||
.arg(entry.LastMod.toString(Qt::LocalDate))
|
||||
.arg(entry.LastAccess.toString(Qt::LocalDate))
|
||||
.arg(entry.Expire.toString(Qt::LocalDate));
|
||||
DetailView->setHtml(str);
|
||||
entry.Password.delRef();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -669,9 +674,10 @@ ClipboardTimer.start(config.ClipboardTimeOut*1000,true);
|
|||
}
|
||||
|
||||
void KeepassMainWindow::OnEditPasswordToClipboard(){
|
||||
Clipboard->setText(currentEntry()->Password.getString(),QClipboard::Clipboard);
|
||||
currentEntry()->Password.unlock();
|
||||
Clipboard->setText(currentEntry()->Password.string(),QClipboard::Clipboard);
|
||||
ClipboardTimer.start(config.ClipboardTimeOut*1000,true);
|
||||
currentEntry()->Password.delRef();
|
||||
currentEntry()->Password.lock();
|
||||
|
||||
}
|
||||
|
||||
|
|
23
src/src.pro
23
src/src.pro
|
@ -3,15 +3,8 @@
|
|||
# Unterordner relativ zum Projektordner: ./src
|
||||
# Das Target ist eine Anwendung: ../bin/keepass
|
||||
|
||||
INSTALLS += target \
|
||||
Share
|
||||
INSTALLS += Share
|
||||
Share.files += ../share/keepass/*
|
||||
unix{ target.path = /usr/local/bin
|
||||
Share.path = /usr/local/share/keepass
|
||||
}
|
||||
macx{ target.path = /Applications
|
||||
Share.path = /Applications/keepass.app/Contents/share/keepass
|
||||
}
|
||||
FORMS += forms/EditGroupDlg.ui \
|
||||
forms/SearchDlg.ui \
|
||||
forms/AboutDlg.ui \
|
||||
|
@ -57,7 +50,8 @@ HEADERS += lib/IniReader.h \
|
|||
global.h \
|
||||
main.h \
|
||||
lib/GroupView.h \
|
||||
lib/EntryView.h
|
||||
lib/EntryView.h \
|
||||
crypto/arcfour.h
|
||||
SOURCES += lib/IniReader.cpp \
|
||||
lib/UrlLabel.cpp \
|
||||
main.cpp \
|
||||
|
@ -88,7 +82,8 @@ SOURCES += lib/IniReader.cpp \
|
|||
Database.cpp \
|
||||
lib/KdePlugin.cpp \
|
||||
lib/GroupView.cpp \
|
||||
lib/EntryView.cpp
|
||||
lib/EntryView.cpp \
|
||||
crypto/arcfour.cpp
|
||||
QT += xml \
|
||||
qt3support
|
||||
MOC_DIR = ../build/moc
|
||||
|
@ -103,3 +98,11 @@ thread \
|
|||
exceptions \
|
||||
stl
|
||||
TEMPLATE = app
|
||||
unix{
|
||||
target.path = /usr/local/bin
|
||||
Share.path = /usr/local/share/keepass
|
||||
}
|
||||
macx{
|
||||
target.path = /Applications
|
||||
Share.path = /Applications/keepass.app/Contents/share/keepass
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue