-rw-r--r-- | noncore/settings/sshkeys/main.cpp | 16 | ||||
-rw-r--r-- | noncore/settings/sshkeys/sshkeys.cpp | 191 | ||||
-rw-r--r-- | noncore/settings/sshkeys/sshkeys.h | 14 | ||||
-rw-r--r-- | noncore/settings/sshkeys/sshkeysbase.ui | 87 |
4 files changed, 272 insertions, 36 deletions
diff --git a/noncore/settings/sshkeys/main.cpp b/noncore/settings/sshkeys/main.cpp index 37be8bf..a7b1d56 100644 --- a/noncore/settings/sshkeys/main.cpp +++ b/noncore/settings/sshkeys/main.cpp @@ -1,14 +1,30 @@ #include <qpe/qpeapplication.h> #include "sshkeys.h" +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <unistd.h> + int main(int argc, char *argv[]) { QPEApplication a(argc, argv); SSHKeysApp app; + int fd; + + /* If we had a controlling TTY, detach from it. + This is to ensure the SSH uses ssh-askpass */ + fd = open("/dev/tty", O_RDONLY); + if (fd != -1) { + ioctl(fd, TIOCNOTTY, NULL); + close(fd); + } a.showMainWidget(&app); return a.exec(); } diff --git a/noncore/settings/sshkeys/sshkeys.cpp b/noncore/settings/sshkeys/sshkeys.cpp index 08ce18d..5095d16 100644 --- a/noncore/settings/sshkeys/sshkeys.cpp +++ b/noncore/settings/sshkeys/sshkeys.cpp @@ -1,58 +1,227 @@ #include "sshkeys.h" #include <qpe/qpeapplication.h> #include <opie/oprocess.h> #include <qmultilineedit.h> #include <qpushbutton.h> -#include <qtable.h> +#include <qlistview.h> +#include <qcombobox.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <ctype.h> + +static char *keynames[] = { "identity", "id_rsa", "id_dsa" }; SSHKeysApp::SSHKeysApp( QWidget* parent, const char* name, WFlags fl ) : SSHKeysBase( parent, name, fl ) { + char *home = getenv("HOME"); + unsigned i; connect(AddButton, SIGNAL(clicked()), this, SLOT(doAddButton())); connect(RefreshListButton, SIGNAL(clicked()), this, SLOT(doRefreshListButton())); connect(RemoveAllButton, SIGNAL(clicked()), this, SLOT(doRemoveAllButton())); - KeyList->horizontalHeader()->setLabel(0, tr("Key")); - KeyList->horizontalHeader()->setLabel(1, tr("Size")); - KeyList->horizontalHeader()->setLabel(2, tr("Fingerprint")); + connect(&addprocess, SIGNAL(receivedStdout(OProcess*,char*,int)), + this, SLOT(log_sshadd_output(OProcess*,char*,int))); + connect(&addprocess, SIGNAL(processExited(OProcess*)), + this, SLOT(ssh_add_exited(OProcess*))); + + connect(KeyFileName, SIGNAL(textChanged(const QString&)), + this, SLOT(add_text_changed(const QString&))); + + if (home) { + for (i = 0; i < sizeof(keynames)/sizeof(keynames[0]); i++) { + char thiskeyname[32]; + + thiskeyname[31] = 0; + snprintf(thiskeyname, 31, "%s/.ssh/%s", home, keynames[i]); + if (!access(thiskeyname, R_OK)) { + KeyFileName->insertItem(thiskeyname); + } + } + } doRefreshListButton(); } SSHKeysApp::~SSHKeysApp() { } void SSHKeysApp::doRefreshListButton() { OProcess sshadd_process; + QListViewItem *t = KeyList->firstChild(); + + while(t) { + QListViewItem *next = t->nextSibling(); + KeyList->takeItem(t); + delete(t); + t = next; + } connect(&sshadd_process, SIGNAL(receivedStdout(OProcess*,char*,int)), this, SLOT(get_list_keys_output(OProcess*,char*,int))); - TextOutput->append("Running ssh-add -l\n"); + keystate = KeySize; + incoming_keyname=""; + incoming_keysize=""; + incoming_keyfingerprint=""; + +// log_text("Running ssh-add -l"); sshadd_process << "ssh-add" << "-l"; bool ret = sshadd_process.start(OProcess::Block, OProcess::AllOutput); - if (!ret) - TextOutput->append("Error running ssh-add\n"); - KeyList->setText(0, 0, "dwmw2@infradead.org (RSA v1)"); - KeyList->setText(0, 1, "1024"); - KeyList->setText(0, 2, "78:24:04:95:40:fc:b2:80:9b:94:d5:ae:19:56:19:65"); + if (!ret) { + log_text("Error running ssh-add"); + return; + } + } void SSHKeysApp::get_list_keys_output(OProcess *proc, char *buffer, int buflen) { - TextOutput->append(buffer); + int i; + (void) proc; + + for (i=0; i<buflen; i++) { + switch(keystate) { + case Noise: + noise: + if (buffer[i] == '\n') { + log_text(incoming_noise.local8Bit()); + incoming_noise = ""; + keystate = KeySize; + } else { + incoming_noise += buffer[i]; + } + break; + + case KeySize: + if (isdigit(buffer[i])) { + incoming_keysize += buffer[i]; + } else if (buffer[i] == ' ') { + keystate = KeyFingerprint; + } else { + incoming_keysize = ""; + incoming_noise = ""; + keystate = Noise; + goto noise; } + break; + case KeyFingerprint: + if (isxdigit(buffer[i]) || buffer[i] == ':') { + incoming_keyfingerprint += buffer[i]; + } else if (buffer[i] == ' ') { + keystate = KeyName; + } else { + incoming_keysize = ""; + incoming_keyfingerprint = ""; + incoming_noise = ""; + keystate = Noise; + goto noise; + } + break; + + case KeyName: + if (buffer[i] == '\n') { + /* Wheee. Got one. */ + KeyList->insertItem(new + QListViewItem(KeyList, incoming_keyname, incoming_keysize, incoming_keyfingerprint)); + incoming_keysize = ""; + incoming_keyfingerprint = ""; + incoming_keyname = ""; + keystate = KeySize; + } else if (isprint(buffer[i])) { + incoming_keyname += buffer[i]; + } else { + incoming_keysize = ""; + incoming_keyfingerprint = ""; + incoming_noise = ""; + keystate = Noise; + goto noise; + } + break; + } + } +} + +void SSHKeysApp::log_sshadd_output(OProcess *proc, char *buffer, int buflen) +{ + (void)proc; + (void)buflen; + + log_text(buffer); +} + +void SSHKeysApp::ssh_add_exited(OProcess *proc) +{ + (void)proc; + + doRefreshListButton(); + setEnabled(TRUE); + if (proc->exitStatus()) { + + log_text(QString("ssh-add failed")); + } +} + +void SSHKeysApp::add_text_changed(const QString &text) +{ + struct stat sbuf; + + if (!text.length() || (!access(text.ascii(), R_OK) && + !stat(text.ascii(), &sbuf) && + S_ISREG(sbuf.st_mode))) + AddButton->setEnabled(TRUE); + else + AddButton->setEnabled(FALSE); +} void SSHKeysApp::doAddButton() { + addprocess.clearArguments(); + + setEnabled(FALSE); + if (KeyFileName->currentText().length()) { + addprocess << "ssh-add" << "--" << KeyFileName->currentText(); + log_text(QString("Running ssh-add -- ") + KeyFileName->currentText()); + } else { + addprocess << "ssh-add"; + log_text("Running ssh-add"); } + bool ret = addprocess.start(OProcess::NotifyOnExit, OProcess::AllOutput); + if (!ret) { + log_text("Error running ssh-add"); + doRefreshListButton(); + setEnabled(TRUE); + } +} + +void SSHKeysApp::log_text(const char *text) +{ + TextOutput->append(text); + TextOutput->setCursorPosition(TextOutput->numLines()+1, 0, FALSE); +} + void SSHKeysApp::doRemoveAllButton() { + OProcess sshadd_process; + + connect(&sshadd_process, SIGNAL(receivedStdout(OProcess*,char*,int)), + this, SLOT(log_sshadd_output(OProcess*,char*,int))); + log_text("Running ssh-add -D"); + sshadd_process << "ssh-add" << "-D"; + bool ret = sshadd_process.start(OProcess::Block, OProcess::AllOutput); + if (!ret) { + log_text("Error running ssh-add"); + } + doRefreshListButton(); } diff --git a/noncore/settings/sshkeys/sshkeys.h b/noncore/settings/sshkeys/sshkeys.h index 4a9f2fe..9a39a2c 100644 --- a/noncore/settings/sshkeys/sshkeys.h +++ b/noncore/settings/sshkeys/sshkeys.h @@ -1,27 +1,35 @@ #ifndef SSHKEYSAPP_H #define SSHKEYSAPP_H #include "sshkeysbase.h" - -class OProcess; +#include <opie/oprocess.h> class SSHKeysApp : public SSHKeysBase { Q_OBJECT public: SSHKeysApp( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); ~SSHKeysApp(); private: - void sshadd(char **args); + void log_text(const char *text); + enum { Noise, KeyName, KeySize, KeyFingerprint } keystate; + QString incoming_keyname; + QString incoming_keysize; + QString incoming_keyfingerprint; + QString incoming_noise; + OProcess addprocess; private slots: void doAddButton(); void doRefreshListButton(); void doRemoveAllButton(); void get_list_keys_output(OProcess *proc, char *buffer, int buflen); + void log_sshadd_output(OProcess *proc, char *buffer, int buflen); + void ssh_add_exited(OProcess *proc); + void add_text_changed(const QString &text); }; #endif diff --git a/noncore/settings/sshkeys/sshkeysbase.ui b/noncore/settings/sshkeys/sshkeysbase.ui index dc1df28..4c9daa9 100644 --- a/noncore/settings/sshkeys/sshkeysbase.ui +++ b/noncore/settings/sshkeys/sshkeysbase.ui @@ -19,26 +19,32 @@ <name>caption</name> <string>SSH Keys</string> </property> <grid> <property stdset="1"> <name>margin</name> <number>11</number> </property> <property stdset="1"> <name>spacing</name> <number>6</number> </property> - <widget row="0" column="1" rowspan="1" colspan="2" > + <widget row="0" column="1" > <class>QComboBox</class> + <item> + <property> + <name>text</name> + <string></string> + </property> + </item> <property stdset="1"> <name>name</name> <cstring>KeyFileName</cstring> </property> <property stdset="1"> <name>sizePolicy</name> <sizepolicy> <hsizetype>7</hsizetype> <vsizetype>0</vsizetype> </sizepolicy> </property> <property stdset="1"> @@ -74,70 +80,107 @@ <name>text</name> <string>Refresh</string> </property> </widget> <widget row="1" column="1" > <class>QPushButton</class> <property stdset="1"> <name>name</name> <cstring>RemoveAllButton</cstring> </property> <property stdset="1"> <name>enabled</name> - <bool>false</bool> + <bool>true</bool> </property> <property stdset="1"> <name>text</name> <string>Clear Keys</string> </property> </widget> - <widget row="3" column="0" rowspan="1" colspan="3" > + <widget row="3" column="0" rowspan="1" colspan="2" > <class>QMultiLineEdit</class> <property stdset="1"> <name>name</name> <cstring>TextOutput</cstring> </property> <property stdset="1"> + <name>enabled</name> + <bool>true</bool> + </property> + <property stdset="1"> <name>sizePolicy</name> <sizepolicy> <hsizetype>7</hsizetype> <vsizetype>1</vsizetype> </sizepolicy> </property> <property stdset="1"> + <name>font</name> + <font> + <family>adobe-helvetica</family> + <pointsize>8</pointsize> + </font> + </property> + <property stdset="1"> <name>readOnly</name> <bool>true</bool> </property> </widget> - <widget row="2" column="0" rowspan="1" colspan="3" > - <class>QTable</class> + <widget row="2" column="0" rowspan="1" colspan="2" > + <class>QListView</class> + <column> + <property> + <name>text</name> + <string>Key Name</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> + <column> + <property> + <name>text</name> + <string>Size</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> + <column> + <property> + <name>text</name> + <string>Fingerprint</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> <property stdset="1"> <name>name</name> <cstring>KeyList</cstring> </property> <property stdset="1"> <name>font</name> <font> <family>adobe-helvetica</family> - <pointsize>9</pointsize> + <pointsize>8</pointsize> </font> </property> - <property stdset="1"> - <name>resizePolicy</name> - <enum>AutoOneFit</enum> - </property> - <property stdset="1"> - <name>numRows</name> - <number>1</number> - </property> - <property stdset="1"> - <name>numCols</name> - <number>3</number> - </property> - <property stdset="1"> - <name>showGrid</name> - <bool>false</bool> - </property> </widget> </grid> </widget> </UI> |