📄 security.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** 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.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** 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.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "security.h"#include <qtopia/config.h>#include <qtopia/qpeapplication.h>#include <qtopia/password.h>#include <qtopia/qpedialog.h>#include <qtopia/qcopenvelope_qws.h>#ifdef QTOPIA_PHONE#include <qtopia/contextbar.h>#include <qtopia/private/contextkeymanager_p.h>#include <qtopia/contextmenu.h>#include "phonesecurity.h"#endif#include <qcheckbox.h>#include <qpushbutton.h>#include <qlabel.h>#include <qcombobox.h>#include <qmessagebox.h>#include <qtimer.h>#include <qhostaddress.h>class WaitScreen : public QLabel{ Q_OBJECTpublic: WaitScreen(QWidget *parent, char *name = 0) : QLabel(parent, name) { setText(tr("Please wait ..."));#ifdef QTOPIA_PHONE ContextBar::clearLabel(this, Key_Back);#endif }public slots: void makeClosable() { canClose = TRUE; close(); }protected: void show() { canClose = FALSE; // should show error if it timesout. QTimer::singleShot(5000, this, SLOT(makeClosable())); QLabel::show(); } void closeEvent(QCloseEvent *e){ // great way to appear to freeze device if (canClose) e->accept(); else e->ignore(); } void keyPressEvent(QKeyEvent *e) { // great way to appear to freeze device e->accept(); }private: bool canClose;};Security::Security( QWidget* parent, const char* name, WFlags fl )#ifdef QTOPIA_PHONE : SecurityBase( parent, name, fl ), mStatus(0)#else : SecurityBase( parent, name, TRUE, fl )#endif{ valid=FALSE; Config cfg("Security"); cfg.setGroup("Passcode"); passcode = cfg.readEntry("passcode");#ifdef QTOPIA_PHONE connect(passcode_poweron, SIGNAL(toggled(bool)), SLOT(markProtected(bool)));#else passcode_poweron->setChecked(cfg.readBoolEntry("passcode_poweron",FALSE));#endif cfg.setGroup("Sync"); QHostAddress allowed; allowed.setAddress(cfg.readEntry("auth_peer","192.168.0.0")); uint auth_peer = allowed.ip4Addr(); int auth_peer_bits = cfg.readNumEntry("auth_peer_bits",16); selectNet(auth_peer,auth_peer_bits); connect(syncnet, SIGNAL(textChanged(const QString&)), this, SLOT(setSyncNet(const QString&)));#ifdef QTOPIA_PHONE QPEApplication::setInputMethodHint(syncnet,QPEApplication::Named,"netmask"); phonesec = new PhoneSecurity(this); connect(phonesec,SIGNAL(changed(bool)),this,SLOT(phoneChanged(bool))); connect(phonesec,SIGNAL(locked(bool)),this,SLOT(phoneLocked(bool))); connect(phonesec,SIGNAL(lockDone(bool)),this,SLOT(phoneLockDone(bool))); //ContextMenu *cm = new ContextMenu(this);#endif /* cfg.setGroup("Remote"); if ( telnetAvailable() ) telnet->setChecked(cfg.readEntry("allow_telnet")); else telnet->hide(); if ( sshAvailable() ) ssh->setChecked(cfg.readEntry("allow_ssh")); else ssh->hide(); */ connect(changepasscode,SIGNAL(clicked()), this, SLOT(changePassCode())); connect(clearpasscode,SIGNAL(clicked()), this, SLOT(clearPassCode()));#ifdef QTOPIA_PHONE connect(pinSelection, SIGNAL(activated(int)), this, SLOT(updateGUI()));#else dl = new QPEDialogListener(this);#endif updateGUI();}Security::~Security(){}void Security::phoneChanged(bool success){#ifdef QTOPIA_PHONE mStatus->makeClosable(); if (success) QMessageBox::information(this, tr("Sucess"), tr("<p>Successfully changed PIN.")); else QMessageBox::warning(this, tr("Failure"), tr("<p>Could not change PIN."));#else Q_UNUSED(success);#endif}void Security::phoneLocked(bool success){#ifdef QTOPIA_PHONE if (!success) QMessageBox::warning(this, tr("Failure"), tr("<p>Could not change protection state."));#else Q_UNUSED(success);#endif}void Security::phoneLockDone(bool success){ passcode_poweron->blockSignals(TRUE); passcode_poweron->setChecked(success); passcode_poweron->blockSignals(FALSE); passcode_poweron->setEnabled(TRUE);}void Security::updateGUI(){#ifdef QTOPIA_PHONE // phone passcode. they are never 'cleared' clearpasscode->hide(); passcode_poweron->setEnabled(FALSE); phonesec->setLockType(pinSelection->currentItem());#else bool empty = passcode.isEmpty(); changepasscode->setText( empty ? tr("Set code" ) : tr("Change code" ) ); passcode_poweron->setEnabled( !empty ); clearpasscode->setEnabled( !empty );#endif}void Security::markProtected(bool b){#ifdef QTOPIA_PHONE ContextKeyManager::instance()->setClassStandardLabel("PasswordDialog", Key_Back, ContextBar::Back, ContextBar::ModalAndNonModal); passcode_poweron->setEnabled(FALSE); QString p; if (pinSelection->currentItem() == 0) { p = enterPassCode(tr("Enter SIM PIN"), FALSE); } else { p = enterPassCode(tr("Enter Phone PIN"), FALSE); } if (!p.isNull()) phonesec->markProtected(pinSelection->currentItem(), b, p);#else Q_UNUSED(b);#endif}void Security::show(){ valid=FALSE; setEnabled(FALSE); SecurityBase::show();#ifndef QTOPIA_PHONE if ( passcode.isEmpty() ) { // could insist... //changePassCode(); //if ( passcode.isEmpty() ) //reject(); } else if ( timeout.isNull() || timeout.elapsed() > 2000 ) { // Insist on re-entry of passcode if more than 2 seconds have elapsed. /* ContextKeyManager::instance()->setClassStandardLabel("PasswordDialog", Key_Back, ContextBar::Next, ContextBar::ModalAndNonModal); */ QString pc = enterPassCode(tr("Enter Security passcode")); if ( pc != passcode ) { QMessageBox::critical(this, tr("Passcode incorrect"), tr("<qt>The passcode entered is incorrect. Access denied</qt>"));// reject(); qApp->quit(); return; } timeout.start(); }#endif setEnabled(TRUE); valid=TRUE;}#ifdef QTOPIA_PHONEbool Security::close(bool b){ applySecurity(); return QWidget::close(b);}#elsevoid Security::accept(){ applySecurity(); QDialog::accept();}void Security::done(int r){ QDialog::done(r); close();}#endifvoid Security::selectNet(int auth_peer,int auth_peer_bits){ QString sn; if ( auth_peer_bits == 0 && auth_peer == 0 ) { sn = tr("Any"); } else if ( auth_peer_bits == 32 && auth_peer == 0 ) { sn = tr("None"); } else { sn = QString::number((auth_peer>>24)&0xff) + "." + QString::number((auth_peer>>16)&0xff) + "." + QString::number((auth_peer>>8)&0xff) + "." + QString::number((auth_peer>>0)&0xff) + "/" + QString::number(auth_peer_bits); } for (int i=0; i<syncnet->count(); i++) { if ( sn == syncnet->text(i) || syncnet->text(i).left(sn.length()+1) == sn+" " ) { syncnet->setCurrentItem(i); return; } } syncnet->insertItem(sn); syncnet->setCurrentItem(syncnet->count()-1);}bool Security::parseNet(const QString& sn,int& auth_peer,int& auth_peer_bits){ auth_peer=0; if ( sn == tr("Any") ) { auth_peer = 0; auth_peer_bits = 0; return TRUE; } else if ( sn == tr("None") ) { auth_peer = 0; auth_peer_bits = 32; return TRUE; } else { QString a; int sl = sn.find('/'); if ( sl < 0 ) { auth_peer_bits = 32; a = sn; } else { int n=(uint)sn.find(' ',sl); if ( n>sl ) n-=sl; auth_peer_bits = sn.mid(sl+1,(uint)n).toInt(); a = sn.left(sl); } QStringList b=QStringList::split(QChar('.'),a); if ( b.count() != 4 ) return FALSE; int x=1<<24; auth_peer = 0; for (QStringList::ConstIterator it=b.begin(); it!=b.end(); ++it) { auth_peer += (*it).toInt()*x; x >>= 8; } return x!=0 && auth_peer_bits && auth_peer; }}void Security::setSyncNet(const QString& sn){ int auth_peer,auth_peer_bits; if ( parseNet(sn,auth_peer,auth_peer_bits) ) selectNet(auth_peer,auth_peer_bits);}void Security::applySecurity(){ if ( valid ) { Config cfg("Security");#ifndef QTOPIA_PHONE cfg.setGroup("Passcode"); cfg.writeEntry("passcode",passcode); cfg.writeEntry("passcode_poweron",passcode_poweron->isChecked());#endif cfg.setGroup("Sync"); int auth_peer=0; int auth_peer_bits; QString sn = syncnet->currentText(); parseNet(sn,auth_peer,auth_peer_bits); QHostAddress allowed((Q_UINT32)auth_peer); cfg.writeEntry("auth_peer",allowed.toString()); cfg.writeEntry("auth_peer_bits",auth_peer_bits); /* cfg.setGroup("Remote"); if ( telnetAvailable() ) cfg.writeEntry("allow_telnet",telnet->isChecked()); if ( sshAvailable() ) cfg.writeEntry("allow_ssh",ssh->isChecked()); // ### write ssh/telnet sys config files */ } QCopEnvelope("QPE/System", "securityChanged()");}// for the phone, it requires: once to check old, (even though in// security app already), and// twice for new. Once it has all three, you can attempt to set the sim pin,// or security pin as required.void Security::changePassCode(){#ifdef QTOPIA_PHONE QString old;#endif QString new1; QString new2; bool mismatch = FALSE; bool valid = TRUE; do {#ifdef QTOPIA_PHONE ContextKeyManager::instance()->setClassStandardLabel("PasswordDialog", Key_Back, ContextBar::Next, ContextBar::ModalAndNonModal); // should check current pin first, may not be set. if (old.isNull()) { old = enterPassCode(tr("Enter current PIN"), FALSE); // indicates dialog was canceled. if ( old.isNull() ) return; } if (mismatch) { new1 = enterPassCode(tr("Mismatch: Retry new PIN"), FALSE); } else if (!valid) { new1 = enterPassCode(tr("Invalid: Retry new PIN"), FALSE); } else { new1 = enterPassCode(tr("Enter new passcode"), FALSE); }#else if (mismatch) { new1 = enterPassCode(tr("Mismatch: Retry new code"), TRUE); } else if (!valid) { new1 = enterPassCode(tr("Invalid: Retry new code"), TRUE); } else { new1 = enterPassCode(tr("Enter new passcode"), TRUE); }#endif // indicates dialog was canceled. if ( new1.isNull() ) return; if (new1.isEmpty()) { valid = FALSE; } else {#ifdef QTOPIA_PHONE ContextKeyManager::instance()->setClassStandardLabel("PasswordDialog", Key_Back, ContextBar::Back, ContextBar::ModalAndNonModal); new2 = enterPassCode(tr("Re-enter new PIN"), FALSE);#else new2 = enterPassCode(tr("Re-enter new passcode"), TRUE);#endif if ( new2.isNull() ) return; valid = !new2.isEmpty(); mismatch = new1 != new2; } } while (mismatch || !valid);#ifdef QTOPIA_PHONE phonesec->changePassword(pinSelection->currentItem(),old,new2); if (!mStatus) mStatus = new WaitScreen(0); mStatus->showMaximized();#else passcode = new1; updateGUI();#endif}void Security::clearPassCode(){ passcode = QString::null; updateGUI();}QString Security::enterPassCode(const QString& prompt, bool encrypt){ // magic to stop it crypting. if (encrypt) return Password::getPassword(prompt); else return Password::getPassword("@:" + prompt); // Magic, No tr.}bool Security::telnetAvailable() const{ // ### not implemented return FALSE;}bool Security::sshAvailable() const{ // ### not implemented return FALSE;}#include "security.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -