From ec11f6748540259d1a5f0a0e484a96f7618aec58 Mon Sep 17 00:00:00 2001 From: konrad Date: Wed, 12 Sep 2007 17:02:07 +0000 Subject: [PATCH] a bit nearer to working login git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@21 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- src/keygen.cpp | 154 ++++++++++++++++++++++++++++++--------------- src/keygen.h | 23 +++++-- src/main.cpp | 52 +++++++++++++-- src/mainwindow.cpp | 176 +++++++++++++++++++++++++++++++++++++++++++++++---- src/mainwindow.h | 29 ++++++++- src/smoke.pro | 4 +- src/smoke_de.ts | 78 ++++++++++++++++++++--- src/smoke_de_SAX.ts | 81 ++++++++++++++++++++---- www/machine.php | 10 ++- 9 files changed, 502 insertions(+), 105 deletions(-) diff --git a/src/keygen.cpp b/src/keygen.cpp index 96ee99a..dd8910d 100644 --- a/src/keygen.cpp +++ b/src/keygen.cpp @@ -21,6 +21,10 @@ #include #include #include +#include +#include + +#include "hmac.h" //enable linux to read /dev/random #ifdef __linux__ @@ -31,13 +35,15 @@ //amount of random bits needed: #define RANDNEED 160 +static QPointerefilter; + MKeyGen::MKeyGen() { setWindowTitle(tr("Magic Smoke Key Generator")); //pre-init random buffer randstat=-1; - randent=0; + connect(efilter,SIGNAL(moreBits()),this,SLOT(updateProps())); //make sure all mouse events arrive setMouseTracking(true); QVBoxLayout*vl; @@ -48,7 +54,7 @@ MKeyGen::MKeyGen() lab->setWordWrap(true); lab->setMouseTracking(true); //buffer display - vl->addWidget(randlab=new QLabel(tr("Current random buffer: %1 Bits").arg(randent)),0); + vl->addWidget(randlab=new QLabel(tr("Current random buffer: %1 Bits").arg(efilter->entropy())),0); randlab->setMouseTracking(true); randlab->setFrameShape(QFrame::Box); randlab->setAutoFillBackground(true); @@ -64,6 +70,59 @@ MKeyGen::MKeyGen() hl->addWidget(ccbtn=new QPushButton(tr("&Cancel")),0); connect(ccbtn,SIGNAL(clicked()),this,SLOT(reject())); + //make sure widgets look right + updateProps(); + + //make window really big + showMaximized(); +} + +MKeyGen::~MKeyGen() +{ +} + +void MKeyGen::updateProps() +{ + randlab->setText(tr("Current random buffer: %1 Bits").arg(efilter->entropy())); + if(efilter->entropy()palette(); + pal.setColor(QPalette::Window,QColor("#ff8080")); + randlab->setPalette(pal); + //set button + okbtn->setEnabled(false); + }else{ + //check whether we need to set it + if(randstat==1)return; + randstat=1; + //set label color + QPalette pal=randlab->palette(); + pal.setColor(QPalette::Window,QColor("#80ff80")); + randlab->setPalette(pal); + //set button + okbtn->setEnabled(true); + } +} + +QString MKeyGen::getKey() +{ + if(efilter->entropy()getRandom(40).toHex(); +} + + +EFilter::EFilter() +{ + efilter=this; + randctr=0; + //preload seed + QSettings set; + randbuf.append(set.value("randomseed").toByteArray()); + randent=randbuf.size(); + if(randent>=RANDNEED)set.setValue("randomseed",getRandom(RANDNEED)); //if Linux: try to pre-load some random #ifdef __linux__ int fd=::open("/dev/random",O_RDONLY|O_NONBLOCK); @@ -72,20 +131,44 @@ MKeyGen::MKeyGen() int rd=::read(fd,buf,sizeof(buf)); if(rd>0){ randbuf.append(QByteArray(buf,rd)); - randent=rd*8; + randent+=rd*8; } ::close(fd); } #endif +} - //make sure widgets look right - updateProps(); - - //make window really big - showMaximized(); +EFilter::~EFilter() +{ + QSettings set; + set.setValue("randomseed",getRandom(RANDNEED)); +} + +EFilter* EFilter::instance() +{ + return efilter; +} + +QByteArray EFilter::getRandom(int bytes) +{ + QByteArray ret; + while(ret.size()type()){ @@ -106,10 +189,10 @@ bool MKeyGen::event(QEvent*e) //ignore break; } - return QDialog::event(e); + return false; } -void MKeyGen::addBit(int b) +void EFilter::addBit(int b) { //add bit to buffer randbuf.append((b>>24)&0xff); @@ -127,46 +210,17 @@ void MKeyGen::addBit(int b) randbuf.append(t&0xff); randent++; } - //update display - updateProps(); - randlab->setText(tr("Current random buffer: %1 Bits").arg(randent)); -} - -void MKeyGen::updateProps() -{ - if(randentpalette(); - pal.setColor(QPalette::Window,QColor("#ff8080")); - randlab->setPalette(pal); - //set button - okbtn->setEnabled(false); - }else{ - //check whether we need to set it - if(randstat==1)return; - randstat=1; - //set label color - QPalette pal=randlab->palette(); - pal.setColor(QPalette::Window,QColor("#80ff80")); - randlab->setPalette(pal); - //set button - okbtn->setEnabled(true); + //pack buffer if necessary (>10kB) + if(randbuf.size()>=10240){ + randbuf=getRandom(80); + if(randent>320)randent=320; } + //update display + emit moreBits(); } -QString MKeyGen::getKey() -{ - if(randenttype()==QEvent::KeyPress) - qDebug("key"); - return false; + if(efilter.isNull())return QByteArray(); + return efilter->getRandom(num); } diff --git a/src/keygen.h b/src/keygen.h index 17c8733..1efc408 100644 --- a/src/keygen.h +++ b/src/keygen.h @@ -28,25 +28,38 @@ class MKeyGen:public QDialog QString getKey(); - protected: - bool event(QEvent*); private: - QByteArray randbuf; - int randent; QLabel*randlab; int randstat; QPushButton *okbtn,*ccbtn; - void addBit(int); + private slots: void updateProps(); }; class EFilter:public QObject { Q_OBJECT + public: + EFilter(); + ~EFilter(); + + static EFilter*instance(); + + int entropy(); + QByteArray getRandom(int); + signals: + void moreBits(); protected: bool eventFilter(QObject*,QEvent*); + private: + QByteArray randbuf,randlast; + int randent,randctr; + void addBit(int); }; +//shortcut: +QByteArray getRandom(int); + #endif diff --git a/src/main.cpp b/src/main.cpp index 9edd26b..455e1b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "keygen.h" #include "mainwindow.h" @@ -23,18 +25,39 @@ int main(int argc,char**argv) { + //create global app QApplication app(argc,argv); - EFilter ef; - app.installEventFilter(&ef); - + //locate settings app.setOrganizationName("MagicSmoke"); app.setApplicationName("MagicSmoke"); - //try to find appropriate locale - QString lang=QSettings().value("lang","C").toString(); - if(lang=="C")lang=QLocale::system().name(); + //install event filter for random generator + EFilter ef; + app.installEventFilter(&ef); + //try to find appropriate locale + QString lang=QSettings().value("lang","--").toString(); + if(lang=="--"){ + lang=QLocale::system().name(); + int cur=0; + QStringList langs; + langs<<"C - default"; + QStringList files=QDir(app.applicationDirPath()).entryList(QStringList()<<"smoke_*.qm", QDir::Files, QDir::Name); + for(int i=0;i #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include MMainWindow::MMainWindow() { + setWindowTitle("Magic Smoke"); + //create Menu Bar QMenuBar*mb=menuBar(); QMenu*m=mb->addMenu("&File"); m->addAction("&Test",this,SLOT(testrequest())); m->addSeparator(); m->addAction("&Close Session",this,SLOT(close())); + + //create central stack + setCentralWidget(main=new QStackedWidget); + + //create login widget + main->addWidget(loginwidget=new QWidget); + QGridLayout*gl; + loginwidget->setLayout(gl=new QGridLayout); + QLabel*lab; + int lctr=0; + gl->addWidget(lab=new QLabel(tr("Profile:")),lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(profiles=new QComboBox,lctr,1); + connect(profiles,SIGNAL(currentIndexChanged(int)),this,SLOT(loadProfile())); + gl->addWidget(usealterhost=new QCheckBox(tr("Alternate Hostname:")),++lctr,0); + gl->addWidget(alterhostname=new QLineEdit,lctr,1); + connect(usealterhost,SIGNAL(toggled(bool)),alterhostname,SLOT(setEnabled(bool))); + gl->addWidget(lab=new QLabel(tr("Server URL:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(serverurl=new QLineEdit,lctr,1); + gl->addWidget(useproxy=new QCheckBox(tr("Proxy:")),++lctr,0); + QHBoxLayout*hl; + gl->addLayout(hl=new QHBoxLayout,lctr,1); + hl->addWidget(proxyname=new QLineEdit,1); + hl->addWidget(new QLabel(":"),0); + hl->addWidget(proxyport=new QSpinBox,0); + proxyport->setRange(1,65535); + connect(useproxy,SIGNAL(toggled(bool)),proxyname,SLOT(setEnabled(bool))); + connect(useproxy,SIGNAL(toggled(bool)),proxyport,SLOT(setEnabled(bool))); + QFrame*frm; + gl->addWidget(frm=new QFrame,++lctr,0,1,2); + frm->setFrameShape(QFrame::HLine); + gl->addWidget(lab=new QLabel(tr("Username:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(username=new QLineEdit,lctr,1); + gl->addWidget(lab=new QLabel(tr("Password:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(password=new QLineEdit,lctr,1); + password->setEchoMode(QLineEdit::Password); + gl->setRowStretch(++lctr,10); + gl->addLayout(hl=new QHBoxLayout,++lctr,0,1,2); + QPushButton*p; + hl->addWidget(p=new QPushButton("new Profile"),0); + connect(p,SIGNAL(clicked()),this,SLOT(newProfile())); + hl->addStretch(10); + hl->addWidget(p=new QPushButton("Login"),0); + connect(p,SIGNAL(clicked()),this,SLOT(saveProfile())); + connect(p,SIGNAL(clicked()),this,SLOT(startLogin())); + hl->addWidget(p=new QPushButton("Exit"),0); + connect(p,SIGNAL(clicked()),this,SLOT(close())); + initProfiles(); + loadProfile(); + + //make login the default + mb->setEnabled(false); + main->setCurrentWidget(loginwidget); } -void MMainWindow::testrequest() +void MMainWindow::initProfiles() +{ + QSettings set; + set.beginGroup("profiles"); + QStringList prf=set.childGroups(); + profiles->clear(); + for(int i=0;iaddItem(set.value(prf[i]+"/name").toString(),prf[i]); + } +} + +void MMainWindow::loadProfile() +{ + QString key=profiles->itemData(profiles->currentIndex()).toString(); + QSettings set; + set.beginGroup("profiles/"+key); + usealterhost->setChecked(set.value("usealternatehost",false).toBool()); + alterhostname->setText(set.value("alternatehostname").toString()); + alterhostname->setEnabled(usealterhost->isChecked()); + serverurl->setText(set.value("serverurl","http://my.host.com/path/machine.php").toString()); + useproxy->setChecked(set.value("useproxy",false).toBool()); + proxyname->setText(set.value("proxyname","proxy").toString()); + proxyport->setValue(set.value("proxyport",74).toInt()); + proxyname->setEnabled(useproxy->isChecked()); + proxyport->setEnabled(useproxy->isChecked()); + username->setText(set.value("username").toString()); + password->setText(""); +} + +void MMainWindow::saveProfile() +{ + QString key=profiles->itemData(profiles->currentIndex()).toString(); + QSettings set; + set.beginGroup("profiles/"+key); + set.setValue("usealternatehost",usealterhost->isChecked()); + set.setValue("alternatehostname",alterhostname->text()); + set.setValue("serverurl",serverurl->text()); + set.setValue("useproxy",useproxy->isChecked()); + set.setValue("proxyname",proxyname->text()); + set.setValue("proxyport",proxyport->value()); + set.setValue("username",username->text()); +} + +void MMainWindow::newProfile() +{ + //scan for existing ones... + QSettings set; + set.beginGroup("profiles"); + QStringList prf=set.childGroups(); + QStringList prn; + for(int i=0;iaddItem(pname,pidx); + profiles->setCurrentIndex(profiles->count()-1); +} + +void MMainWindow::startLogin() +{ + //make it impossible for the user to interfere + setEnabled(false); + //start request + startRequest("startsession",getRandom(32).toHex(),SLOT(loginStage2(int,bool))); +} + +void MMainWindow::startRequest(QString hreq,QByteArray data,char*myslot) { req=new QHttp("localhost"); - connect(req,SIGNAL(requestFinished(int,bool)),this,SLOT(trfin(int,bool))); + connect(req,SIGNAL(requestFinished(int,bool)),this,myslot); QHttpRequestHeader hrh("POST","/~konrad/smoke/machine.php"); hrh.setValue("Host","localhost"); - hrh.setValue("X-MagicSmoke-Request","testdueluEhue"); - QByteArray tdata("blah\nschwafel\r\nseier"); - hrh.setContentLength(tdata.size()); - hrh.setContentType("text/x-magicsmoke"); + hrh.setValue("X-MagicSmoke-Request",hreq); + hrh.setValue("X-MagicSmoke-Session",sessionid); + hrh.setContentLength(data.size()); + hrh.setContentType("application/x-magicsmoke"); qDebug("Requesting data with:\n%s",hrh.toString().toAscii().data()); - req->request(hrh,tdata); + req->request(hrh,data); } -void MMainWindow::trfin(int id,bool err) +void MMainWindow::loginStage2(int id,bool err) { qDebug("Received Request finish for ID=%i Status=%s",id,err?"Error":"Ok"); if(err){ @@ -50,9 +202,9 @@ void MMainWindow::trfin(int id,bool err) QHttpResponseHeader hrh=req->lastResponse(); QByteArray data=req->readAll(); qDebug("HTTP Response Headers:\n%s",hrh.toString().toAscii().data()); - QFile fd("rsp"+QString::number(id)+".html"); - fd.open(QIODevice::WriteOnly); - fd.write(data); - fd.close(); + qDebug("HTTP Response Body:\n%s\n<-->",data.data()); } + req->disconnect(); + req->deleteLater(); + setEnabled(true); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 8f187f4..272f605 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -14,19 +14,42 @@ #define MAGICSMOKE_MAINWINDOW_H #include +#include +#include class QHttp; +class QStackedWidget; +class QComboBox; +class QLineEdit; +class QCheckBox; +class QSpinBox; class MMainWindow:public QMainWindow { Q_OBJECT public: MMainWindow(); - public slots: - void testrequest(); - void trfin(int,bool); private: QHttp*req; + QString sessionid; + QStackedWidget*main; + QWidget*loginwidget; + QCheckBox*usealterhost,*useproxy; + QLineEdit*alterhostname,*serverurl,*proxyname,*username,*password; + QSpinBox*proxyport; + QComboBox*profiles; + + private slots: + //handling of login/profile screen + void initProfiles(); + void loadProfile(); + void saveProfile(); + void newProfile(); + void startLogin(); + void loginStage2(int,bool); + + //request handling + void startRequest(QString,QByteArray,char*); }; #endif diff --git a/src/smoke.pro b/src/smoke.pro index 41e2f34..6fbdb6e 100644 --- a/src/smoke.pro +++ b/src/smoke.pro @@ -2,8 +2,8 @@ TEMPLATE = app TARGET = msmoke #build for debug or release? -CONFIG += release -#CONFIG += debug +#CONFIG += release +CONFIG += debug CONFIG += qt thread QT += xml network diff --git a/src/smoke_de.ts b/src/smoke_de.ts index c2c30a8..487dcf5 100644 --- a/src/smoke_de.ts +++ b/src/smoke_de.ts @@ -3,61 +3,119 @@ MKeyGen - + Current random buffer: %1 Bits Aktueller Zufallspuffer: %1 Bits - + Magic Smoke Key Generator Magic Smoke Schlüsselgenerator - + <html><h1>Key Generation</h1> I am currently collecting random bits in order to generate a host key for this installation. Please use mouse and keyboard to generate more random. Alternatively you can load a key from an external medium.<p> At least %1 Bits of random are required. <html><h1>Schlüsselgenerierung</h1>Das Programm sammelt gerade Zufallsbits für diese Installation. Bitte benutzen Sie Maus und Tastatur, um mehr Zufall zu generieren. Alternativ können Sie auch einen fertigen Schlüssel von einem externen Medium laden.<p>Mindestens %1 Zufallsbits werden gebraucht. - + &OK &Ok - + &Cancel &Abbrechen + MMainWindow + + + Profile: + + + + + Alternate Hostname: + + + + + Server URL: + + + + + Proxy: + + + + + Username: + + + + + Password: + + + + + New Profile + + + + + Please enter a profile name. It must be non-empty and must not be used yet: + + + + initkey - + Warning - + Magic Smoke needs a host key. You have to generate one before you can use the program. + + + Enter Host Name + + + + + Host name: + + + + + Magic Smoke needs a host name. You have to configure one before you can use the program. + + initprofile - + default initial profile - + Create Initial Profile - + You need a profile to work with Magic Smoke. Magic Smoke will now create one for you. Please enter the name you wish to give this profile. diff --git a/src/smoke_de_SAX.ts b/src/smoke_de_SAX.ts index b7a2704..441d295 100644 --- a/src/smoke_de_SAX.ts +++ b/src/smoke_de_SAX.ts @@ -1,64 +1,121 @@ - MKeyGen - + Current random buffer: %1 Bits Aktueller Füllschdand vom dem Zufallsbuffer: %1 Bids - + Magic Smoke Key Generator Mädschig Schmohg Schlüsselgenerador - + <html><h1>Key Generation</h1> I am currently collecting random bits in order to generate a host key for this installation. Please use mouse and keyboard to generate more random. Alternatively you can load a key from an external medium.<p> At least %1 Bits of random are required. <html><h1>Schlüsselgenerierung</h1>Das Brogramm sammeld grade Zufallsbids für diese Inschdalladsion. <br>Das iss im Grunde ne' ganz eefache Sache. Basse off: Du waggelsd ä bissl an dor Maus und hämmerst wie ä Beglobbder off de Dasdadur. Dann wenn's Brogramm genug Zufall had wird de rode Leisde unden grün. Das heesd Du gannst offhörn und Disch wiedor wie'n normaler Mensch benehm'.Wenn Dir das nich bassd gannsde och jemand andres den Schrodd machn' lassn' und 'ne Schlüsseldadei laden.<p>Mindeschdens %1 Zufallsbids brauchsde. Geene Sorsche das gehd fix. - + &OK Nu &glar! Nehm'sch. - + &Cancel &Nee lass mal. + MMainWindow + + + Profile: + + + + + Alternate Hostname: + + + + + Server URL: + + + + + Proxy: + + + + + Username: + + + + + Password: + + + + + New Profile + + + + + Please enter a profile name. It must be non-empty and must not be used yet: + + + + initkey - + Warning Dumm gelaufen - + Magic Smoke needs a host key. You have to generate one before you can use the program. Mädschig Schmohg brauchd 'nen Schlüssel. Desweschen isser beleidschd. Beim nächsden Schdard mussde ihn einen mach'n lass'n. + + + Enter Host Name + Gombjudername eingäbn + + + + Host name: + Gombjudername: + + + + Magic Smoke needs a host name. You have to configure one before you can use the program. + Mädschig Schmohg brauchd 'nen Namen für diesen Gombjuder. Desweschen isser beleidschd. Beim nächsden Schdard mussde ihn eingäben. + initprofile - + default initial profile - Schandardbrofiel + Schdandardbrofiel - + Create Initial Profile Erschdes Brofiel anlechen - + You need a profile to work with Magic Smoke. Magic Smoke will now create one for you. Please enter the name you wish to give this profile. Gugge, Du brauchsd sowas wie'n Brofiel. Mädschig Schmohg iss nedd und machd eens für Disch. Desderweschen brauchsde jedsd nur noch n Namen dafür eindibben. diff --git a/www/machine.php b/www/machine.php index f94ba95..5dbf19d 100644 --- a/www/machine.php +++ b/www/machine.php @@ -15,7 +15,7 @@ $ALLOWEDREQUESTS=array( ); $SMOKEREQUEST=strtolower($_SERVER["HTTP_X_MAGICSMOKE_REQUEST"]); if(!in_array($SMOKEREQUEST,$ALLOWEDREQUESTS)){ - header("X-MagicSmoke-Status","InvalidRequest"); + header("X-MagicSmoke-Status: InvalidRequest"); exit(); } $REQUESTDATA=""; @@ -28,7 +28,7 @@ include("loader.php"); // server info can be answered without performing any more initialization if($SMOKEREQUEST=="serverinfo"){ - header("X-MagicSmoke-Status","Ok"); + header("X-MagicSmoke-Status: Ok"); print("\n $MAGICSMOKEVERSION$ClientAuthAlgo\n"); exit(); } @@ -42,12 +42,13 @@ include("inc/session.php"); // request to start a session if($SMOKEREQUEST=="startsession"){ //TODO: start session + echo "blah session"; exit(); } //request to close a session if($SMOKEREQUEST=="closesession"){ //TODO: close session - header("X-MagicSmoke-Status","Ok"); + header("X-MagicSmoke-Status: Ok"); exit(); } @@ -57,5 +58,6 @@ if($SMOKEREQUEST=="closesession"){ //request session authentication - +//EOF +die("Internal Error"); ?> \ No newline at end of file -- 1.7.2.5