Commits

Etienne Perot committed 090267e Merge

Merge branch 'autoopen'

Comments (0)

Files changed (5)

src/lib/random.cpp

 
 #if defined(Q_WS_X11) || defined(Q_WS_MAC)
 	#include <QFile>
+	#include <sys/types.h>
+	#include <unistd.h>
 #elif defined(Q_WS_WIN)
 	#include <windows.h>
 	#include <wincrypt.h>
 	HCRYPTPROV handle;
 	if (!CryptAcquireContext(&handle, 0, 0,  PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
 		return false;
-	
+
 	CryptGenRandom(handle, length, buffer);
 	CryptReleaseContext(handle, 0);
-	
+
 	return true;
 }
 
 	static bool initalized = false;
 	if (initalized)
 		return;
-	
+
 	QByteArray buffer;
 	QDataStream stream(&buffer, QIODevice::WriteOnly);
-	
+
 	stream << QCursor::pos();
 	stream << QDateTime::currentDateTime().toTime_t();
 	stream << QTime::currentTime().msec();
 	quint64 code_value = (quint64)initStdRand;
 	stream << code_value;
 	stream << (quint64)&code_value;
-	
+
 	QByteArray hash = QCryptographicHash::hash(buffer, QCryptographicHash::Sha1);
-	
+
 	qsrand( *((uint*) hash.data()) );
 	initalized = true;
 }
 int main(int argc, char **argv)
 {
 	setlocale(LC_CTYPE, "");
-	
+
 #if defined(Q_WS_X11) && defined(AUTOTYPE)
 	QApplication* app = new KeepassApplication(argc,argv);
 #else
 #endif
 	EventListener* eventListener = new EventListener();
 	app->installEventFilter(eventListener);
-	
+
 	QApplication::setQuitOnLastWindowClosed(false);
-	
+
 	AppDir = QApplication::applicationFilePath();
 	AppDir.truncate(AppDir.lastIndexOf("/"));
 #if defined(Q_WS_X11)
 		HomeDir = QDir::fromNativeSeparators(HomeDir)+"/KeePassX";
 	else
 		HomeDir = QDir::homePath()+"/KeePassX";
-	
+
 	DataDir = AppDir+"/share";
 #endif
 	DataDir = QDir::cleanPath(DataDir);
-	
+
 	CmdLineArgs args;
 	if ( !args.parse(QApplication::arguments()) ){
 		qCritical("%s\n", CSTR( args.error() ));
 #endif
 	config = new KpxConfig(IniFilename);
 	fileDlgHistory.load();
-	
+
 	// PlugIns
 	/*
 #ifdef Q_WS_X11
 	}
 #endif
 	*/
-	
+
 	DetailViewTemplate=config->detailViewTemplate();
 
 	loadImages();
 	KpxBookmarks::load();
 	initYarrow(); //init random number generator
 	SecString::generateSessionKey();
-	
+
 	installTranslator();
 
 #ifdef Q_WS_MAC
 	}
 #endif
 
-	KeepassMainWindow *mainWin = new KeepassMainWindow(args.file(), args.startMinimized(), args.startLocked());
+	KeepassMainWindow *mainWin = new KeepassMainWindow(args.file(), args.password(), args.keyFile(), args.bypassLock(), args.startMinimized(), args.startLocked());
 #ifdef Q_WS_MAC
 	eventListener->setMainWin(mainWin);
 #endif
 CmdLineArgs::CmdLineArgs(){
 	StartMinimized=false;
 	StartLocked=false;
+	BypassLock=true;
 	Help=false;
+	DefaultPassword="";
+	DefaultKeyFile="";
 }
 
 bool CmdLineArgs::parse(const QStringList& argv){
 			i++;
 			continue;
 		}
+		if(argv[i]=="-pwd"){
+			if(argv.size() == i+1){
+				Error="Missing argument for '-pwd'.";
+				return false;
+			}
+			if(argv[i+1].left(1)=="-"){
+				Error=QString("Expected a path as argument for '-pwd' but got '%1.'").arg(argv[i+1]);
+				return false;
+			}
+			QString password(argv[i+1]);
+			DefaultPassword=password;
+			i++;
+			continue;
+		}
+		if(argv[i]=="-keyfile"){
+			if(argv.size() == i+1){
+				Error="Missing argument for '-keyfile'.";
+				return false;
+			}
+			if(argv[i+1].left(1)=="-"){
+				Error=QString("Expected a path as argument for '-keyfile' but got '%1.'").arg(argv[i+1]);
+				return false;
+			}
+			QString keyfile(argv[i+1]);
+			DefaultKeyFile=keyfile;
+			i++;
+			continue;
+		}
+		if(argv[i]=="-bypasslock"){
+			BypassLock=true;
+			continue;
+		}
 		if(argv[i]=="-min"){
 			StartMinimized=true;
 			continue;
 	cerr << "  -cfg <CONFIG>     Use specified file for loading/saving the configuration." << endl;
 	cerr << "  -min              Start minimized." << endl;
 	cerr << "  -lock             Start locked." << endl;
+	cerr << "  -bypasslock       Ignore the *.lock file if there is one." << endl;
+	cerr << "  -pwd <PASSWORD>   Use this password to open the database." << endl;
+	cerr << "  -keyfile <KEY>    Use this keyfile to open the database." << endl;
 }
 
 
 /*QString findPlugin(const QString& filename){
-	QFileInfo info;	
+	QFileInfo info;
 	info.setFile(AppDir+"/../lib/"+filename);
 	if(info.exists() && info.isFile())
-		return AppDir+"/../lib/"+filename;	
+		return AppDir+"/../lib/"+filename;
 	return QString();
 }*/
 
 		if ( (t>=QEvent::MouseButtonPress && t<=QEvent::KeyRelease) || (t>=QEvent::HoverEnter && t<=QEvent::HoverMove) )
 			EventOccurred = true;
 	}
