source: src-qt4/pc-firstbootgui/firstboot.cpp @ e9326b4

9.2-releasereleng/10.0releng/10.0.1
Last change on this file since e9326b4 was e9326b4, checked in by Kris Moore <kris@…>, 9 months ago

Add ability to encrypt users homedir when we add the first
user at system bootup

  • Property mode set to 100644
File size: 12.7 KB
Line 
1#include <QProcess>
2#include <QTimer>
3#include <QGraphicsPixmapItem>
4#include <QTemporaryFile>
5#include <QCloseEvent>
6#include <pcbsd-netif.h>
7#include <pcbsd-utils.h>
8
9#include "backend.h"
10#include "ui_firstboot.h"
11#include "firstboot.h"
12#include "helpText.h"
13
14Installer::Installer(QWidget *parent) : QMainWindow(parent)
15{
16    setupUi(this);
17    translator = new QTranslator();
18
19    connect(backButton, SIGNAL(clicked()), this, SLOT(slotBack()));
20    connect(nextButton, SIGNAL(clicked()), this, SLOT(slotNext()));
21
22    connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
23    connect(pushTouchKeyboard, SIGNAL(clicked()), this, SLOT(slotPushVirtKeyboard()));
24    connect(pushChangeKeyLayout, SIGNAL(clicked()), this, SLOT(slotPushKeyLayout()));
25
26    connect(lineRootPW, SIGNAL(textChanged ( const QString &)), this, SLOT(slotCheckRootPW()));
27    connect(lineRootPW2, SIGNAL(textChanged ( const QString &)), this, SLOT(slotCheckRootPW()));
28
29    connect(lineName,SIGNAL(textChanged(const QString)),this,SLOT(slotCheckUser()));
30    connect(lineName,SIGNAL(editingFinished()),this,SLOT(slotSuggestUsername()));
31    connect(lineUsername,SIGNAL(textChanged(const QString)),this,SLOT(slotCheckUser()));
32    connect(linePW,SIGNAL(textChanged(const QString)),this,SLOT(slotCheckUser()));
33    connect(linePW2,SIGNAL(textChanged(const QString)),this,SLOT(slotCheckUser()));
34
35    backButton->setText(tr("&Back"));
36    nextButton->setText(tr("&Next"));
37
38
39    // Load the keyboard info
40    keyModels = Scripts::Backend::keyModels();
41    keyLayouts = Scripts::Backend::keyLayouts();
42
43    // Load the timezones
44    comboBoxTimezone->clear();
45    comboBoxTimezone->addItems(Scripts::Backend::timezones());
46    // Set America/New_York to default
47    int index = comboBoxTimezone->findText("America/New_York", Qt::MatchStartsWith);
48    if (index != -1)
49       comboBoxTimezone->setCurrentIndex(index);
50
51    // Start on the first screen
52    installStackWidget->setCurrentIndex(0);
53    backButton->setVisible(false);
54}
55
56Installer::~Installer()
57{
58    //delete ui;
59}
60
61void Installer::slotSuggestUsername()
62{
63  if ( ! lineUsername->text().isEmpty() || lineName->text().isEmpty() )
64    return;
65  QString name;
66  if ( lineName->text().indexOf(" ") != -1 ) {
67    name = lineName->text().section(' ', 0, 0).toLower();
68    name.truncate(1);
69  }
70  name = name + lineName->text().section(' ', -1, -1).toLower();
71  lineUsername->setText(name);
72}
73
74void Installer::slotPushKeyLayout()
75{
76  wKey = new widgetKeyboard();
77  wKey->programInit(keyModels, keyLayouts);
78  wKey->setWindowModality(Qt::ApplicationModal);
79  connect(wKey, SIGNAL(changedLayout(QString, QString, QString)), this, SLOT(slotKeyLayoutUpdated(QString, QString, QString)));
80  wKey->show();
81  wKey->raise();
82}
83
84// Start xvkbd
85void Installer::slotPushVirtKeyboard()
86{
87   system("killall -9 xvkbd; xvkbd -compact &");
88}
89
90void Installer::initInstall()
91{
92    // load languages
93    comboLanguage->clear();
94    languages = Scripts::Backend::languages();
95    for (int i=0; i < languages.count(); ++i) {
96        QString languageStr = languages.at(i);
97        QString language = languageStr.split("-").at(0);
98        comboLanguage->addItem(language.trimmed());
99    }
100    connect(comboLanguage, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotChangeLanguage()));
101}
102
103void Installer::proceed(bool forward)
104{
105    int count = installStackWidget->count() - 1;
106    int index = installStackWidget->currentIndex();
107
108    index = forward ?
109            (index == count ? count : index + 1) :
110            (index == 0 ? 0 : index - 1);
111
112    installStackWidget->setCurrentIndex(index);
113}
114
115// Check root pw
116void Installer::slotCheckRootPW()
117{
118  nextButton->setEnabled(false);
119
120  if ( lineRootPW->text().isEmpty() )
121     return;
122  if ( lineRootPW2->text().isEmpty() )
123     return;
124  if ( lineRootPW->text() != lineRootPW2->text() )
125     return;
126  // if we get this far, all the fields are filled in
127  nextButton->setEnabled(true);
128}
129
130void Installer::slotCheckUser()
131{
132  nextButton->setEnabled(false);
133  if ( lineName->text().isEmpty() )
134     return;
135  if ( lineUsername->text().isEmpty() )
136     return;
137  if ( linePW->text().isEmpty() )
138     return;
139  if ( linePW2->text().isEmpty() )
140     return;
141  if ( linePW->text() != linePW2->text() )
142     return;
143  nextButton->setEnabled(true);
144}
145
146// Slot which is called when the Finish button is clicked
147void Installer::slotFinished()
148{
149  qApp->quit();
150}
151
152void Installer::slotNext()
153{
154   QString tmp;
155   backButton->setVisible(true);
156
157   // Check rootPW match
158   if ( installStackWidget->currentIndex() == 1)
159     slotCheckRootPW();
160   // Check user info
161   if ( installStackWidget->currentIndex() == 2)
162     slotCheckUser();
163
164   // Check if we have a wireless device
165   if ( installStackWidget->currentIndex() == 3) {
166     if ( system("ifconfig wlan0") == 0 ) {
167       haveWifi = true;
168       QTimer::singleShot(50,this,SLOT(slotScanNetwork()));
169       connect(pushButtonRescan, SIGNAL(clicked()), this, SLOT(slotScanNetwork()));
170       connect(listWidgetWifi, SIGNAL(itemPressed(QListWidgetItem *)), this, SLOT(slotAddNewWifi()));
171     } else {
172       haveWifi = false;
173     }
174   }
175
176   // If not doing a wireless connection
177   if ( installStackWidget->currentIndex() == 3 && ! haveWifi) {
178      installStackWidget->setCurrentIndex(5);
179      // Save the settings
180      saveSettings();
181      nextButton->setText(tr("&Finish"));
182      backButton->setVisible(false);
183      nextButton->disconnect();
184      connect(nextButton, SIGNAL(clicked()), this, SLOT(slotFinished()));
185      return;
186   }
187
188   // Finished screen
189   if ( installStackWidget->currentIndex() == 4 ) {
190      // Save the settings
191      saveSettings();
192      nextButton->setText(tr("&Finish"));
193      backButton->setVisible(false);
194      nextButton->disconnect();
195      connect(nextButton, SIGNAL(clicked()), this, SLOT(slotFinished()));
196   }
197
198   proceed(true);
199}
200
201void Installer::slotBack()
202{
203   nextButton->setEnabled(true);
204
205   if ( installStackWidget->currentIndex() == 1 )
206     backButton->setVisible(false);
207   else
208     backButton->setVisible(true);
209
210   proceed(false);
211}
212
213void Installer::slotChangeLanguage()
214{
215    if ( comboLanguage->currentIndex() == -1 )
216      return;
217
218    // Figure out the language code
219    QString langCode = languages.at(comboLanguage->currentIndex());
220   
221    // Grab the language code
222    langCode.truncate(langCode.lastIndexOf(")"));
223    langCode.remove(0, langCode.lastIndexOf("(") + 1); 
224
225    // Check what directory our app is in
226    QString appDir;
227    if ( QFile::exists("/usr/local/bin/pc-sysinstaller") )
228      appDir = "/usr/local/share/pcbsd";
229    else
230      appDir = QCoreApplication::applicationDirPath();
231   
232    //QTranslator *translator = new QTranslator();
233    qDebug() << "Remove the translator";
234    if ( ! translator->isEmpty() )
235      QCoreApplication::removeTranslator(translator);
236   
237    if (translator->load( QString("FirstBoot_") + langCode, appDir + "/i18n/" )) {
238      qDebug() << "Load new Translator" << langCode;
239      QCoreApplication::installTranslator(translator);
240      this->retranslateUi(this);
241    }
242
243}
244
245void Installer::changeLang(QString code)
246{
247   // Change the language in the combobox with the current running one
248   comboLanguage->disconnect();
249
250   for (int i=0; i < languages.count(); ++i) {
251      if ( languages.at(i).indexOf("(" + code + ")" ) != -1 ) {
252        comboLanguage->setCurrentIndex(i); 
253      }
254   }
255
256   connect(comboLanguage, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotChangeLanguage()));
257}
258
259void Installer::slotHelp()
260{
261        pcHelp = new dialogHelp();
262        switch (installStackWidget->currentIndex()) {
263        case 0:
264                pcHelp->dialogInit(HELPTEXT0);
265                break;
266        case 1:
267                pcHelp->dialogInit(HELPTEXT1);
268                break;
269        case 2:
270                pcHelp->dialogInit(HELPTEXT2);
271                break;
272        case 3:
273                pcHelp->dialogInit(HELPTEXT3);
274                break;
275        case 4:
276                pcHelp->dialogInit(HELPTEXT4);
277                break;
278        case 5:
279                pcHelp->dialogInit(HELPTEXT5);
280                break;
281        default:
282                pcHelp->dialogInit("Missing help file...");
283                break;
284        }
285        pcHelp->show();
286}
287
288void Installer::slotScanNetwork()
289{
290  QString strength, ssid, security, FileLoad;
291  QStringList ifconfout, ifline;
292  int foundItem = 0;
293
294  // Clear the list box and disable the add button
295  listWidgetWifi->clear();
296
297  // Start the scan and get the output
298  //ifconfout = pcbsd::Utils::runShellCommand("ifconfig -v wlan0 up list scan");
299  ifconfout = pcbsd::Utils::runShellCommand("ifconfig -v wlan0 list scan");
300 
301  qDebug() << ifconfout;
302
303  //display the info for each wifi access point
304  for(int i=1; i<ifconfout.size(); i++){    //Skip the header line by starting at 1
305    ifline = NetworkInterface::parseWifiScanLine(ifconfout[i],true); //get a single line
306    //save the info for this wifi
307    ssid = ifline[0];
308    strength = ifline[4];
309    //determine the icon based on if there is security encryption
310    security = ifline[6]; //NetworkInterface::getWifiSecurity(ssid,DeviceName);
311    if(security.contains("None")){
312      FileLoad = ":/modules/images/object-unlocked.png";
313    }else{
314      FileLoad = ":/modules/images/object-locked.png";
315    }
316    //Add the wifi access point to the list
317    listWidgetWifi->addItem(new QListWidgetItem(QIcon(FileLoad), ssid + " (signal: " +strength + ")") );
318    foundItem = 1; //set the flag for wifi signals found
319  }
320   
321  if ( foundItem == 1 )
322    listWidgetWifi->setCurrentRow(-1);
323}
324
325void Installer::slotAddNewWifi()
326{
327  if ((listWidgetWifi->currentRow()) ==-1 )
328     return;
329
330  QString line = listWidgetWifi->item(listWidgetWifi->currentRow())->text();
331  QString ssidc = line.section(" (",0,0,QString::SectionSkipEmpty);
332  addNetworkProfile(ssidc);
333}
334
335void Installer::addNetworkProfile(QString ssid)
336{
337  //get the full SSID string
338  QString dat = pcbsd::Utils::runShellCommandSearch("ifconfig -v wlan0 list scan",ssid);
339  QStringList wdat = NetworkInterface::parseWifiScanLine(dat,true);
340  QString SSID = wdat[0];
341 
342  //Get the Security Type
343  QString sectype = wdat[6];
344 
345  if(sectype == "None"){
346    //run the Quick-Connect slot without a key
347    slotQuickConnect("",SSID);
348  }else{
349    //Open the dialog to prompt for the Network Security Key
350    dialogNetKey = new netKey();
351    //Insert the SSID into the dialog
352    dialogNetKey->setSSID(SSID);
353    //connect the signal from the dialog to the quick-connect slot
354    connect(dialogNetKey,SIGNAL( saved(QString,QString) ),this,SLOT( slotQuickConnect(QString,QString) ) );
355    //Activate the dialog
356    dialogNetKey->exec();
357  }
358}
359
360void Installer::slotQuickConnect(QString key,QString SSID){
361 
362  // Run the wifiQuickConnect function
363  NetworkInterface::wifiQuickConnect(SSID,key,"wlan0");
364 
365  // Restart the network
366  system("/etc/rc.d/netif restart &");
367 
368  // Move to finish screen
369  installStackWidget->setCurrentIndex(5);
370
371  // Save the settings
372  saveSettings();
373  nextButton->setText(tr("&Finish"));
374  backButton->setVisible(false);
375  nextButton->disconnect();
376  connect(nextButton, SIGNAL(clicked()), this, SLOT(slotFinished()));
377}
378
379void Installer::saveSettings()
380{
381  // Check if we need to change the language
382  if ( comboLanguage->currentIndex() != 0 ) {
383    QString lang = languages.at(comboLanguage->currentIndex());
384    // Grab the language code
385    lang.truncate(lang.lastIndexOf(")"));
386    lang.remove(0, lang.lastIndexOf("(") + 1);
387    qDebug() << "Set Lang:" << lang;
388    system("/usr/local/share/pcbsd/scripts/set-lang.sh " + lang.toLatin1());
389  }
390
391  // Set the timezone
392  QString tz = comboBoxTimezone->currentText();
393  if ( tz.indexOf(":") != -1 )
394   tz = tz.section(":", 0, 0);
395  system("cp /usr/share/zoneinfo/" + tz.toLatin1() + " /etc/localtime");
396
397  // Set the root PW
398  QTemporaryFile rfile("/tmp/.XXXXXXXX");
399  if ( rfile.open() ) {
400    QTextStream stream( &rfile );
401      stream << lineRootPW->text();
402    rfile.close();
403  }
404  system("cat " + rfile.fileName().toLatin1() + " | pw usermod root -h 0 ");
405  rfile.remove();
406
407  // Create the new home-directory
408  system("/usr/local/share/pcbsd/scripts/mkzfsdir.sh /usr/home/" + lineUsername->text().toLatin1() );
409
410  // Create the new username
411  QTemporaryFile ufile("/tmp/.XXXXXXXX");
412  if ( ufile.open() ) {
413    QTextStream stream( &ufile );
414      stream << linePW->text();
415    ufile.close();
416  }
417  QString userCmd = " | pw useradd -n \"" + lineUsername->text() + "\" -c \"" + lineName->text() + "\" -h 0 -s \"/bin/csh\" -m -d \"/usr/home/" + lineUsername->text() + "\" -G \"wheel,operator\"";
418  system("cat " + ufile.fileName().toLatin1() + userCmd.toLatin1());
419  ufile.remove();
420
421  // Enable Flash for the new user
422  QString flashCmd = "su -m " + lineUsername->text() + " -c \"flashpluginctl on\"";
423  system(flashCmd.toLatin1());
424 
425  // Encrypt the users home-directory?
426  if ( checkEnc->isChecked() )
427    system("enable_user_pefs " + lineUsername->text().toLatin1() + " " + linePW->text().toLatin1());
428
429}
430
431void Installer::slotKeyLayoutUpdated(QString mod, QString lay, QString var)
432{
433  kbMod = mod;
434  kbLay = lay;
435  kbVar = var;
436}
437
438void Installer::closeEvent(QCloseEvent *event)
439{
440   event->ignore();
441}
Note: See TracBrowser for help on using the repository browser.