1 /*-
2 * Copyright (c) 2018 Marcel Kaiser. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include <QDesktopWidget>
26 #include <QTextCodec>
27 #include <QScreen>
28 #include <iostream>
29
30 #include "mainwin.h"
31 #include "qt-helper/qt-helper.h"
32
MainWin(const char * msg,const char * usr,const char * cmd,QWidget * parent)33 MainWin::MainWin(const char *msg, const char *usr, const char *cmd,
34 QWidget *parent) : QMainWindow(parent) {
35 this->cmd = cmd;
36 this->usr = usr;
37
38 QString pstring = QString(tr("Please enter the password for " \
39 "user %1"));
40 QString ustr = QString(usr == 0 ? "root" : usr);
41 QString prompt = pstring.arg(ustr);
42 QIcon okIcon = qh_loadStockIcon(QStyle::SP_DialogOkButton, 0);
43 QIcon cancelIcon = qh_loadStockIcon(QStyle::SP_DialogCancelButton,
44 NULL);
45 QIcon pic = qh_loadIcon("dialog-password", NULL);
46 pwdField = new QLineEdit(this);
47 statusMsg = new QLabel(this);
48 statusBar = new QStatusBar(this);
49 QLabel *icon = new QLabel(this);
50 QLabel *text;
51 QLabel *label = new QLabel(prompt);
52 QPushButton *ok = new QPushButton(okIcon, tr("&Ok"));
53 QPushButton *cancel = new QPushButton(cancelIcon, tr("&Cancel"));
54 QVBoxLayout *vbox = new QVBoxLayout;
55 QHBoxLayout *bbox = new QHBoxLayout;
56 QHBoxLayout *hbox = new QHBoxLayout;
57 QWidget *container = new QWidget(this);
58
59 if (msg == 0 || *msg == '\0') {
60 text = new QLabel(QString(tr("Execute '%1' as user %2\n")
61 .arg(QString(cmd)).arg(ustr)));
62 } else
63 text = new QLabel(QString(msg).append("\n"));
64 icon->setPixmap(pic.pixmap(64));
65 text->setWordWrap(true);
66 pwdField->setEchoMode(QLineEdit::Password);
67 label->setStyleSheet("font-weight: bold;");
68 ok->setDefault(true);
69 cancel->setDefault(true);
70
71 bbox->addWidget(ok, 1, Qt::AlignRight);
72 bbox->addWidget(cancel, 0, Qt::AlignRight);
73
74 hbox->addWidget(icon, 0, Qt::AlignLeft);
75 hbox->addWidget(text, 1, Qt::AlignJustify);
76 vbox->addLayout(hbox);
77 vbox->addWidget(label, 1, Qt::AlignLeft);
78
79 vbox->addWidget(pwdField);
80 vbox->addWidget(statusMsg);
81 vbox->addLayout(bbox);
82 container->setLayout(vbox);
83 setCentralWidget(container);
84
85 setMinimumWidth(500);
86 setMaximumWidth(500);
87 setWindowIcon(pic);
88 setWindowTitle("DSBSu");
89 show();
90 setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,
91 size(), qApp->primaryScreen()->geometry()));
92 connect(ok, SIGNAL(clicked()), this, SLOT(callBackend()));
93 connect(pwdField, SIGNAL(returnPressed()), this, SLOT(callBackend()));
94 connect(cancel, SIGNAL(clicked()), this, SLOT(cbCancel()));
95 connect(pwdField, SIGNAL(textChanged(const QString &)), this,
96 SLOT(resetStatusBar(const QString &)));
97 }
98
MainWin(const char * cmd,const char * usr,QWidget * parent)99 MainWin::MainWin(const char *cmd, const char *usr, QWidget *parent)
100 : QMainWindow(parent) {
101 this->usr = usr;
102
103 QString pstring = QString(tr("Please enter the password for " \
104 "user %1"));
105 QString ustr = QString(usr == 0 ? "root" : usr);
106 QString prompt = pstring.arg(ustr);
107 QIcon okIcon = qh_loadStockIcon(QStyle::SP_DialogOkButton, 0);
108 QIcon cancelIcon = qh_loadStockIcon(QStyle::SP_DialogCancelButton,
109 NULL);
110 QIcon pic = qh_loadIcon("dialog-password", NULL);
111 pwdField = new QLineEdit(this);
112 statusMsg = new QLabel(this);
113 statusBar = new QStatusBar(this);
114 QLabel *icon = new QLabel(this);
115 QLabel *text;
116 QLabel *label = new QLabel(prompt);
117 QPushButton *ok = new QPushButton(okIcon, tr("&Ok"));
118 QPushButton *cancel = new QPushButton(cancelIcon, tr("&Cancel"));
119 QVBoxLayout *vbox = new QVBoxLayout;
120 QHBoxLayout *bbox = new QHBoxLayout;
121 QHBoxLayout *hbox = new QHBoxLayout;
122 QWidget *container = new QWidget(this);
123
124 text = new QLabel(tr("<qt>The command \"<tt>%1</tt>\" " \
125 "requires authentication\n</qt>").arg(cmd));
126 icon->setPixmap(pic.pixmap(64));
127 pwdField->setEchoMode(QLineEdit::Password);
128 label->setStyleSheet("font-weight: bold;");
129 ok->setDefault(true);
130 cancel->setDefault(true);
131
132 bbox->addWidget(ok, 1, Qt::AlignRight);
133 bbox->addWidget(cancel, 0, Qt::AlignRight);
134
135 hbox->addWidget(icon, 0, Qt::AlignLeft);
136 hbox->addWidget(text, 1, Qt::AlignLeft);
137 vbox->addLayout(hbox);
138 vbox->addWidget(label, 1, Qt::AlignLeft);
139
140 vbox->addWidget(pwdField);
141 vbox->addWidget(statusMsg);
142 vbox->addLayout(bbox);
143 container->setLayout(vbox);
144 setCentralWidget(container);
145
146 setMinimumWidth(500);
147 setWindowIcon(pic);
148 setWindowTitle("DSBSu");
149 show();
150 setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,
151 size(), qApp->primaryScreen()->geometry()));
152 connect(ok, SIGNAL(clicked()), this, SLOT(printPwd()));
153 connect(pwdField, SIGNAL(returnPressed()), this, SLOT(printPwd()));
154 connect(cancel, SIGNAL(clicked()), this, SLOT(cbCancel()));
155 connect(pwdField, SIGNAL(textChanged(const QString &)), this,
156 SLOT(resetStatusBar(const QString &)));
157 }
158
159 void
printPwd()160 MainWin::printPwd()
161 {
162 QTextCodec *codec = QTextCodec::codecForLocale();
163 QByteArray encstr = codec->fromUnicode(pwdField->text());
164
165 std::cout << encstr.data() << std::endl;
166 QCoreApplication::exit(0);
167 }
168
169 void
resetStatusBar(const QString &)170 MainWin::resetStatusBar(const QString & /*unused*/)
171 {
172 statusMsg->setText("");
173 }
174
175 void
callBackend()176 MainWin::callBackend()
177 {
178 QTextCodec *codec = QTextCodec::codecForLocale();
179 QByteArray encstr = codec->fromUnicode(pwdField->text());
180
181 if ((proc = dsbsu_exec_su(cmd, usr, encstr.data())) == NULL) {
182 if (dsbsu_error() == DSBSU_EAUTH) {
183 pwdField->clear();
184 statusMsg->setText(tr("Wrong password"));
185 } else {
186 close();
187 QCoreApplication::exit(1);
188 }
189 } else {
190 close();
191 QCoreApplication::exit(0);
192 }
193 }
194
195 void
cbCancel()196 MainWin::cbCancel()
197 {
198 QCoreApplication::exit(-1);
199 }
200
closeEvent(QCloseEvent *)201 void MainWin::closeEvent(QCloseEvent * /* unused */)
202 {
203 QCoreApplication::exit(-1);
204 }
205
206