-	
+
 #ifdef Q_WS_MAC
 	if (event->type() == QEvent::FileOpen) {
 		QString filename = static_cast<QFileOpenEvent*>(event)->file();
 		}
 	}
 #endif
-	
+
 	return false;
 }
 	static void printHelp();
 	QString error() {return Error;}
 	QString file() {return File;}
+	QString keyFile() {return DefaultKeyFile;}
 	QString configLocation() {return ConfigLocation;}
 	QString language() {return Language;}
+	QString password() {return DefaultPassword;}
 	bool startMinimized() {return StartMinimized;}
 	bool startLocked() {return StartLocked;}
+	bool bypassLock() {return BypassLock;}
 	bool help() {return Help;}
 	void setFile(const QString& filename) {File = filename;};
 private:
 	QString File;
 	QString ConfigLocation;
 	QString Language;
+	QString DefaultPassword;
+	QString DefaultKeyFile;
 	bool StartMinimized;
 	bool StartLocked;
+	bool BypassLock;
 	bool Help;
 };
 
 class EventListener : public QObject {
 	Q_OBJECT
-	
+
 #ifdef Q_WS_MAC
 	public:
 		EventListener() { pMainWindow = NULL; };
 		inline void setMainWin(KeepassMainWindow* mainWin) {
 			pMainWindow = mainWin;
 		};
-	
+
 	private:
 		QString pFile;
 		KeepassMainWindow* pMainWindow;
 #endif
-	
+
 	protected:
 		bool eventFilter(QObject*, QEvent* event);
 };

src/mainwindow.cpp

 #include "lib/HelperMacX.h"
 #endif
 
+
 Import_KeePassX_Xml import_KeePassX_Xml;
 Import_PwManager import_PwManager;
 Import_KWalletXml import_KWalletXml;
 Export_KeePassX_Xml export_KeePassX_Xml;
 
 KeepassMainWindow::KeepassMainWindow(const QString& ArgFile,bool ArgMin,bool ArgLock,QWidget *parent, Qt::WFlags flags) :QMainWindow(parent,flags){
+	init(ArgFile,"","",false,ArgMin,ArgLock);
+}
+KeepassMainWindow::KeepassMainWindow(const QString& ArgFile, const QString& DefaultPass, const QString& DefaultFile, bool BypassLock, bool ArgMin,bool ArgLock,QWidget *parent, Qt::WFlags flags) :QMainWindow(parent,flags){
+	init(ArgFile,DefaultPass,DefaultFile,BypassLock,ArgMin,ArgLock);
+}
+void KeepassMainWindow::init(const QString& ArgFile, const QString& DefaultPass, const QString& DefaultFile, bool BypassLock, bool ArgMin,bool ArgLock){
+	DefaultPassword=DefaultPass;
+	DefaultKeyFile=DefaultFile;
+	BypassLockFile=BypassLock;
 	ShutingDown=false;
 	IsLocked=false;
 	EventOccurred=true;
 
 	setupConnections();
 	connect(qApp, SIGNAL(commitDataRequest(QSessionManager&)), SLOT(OnShutdown(QSessionManager&)));
-	
+
 	inactivityTimer = new QTimer(this);
 	inactivityTimer->setInterval(500);
 	connect(inactivityTimer, SIGNAL(timeout()), SLOT(OnInactivityTimer()));
 		if (ArgLock)
 			fakeOpenDatabase(f);
 		else
-			openDatabase(f,false);
+			openDatabase(f,false,BypassLock,DefaultPassword,DefaultKeyFile);
 	}
 	else if(config->openLastFile() && !config->lastFile().isEmpty()){
 		QFileInfo file(config->lastFile());
 		else
 			config->setLastFile(QString());
 	}
-	
+
 	// TODO HelpBrowser
 	/*HelpBrowser = new QAssistantClient(QString(),this);
 	HelpBrowser->setArguments(QStringList()<< "-profile" << "share/keepass/doc/keepassx.adp");*/
 
 	createBookmarkActions();
-	
+
 	if (showWindow)
 		show();
 	else if (!config->showSysTrayIcon())
 		case 22: ViewToolButtonSize22Action->setChecked(true); break;
 		case 28: ViewToolButtonSize28Action->setChecked(true); break;
 	}
-	
+
 #ifdef Q_WS_MAC
 	ViewMenu->addSeparator();
 	ViewMenu->addAction(ViewMinimizeAction);
 }
 
 
-bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){
+bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto,bool bypass,QString defaultPwd, QString defaultFile){
 	if (!QFile::exists(filename)){
 		QMessageBox::critical(this, tr("Error"), tr("The database file does not exist."));
 		return false;
 	}
-	
+
 	dbReadOnly = false;
-	
-	if (QFile::exists(filename+".lock")){
+
+	if (!bypass && QFile::exists(filename+".lock")){
 		QMessageBox msgBox(this);
 		msgBox.setIcon(QMessageBox::Question);
 		msgBox.setWindowTitle(tr("Database locked"));
 		HelperMacX::processToFront(HelperMacX::getKeepassxPID());
 #endif
 		msgBox.exec();
-		
+
 		if (!msgBox.clickedButton() || msgBox.clickedButton() == msgBox.button(QMessageBox::No))
 			return false;
 		else if (msgBox.clickedButton() == readOnlyButton)
 			dbReadOnly = true;
 	}
-	
+
 	if(!IsAuto){
 		config->setLastKeyLocation(QString());
 		config->setLastKeyType(PASSWORD);
 	}
 	db = new Kdb3Database();
-	PasswordDialog::DlgFlags flags=PasswordDialog::Flag_None;
-	if(IsAuto)
-		flags = PasswordDialog::Flag_Auto;
-	PasswordDialog dlg(this,PasswordDialog::Mode_Ask,flags,filename);
-	if (InUnLock){
-		dlg.setWindowModality(Qt::WindowModal);
-		unlockDlg = &dlg;
-	}
-#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_MAC)
-	// On MacX, QMessageBox is not brought to foreground on exec() when app not already there
-	HelperMacX::processToFront(HelperMacX::getKeepassxPID());
-#endif
-	bool rejected = (dlg.exec()==PasswordDialog::Exit_Cancel);
-	if (InUnLock)
-		unlockDlg = NULL;
-	if (rejected)
-		return false;
-	
-	if(dlg.selectedBookmark()!=QString())
-		filename=dlg.selectedBookmark();
-
 	GroupView->db=db;
 	EntryView->db=db;
 	setupDatabaseConnections(db);
-	QString err;
-	setStatusBarMsg(StatusBarLoading);
-	db->setKey(dlg.password(),dlg.keyFile());
-	
+
+	if(defaultPwd.isEmpty() && defaultFile.isEmpty())
+	{
+		PasswordDialog::DlgFlags flags=PasswordDialog::Flag_None;
+		if(IsAuto)
+			flags = PasswordDialog::Flag_Auto;
+		PasswordDialog dlg(this,PasswordDialog::Mode_Ask,flags,filename);
+		if (InUnLock){
+			dlg.setWindowModality(Qt::WindowModal);
+			unlockDlg = &dlg;
+		}
+		#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_MAC)
+			// On MacX, QMessageBox is not brought to foreground on exec() when app not already there
+			HelperMacX::processToFront(HelperMacX::getKeepassxPID());
+		#endif
+		bool rejected = (dlg.exec()==PasswordDialog::Exit_Cancel);
+		if (InUnLock)
+			unlockDlg = NULL;
+		if (rejected)
+			return false;
+
+		if(dlg.selectedBookmark()!=QString())
+			filename=dlg.selectedBookmark();
+
+		QString err;
+		setStatusBarMsg(StatusBarLoading);
+		db->setKey(dlg.password(),dlg.keyFile());
+	}
+	else
+	{
+		db->setKey(defaultPwd, defaultFile);
+	}
+
 	if (!dbReadOnly && !QFile::exists(filename+".lock")){
 		QFile lock(filename+".lock");
 		if (!lock.open(QIODevice::WriteOnly)){
 			dbReadOnly = true;
 		}
 	}
-	
+
 	if(db->load(filename, dbReadOnly)){
 		if (IsLocked)
 			resetLock();
 	if (statusbarState != StatusBarReadOnlyLock)
 		setStatusBarMsg(StatusBarReady);
 	inactivityCounter = 0;
-	
+
 	GroupView->selectFirstGroup();
-	
+
 	return true;
 }
 
 		QMessageBox::critical(this, tr("Error"), tr("The database file does not exist."));
 		return;
 	}
-	
+
 	config->setLastFile(filename);
 	updateCurrentFile(filename);
 	setLock();
 	ExtrasShowExpiredEntriesAction->setEnabled(IsOpen);
 	AddThisAsBookmarkAction->setEnabled(IsOpen && db->file());
 	FileUnLockWorkspaceAction->setEnabled(IsOpen||IsLocked);
-	
+
 	if(!IsOpen){
 		EditNewSubgroupAction->setEnabled(false);
 		EditEditGroupAction->setEnabled(false);
 		EditAutoTypeAction->setEnabled(false);
 #endif
 	}
-	
+
 	updateWindowTitle();
 	updateTrayTooltip();
 }
 		if (OnFileSave())
 			return; // return on success, so we don't set the state to modified
 	}
-	
+
 	ModFlag=mod;
 	if(mod)
 		FileSaveAction->setIcon(getIcon("filesave"));
 			tr("Save Database..."),QStringList()<<tr("KeePass Databases (*.kdb)")<< tr("All Files (*)"));
 	if (filename.isEmpty() || filename.compare(".kdb", Qt::CaseInsensitive)==0)
 		return false;
-	
+
 	QFile lock(filename+".lock");
 	if (!lock.open(QIODevice::WriteOnly)){
 		QMessageBox::critical(this, tr("Error"), tr("Couldn't create database lock file."));
 		return false;
 	}
-	
+
 	if(!db->changeFile(filename)){
 		showErrMsg(QString("%1\n%2").arg(tr("File could not be saved.")).arg(db->getError()));
 		QFile::remove( filename+".lock" );
 		return false;
 	}
-	
+
 	if (!dbReadOnly && !currentFilePath.isEmpty() && QFile::exists(currentFilePath+".lock")){
 		if (!QFile::remove(currentFilePath+".lock"))
 			QMessageBox::critical(this, tr("Error"), tr("Couldn't remove database lock file."));
 	}
-	
+
 	dbReadOnly = false;
 	updateCurrentFile(filename);
 	updateWindowTitle();
 	updateTrayTooltip();
-	
+
 	return OnFileSave();
 }
 
 		hide();
 		return;
 	}
-	
+
 	if(FileOpen && !closeDatabase()){
 		ShutingDown = false;
 		e->ignore();
 			show();
 		return;
 	}
-	
+
 	e->accept();
-	
+
 #ifdef GLOBAL_AUTOTYPE
 	autoType->unregisterGlobalShortcut();
 #endif
 	if (config->showEntryDetails())
 		config->setHSplitterPos(HSplitter->saveState());
 	config->setShowStatusbar(statusBar()->isVisible());
-	
+
 	delete SysTray;
 	QMainWindow::closeEvent(e);
 	QApplication::quit();
 			return;
 		}
 	}
-	
+
 	QMainWindow::hideEvent(event);
 }
 
 #endif
 		OnUnLockWorkspace();
 	}
-	
+
 	QMainWindow::showEvent(event);
 }
 
 		updateTrayTooltip();
 		setStatusBarMsg(statusbarState);
 	}
-	
+
 	EntryView->setAlternatingRowColors(config->alternatingRowColors());
 	SysTray->setVisible(config->showSysTrayIcon());
 	menuBookmarks->menuAction()->setVisible(config->featureBookmarks());
 		show();
 	}
 #endif
-	
+
 	EventOccurred = true;
 	if (config->lockOnInactivity() && config->lockAfterSec()!=0 && !inactivityTimer->isActive()){
 		inactivityCounter = 0;
 				lockGroup.prepend(parent->indexOfChild(item));
 			item = parent;
 		}
-		
+
 		if (closeDatabase(true)) {
 			setStateFileModified(false);
 			setLock();
 void KeepassMainWindow::OnInactivityTimer(){
 	if (IsLocked || !FileOpen)
 		return;
-	
+
 	if (QApplication::activeModalWidget()!=NULL || EventOccurredBlock){
 		inactivityCounter = 0;
 		return;
 	}
-	
+
 	if (EventOccurred){
 		inactivityCounter = 0;
 		EventOccurred = false;
 
 void KeepassMainWindow::OnShutdown(QSessionManager& manager) {
 	ShutingDown = true;
-	
+
 	/* QApplication::commitData() only closes visible windows,
 	   so we need to manually close mainwindow if it's hidden */
 	if (manager.allowsInteraction() && !isVisible()) {
 
 void KeepassMainWindow::setStatusBarMsg(StatusBarMsg statusBarMsg) {
 	QString text;
-	
+
 	switch (statusBarMsg) {
 		case StatusBarReady:
 			text = tr("Ready");
 			text = tr("Couldn't create lock file. Opening the database read-only.");
 			break;
 	}
-	
+
 	statusbarState = statusBarMsg;
 	StatusBarGeneral->setText(text);
 }
 	Q_OBJECT
 	public:
 		KeepassMainWindow (const QString& ArgFile,bool ArgMin,bool ArgLock,QWidget *parent=0, Qt::WFlags flags=0);
+		KeepassMainWindow (const QString& ArgFile, const QString& DefaultPass, const QString& DefaultFile, bool BypassLock, bool ArgMin,bool ArgLock,QWidget *parent=0, Qt::WFlags flags=0);
 		IDatabase* db;
 		inline bool isLocked() { return IsLocked; };
 		inline bool isOpened() { return FileOpen; };
-	
+
 	public slots:
 		void OnUnLockWorkspace();
 		void openFile(const QString& filename);
 		void loadColumnVisibility();
 
 	private:
+		void init(const QString& ArgFile, const QString& DefaultPass, const QString& DefaultFile, bool BypassLock, bool ArgMin,bool ArgLock);
 		void closeEvent(QCloseEvent* event);
 		void hideEvent(QHideEvent* event);
 		void showEvent(QShowEvent* event);
 		void setStateFileModified(bool);
 		void setStateGroupSelected(SelectionState s);
 		void setStateEntrySelected(SelectionState s);
-		bool openDatabase(QString filename,bool IsAuto=false);
+		bool openDatabase(QString filename,bool IsAuto=false,bool bypass=false,QString DefaultPwd="",QString DefaultFile="");
 		void fakeOpenDatabase(const QString& filename);
 		void setupDatabaseConnections(IDatabase* DB);
 		bool closeDatabase(bool lock=false);
 		Ui_WorkspaceLockedWidget WorkspaceLockedWidget;
 		bool ShutingDown;
 		bool InUnLock;
+		bool BypassLockFile;
+		QString DefaultPassword;
+		QString DefaultKeyFile;
 		QList<int> lockGroup;
 		QDialog* unlockDlg;
 		QString currentFilePath;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.