~ubuntu-sdk-team/qtcreator-plugin-remotelinux/trunk

« back to all changes in this revision

Viewing changes to src/qnx/blackberrysetupwizard.cpp

  • Committer: CI bot
  • Author(s): Benjamin Zeller
  • Date: 2014-06-16 10:28:43 UTC
  • mfrom: (4.2.4 remotelinux)
  • Revision ID: ps-jenkins@lists.canonical.com-20140616102843-8juvmjvzwlzsboyw
Migrating to Qt5.3 and QtC 3.1 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
**
3
 
** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
4
 
**
5
 
** Contact: BlackBerry (qt@blackberry.com)
6
 
** Contact: KDAB (info@kdab.com)
7
 
**
8
 
** This file is part of Qt Creator.
9
 
**
10
 
** Commercial License Usage
11
 
** Licensees holding valid commercial Qt licenses may use this file in
12
 
** accordance with the commercial license agreement provided with the
13
 
** Software or, alternatively, in accordance with the terms contained in
14
 
** a written agreement between you and Digia.  For licensing terms and
15
 
** conditions see http://qt.digia.com/licensing.  For further information
16
 
** use the contact form at http://qt.digia.com/contact-us.
17
 
**
18
 
** GNU Lesser General Public License Usage
19
 
** Alternatively, this file may be used under the terms of the GNU Lesser
20
 
** General Public License version 2.1 as published by the Free Software
21
 
** Foundation and appearing in the file LICENSE.LGPL included in the
22
 
** packaging of this file.  Please review the following information to
23
 
** ensure the GNU Lesser General Public License version 2.1 requirements
24
 
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
 
**
26
 
** In addition, as a special exception, Digia gives you certain additional
27
 
** rights.  These rights are described in the Digia Qt LGPL Exception
28
 
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
 
**
30
 
****************************************************************************/
31
 
 
32
 
#include "blackberrysetupwizard.h"
33
 
#include "blackberrysetupwizardpages.h"
34
 
#include "blackberrydeviceconfiguration.h"
35
 
#include "blackberrycertificate.h"
36
 
#include "blackberryconfigurationmanager.h"
37
 
#include "blackberrydebugtokenrequester.h"
38
 
#include "blackberrydebugtokenuploader.h"
39
 
#include "blackberrydeviceinformation.h"
40
 
#include "blackberrysigningutils.h"
41
 
#include "qnxconstants.h"
42
 
 
43
 
#include <projectexplorer/devicesupport/devicemanager.h>
44
 
#include <projectexplorer/devicesupport/idevice.h>
45
 
#include <ssh/sshconnection.h>
46
 
#include <ssh/sshkeygenerator.h>
47
 
#include <utils/fileutils.h>
48
 
#include <coreplugin/icore.h>
49
 
 
50
 
#include <QDir>
51
 
#include <QMessageBox>
52
 
#include <QHostInfo>
53
 
#include <QAbstractButton>
54
 
 
55
 
using namespace ProjectExplorer;
56
 
using namespace Qnx;
57
 
using namespace Qnx::Internal;
58
 
 
59
 
BlackBerrySetupWizard::BlackBerrySetupWizard(QWidget *parent) :
60
 
    Utils::Wizard(parent),
61
 
    m_ndkPage(0),
62
 
    m_keysPage(0),
63
 
    m_certificatePage(0),
64
 
    m_devicePage(0),
65
 
    m_certificate(0),
66
 
    m_deviceInfo(0),
67
 
    m_requester(0),
68
 
    m_uploader(0),
69
 
    m_utils(BlackBerrySigningUtils::instance()),
70
 
    m_keyGenerator(0),
71
 
    m_currentStep(-1),
72
 
    m_stepOffset(0)
73
 
{
74
 
    setWindowTitle(tr("BlackBerry Development Environment Setup Wizard"));
75
 
    setOption(QWizard::IndependentPages, true);
76
 
 
77
 
    m_welcomePage = new BlackBerrySetupWizardWelcomePage(this);
78
 
    m_ndkPage = new BlackBerrySetupWizardNdkPage(this);
79
 
    m_keysPage = new BlackBerrySetupWizardKeysPage(this);
80
 
    m_certificatePage = new BlackBerrySetupWizardCertificatePage(this);
81
 
    m_devicePage = new BlackBerrySetupWizardDevicePage(this);
82
 
    m_finishPage = new BlackBerrySetupWizardFinishPage(this);
83
 
 
84
 
    setPage(WelcomePageId, m_welcomePage);
85
 
    setPage(NdkPageId, m_ndkPage);
86
 
    setPage(KeysPageId, m_keysPage);
87
 
    setPage(CertificatePageId, m_certificatePage);
88
 
    setPage(DevicePageId, m_devicePage);
89
 
    setPage(FinishPageId, m_finishPage);
90
 
 
91
 
    m_deviceInfo = new BlackBerryDeviceInformation(this);
92
 
    m_requester = new BlackBerryDebugTokenRequester(this);
93
 
    m_uploader = new BlackBerryDebugTokenUploader(this);
94
 
    m_keyGenerator = new QSsh::SshKeyGenerator;
95
 
 
96
 
    connect(m_ndkPage, SIGNAL(targetsUpdated()),
97
 
            this, SIGNAL(ndkTargetsUpdated()));
98
 
    connect(m_deviceInfo, SIGNAL(finished(int)),
99
 
            this, SLOT(deviceInfoFinished(int)));
100
 
    connect(m_requester, SIGNAL(finished(int)),
101
 
            this, SLOT(debugTokenArrived(int)));
102
 
    connect(m_uploader, SIGNAL(finished(int)),
103
 
            this, SLOT(uploaderFinished(int)));
104
 
    connect(this, SIGNAL(stepFinished()),
105
 
            this, SLOT(processNextStep()));
106
 
 
107
 
    registerStep("requestDevicePin", tr("Reading device PIN..."));
108
 
    registerStep("generateDeveloperCertificate", tr("Generating developer certificate..."));
109
 
    registerStep("generateSshKeys", tr("Generating SSH keys..."));
110
 
    registerStep("requestDebugToken", tr("Requesting a debug token for the device..."));
111
 
    registerStep("uploadDebugToken", tr("Now uploading the debug token..."));
112
 
    registerStep("writeDeviceInformation", tr("Writing device information..."));
113
 
}
114
 
 
115
 
BlackBerrySetupWizard::~BlackBerrySetupWizard()
116
 
{
117
 
    delete m_keyGenerator;
118
 
 
119
 
    foreach (Step *s, m_stepList)
120
 
        delete s;
121
 
 
122
 
    m_stepList.clear();
123
 
}
124
 
 
125
 
void BlackBerrySetupWizard::accept()
126
 
{
127
 
    setBusy(true);
128
 
    processNextStep();
129
 
}
130
 
 
131
 
void BlackBerrySetupWizard::processNextStep()
132
 
{
133
 
    m_currentStep++;
134
 
 
135
 
    if (m_currentStep >= m_stepList.size())
136
 
        return;
137
 
 
138
 
    const Step *step = m_stepList.at(m_currentStep);
139
 
 
140
 
    m_finishPage->setProgress(step->message, m_currentStep * m_stepOffset);
141
 
    QMetaObject::invokeMethod(this, step->slot);
142
 
}
143
 
 
144
 
void BlackBerrySetupWizard::deviceInfoFinished(int status)
145
 
{
146
 
    const QString errorString = tr("Error reading device PIN. "
147
 
            "Please make sure that the specified device IP address is correct.");
148
 
 
149
 
    if (status != BlackBerryDeviceInformation::Success) {
150
 
        QMessageBox::critical(this, tr("Error"), errorString);
151
 
        reset();
152
 
        return;
153
 
    }
154
 
 
155
 
    m_devicePin = m_deviceInfo->devicePin();
156
 
 
157
 
    if (m_devicePin.isEmpty()) {
158
 
        QMessageBox::critical(this, tr("Error"), errorString);
159
 
        reset();
160
 
        return;
161
 
    }
162
 
 
163
 
    emit stepFinished();
164
 
}
165
 
 
166
 
void BlackBerrySetupWizard::certificateCreated(int status)
167
 
{
168
 
    if (status == BlackBerryCertificate::Error) {
169
 
        QMessageBox::critical(this, tr("Error"), tr("Error creating developer certificate."));
170
 
        m_certificate->deleteLater();
171
 
        m_certificate = 0;
172
 
        reset();
173
 
        return;
174
 
    }
175
 
 
176
 
    emit stepFinished();
177
 
}
178
 
 
179
 
void BlackBerrySetupWizard::debugTokenArrived(int status)
180
 
{
181
 
    QString errorString = tr("Failed to request debug token:") + QLatin1Char(' ');
182
 
 
183
 
    switch (status) {
184
 
    case BlackBerryDebugTokenRequester::Success:
185
 
        emit stepFinished();
186
 
        return;
187
 
    case BlackBerryDebugTokenRequester::WrongCskPassword:
188
 
        m_utils.clearCskPassword();
189
 
        errorString += tr("Wrong CSK password.");
190
 
        break;
191
 
    case BlackBerryDebugTokenRequester::WrongKeystorePassword:
192
 
        errorString += tr("Wrong keystore password.");
193
 
        break;
194
 
    case BlackBerryDebugTokenRequester::NetworkUnreachable:
195
 
        errorString += tr("Network unreachable.");
196
 
        break;
197
 
    case BlackBerryDebugTokenRequester::IllegalPin:
198
 
        errorString += tr("Illegal device PIN.");
199
 
        break;
200
 
    case BlackBerryDebugTokenRequester::FailedToStartInferiorProcess:
201
 
        errorString += tr("Failed to start inferior process.");
202
 
        break;
203
 
    case BlackBerryDebugTokenRequester::InferiorProcessTimedOut:
204
 
        errorString += tr("Inferior processes timed out.");
205
 
        break;
206
 
    case BlackBerryDebugTokenRequester::InferiorProcessCrashed:
207
 
        errorString += tr("Inferior process has crashed.");
208
 
        break;
209
 
    case BlackBerryDebugTokenRequester::InferiorProcessReadError:
210
 
    case BlackBerryDebugTokenRequester::InferiorProcessWriteError:
211
 
        errorString += tr("Failed to communicate with the inferior process.");
212
 
        break;
213
 
    case BlackBerryDebugTokenRequester::UnknownError:
214
 
    default:
215
 
        m_utils.clearCskPassword();
216
 
        errorString += tr("An unknwon error has occurred.");
217
 
        break;
218
 
    }
219
 
 
220
 
    QMessageBox::critical(this, tr("Error"), errorString);
221
 
 
222
 
    reset();
223
 
}
224
 
 
225
 
void BlackBerrySetupWizard::uploaderFinished(int status)
226
 
{
227
 
    QString errorString = tr("Failed to upload debug token:") + QLatin1Char(' ');
228
 
 
229
 
    switch (status) {
230
 
    case BlackBerryDebugTokenUploader::Success:
231
 
        emit stepFinished();
232
 
        return;
233
 
    case BlackBerryDebugTokenUploader::NoRouteToHost:
234
 
        errorString += tr("No route to host.");
235
 
        break;
236
 
    case BlackBerryDebugTokenUploader::AuthenticationFailed:
237
 
        errorString += tr("Authentication failed.");
238
 
        break;
239
 
    case BlackBerryDebugTokenUploader::DevelopmentModeDisabled:
240
 
        errorString += tr("Development mode is disabled on the device.");
241
 
        break;
242
 
    case BlackBerryDebugTokenUploader::FailedToStartInferiorProcess:
243
 
        errorString += tr("Failed to start inferior process.");
244
 
        break;
245
 
    case BlackBerryDebugTokenUploader::InferiorProcessTimedOut:
246
 
        errorString += tr("Inferior processes timed out.");
247
 
        break;
248
 
    case BlackBerryDebugTokenUploader::InferiorProcessCrashed:
249
 
        errorString += tr("Inferior process has crashed.");
250
 
        break;
251
 
    case BlackBerryDebugTokenUploader::InferiorProcessReadError:
252
 
    case BlackBerryDebugTokenUploader::InferiorProcessWriteError:
253
 
        errorString += tr("Failed to communicate with the inferior process.");
254
 
        break;
255
 
    case BlackBerryDebugTokenUploader::UnknownError:
256
 
        errorString += tr("An unknwon error has happened.");
257
 
        break;
258
 
    }
259
 
 
260
 
    QMessageBox::critical(this, tr("Error"), errorString);
261
 
 
262
 
    reset();
263
 
}
264
 
 
265
 
void BlackBerrySetupWizard::registerStep(const QByteArray &slot, const QString &message)
266
 
{
267
 
    Step *s = new Step;
268
 
    s->slot = slot;
269
 
    s->message = message;
270
 
    m_stepList << s;
271
 
 
272
 
    m_stepOffset = 100/m_stepList.size();
273
 
}
274
 
 
275
 
void BlackBerrySetupWizard::setBusy(bool busy)
276
 
{
277
 
    button(QWizard::BackButton)->setEnabled(!busy);
278
 
    button(QWizard::NextButton)->setEnabled(!busy);
279
 
    button(QWizard::FinishButton)->setEnabled(!busy);
280
 
    button(QWizard::CancelButton)->setEnabled(!busy);
281
 
 
282
 
    if (!busy)
283
 
        m_finishPage->setProgress(QString(), -1);
284
 
}
285
 
 
286
 
void BlackBerrySetupWizard::cleanupFiles() const
287
 
{
288
 
    BlackBerryConfigurationManager &configuration = BlackBerryConfigurationManager::instance();
289
 
 
290
 
    QFile f;
291
 
 
292
 
    f.setFileName(configuration.defaultKeystorePath());
293
 
    f.remove();
294
 
 
295
 
    f.setFileName(configuration.defaultDebugTokenPath());
296
 
    f.remove();
297
 
 
298
 
    f.setFileName(privateKeyPath());
299
 
    f.remove();
300
 
 
301
 
    f.setFileName(publicKeyPath());
302
 
    f.remove();
303
 
 
304
 
    QDir::root().rmpath(storeLocation());
305
 
}
306
 
 
307
 
void BlackBerrySetupWizard::reset()
308
 
{
309
 
    cleanupFiles();
310
 
    setBusy(false);
311
 
    m_currentStep = -1;
312
 
 
313
 
    if (m_certificate) {
314
 
        m_certificate->deleteLater();
315
 
        m_certificate = 0;
316
 
    }
317
 
}
318
 
 
319
 
void BlackBerrySetupWizard::requestDevicePin()
320
 
{
321
 
    if (!isPhysicalDevice()) {
322
 
        emit stepFinished();
323
 
        return;
324
 
    }
325
 
 
326
 
    m_deviceInfo->setDeviceTarget(hostName(), devicePassword());
327
 
}
328
 
 
329
 
void BlackBerrySetupWizard::generateDeveloperCertificate()
330
 
{
331
 
    BlackBerryConfigurationManager &configuration = BlackBerryConfigurationManager::instance();
332
 
 
333
 
    m_certificate = new BlackBerryCertificate(configuration.defaultKeystorePath(),
334
 
            certificateAuthor(), certificatePassword());
335
 
 
336
 
    connect(m_certificate, SIGNAL(finished(int)), this, SLOT(certificateCreated(int)));
337
 
 
338
 
    m_certificate->store();
339
 
}
340
 
 
341
 
void BlackBerrySetupWizard::generateSshKeys()
342
 
{
343
 
    const bool success = m_keyGenerator->generateKeys(QSsh::SshKeyGenerator::Rsa,
344
 
            QSsh::SshKeyGenerator::Mixed, 4096,
345
 
            QSsh::SshKeyGenerator::DoNotOfferEncryption);
346
 
 
347
 
    if (!success) {
348
 
        QMessageBox::critical(this, tr("Key Generation Failed"), m_keyGenerator->error());
349
 
        reset();
350
 
        return;
351
 
    }
352
 
 
353
 
    if (!QDir::root().mkpath(storeLocation())) {
354
 
        QMessageBox::critical(this, tr("Failure to Save Key File"),
355
 
                              tr("Failed to create directory: '%1'.").arg(storeLocation()));
356
 
        reset();
357
 
        return;
358
 
    }
359
 
 
360
 
    if (QFileInfo(privateKeyPath()).exists()) {
361
 
        QMessageBox::critical(this, tr("Failure to Save Key File"),
362
 
                              tr("Private key file already exists: '%1'").arg(privateKeyPath()));
363
 
        reset();
364
 
        return;
365
 
    }
366
 
 
367
 
    if (QFileInfo(publicKeyPath()).exists()) {
368
 
        QMessageBox::critical(this, tr("Failure to Save Key File"),
369
 
                              tr("Public key file already exists: '%1'").arg(publicKeyPath()));
370
 
        reset();
371
 
        return;
372
 
    }
373
 
 
374
 
    Utils::FileSaver privateKeySaver(privateKeyPath());
375
 
    privateKeySaver.write(m_keyGenerator->privateKey());
376
 
 
377
 
    if (!privateKeySaver.finalize(this)) {
378
 
        reset();
379
 
        return; // finalize shows an error message if necessary
380
 
    }
381
 
 
382
 
    QFile::setPermissions(privateKeyPath(), QFile::ReadOwner | QFile::WriteOwner);
383
 
 
384
 
    Utils::FileSaver publicKeySaver(publicKeyPath());
385
 
 
386
 
    // blackberry-connect requires an @ character to be included in the RSA comment
387
 
    const QString atHost = QLatin1Char('@') + QHostInfo::localHostName();
388
 
    QByteArray publicKeyContent = m_keyGenerator->publicKey();
389
 
    publicKeyContent.append(atHost.toLocal8Bit());
390
 
 
391
 
    publicKeySaver.write(publicKeyContent);
392
 
 
393
 
    if (!publicKeySaver.finalize(this)) {
394
 
        reset();
395
 
        return;
396
 
    }
397
 
 
398
 
    emit stepFinished();
399
 
}
400
 
 
401
 
void BlackBerrySetupWizard::requestDebugToken()
402
 
{
403
 
    if (!isPhysicalDevice()) {
404
 
        emit stepFinished();
405
 
        return;
406
 
    }
407
 
 
408
 
    BlackBerryConfigurationManager &configuration = BlackBerryConfigurationManager::instance();
409
 
 
410
 
    m_requester->requestDebugToken(configuration.defaultDebugTokenPath(),
411
 
            m_utils.cskPassword(), configuration.defaultKeystorePath(), certificatePassword(), m_devicePin);
412
 
}
413
 
 
414
 
void BlackBerrySetupWizard::uploadDebugToken()
415
 
{
416
 
    if (!isPhysicalDevice()) {
417
 
        emit stepFinished();
418
 
        return;
419
 
    }
420
 
 
421
 
    BlackBerryConfigurationManager &configuration = BlackBerryConfigurationManager::instance();
422
 
 
423
 
    m_uploader->uploadDebugToken(configuration.defaultDebugTokenPath(),
424
 
            hostName(), devicePassword());
425
 
}
426
 
 
427
 
void BlackBerrySetupWizard::writeDeviceInformation()
428
 
{
429
 
    DeviceManager * const deviceManager = DeviceManager::instance();
430
 
    deviceManager->addDevice(device());
431
 
 
432
 
    m_utils.setDefaultCertificate(m_certificate);
433
 
 
434
 
    QWizard::accept();
435
 
}
436
 
 
437
 
QString BlackBerrySetupWizard::privateKeyPath() const
438
 
{
439
 
    return storeLocation() + QLatin1String("/id_rsa");
440
 
}
441
 
 
442
 
QString BlackBerrySetupWizard::publicKeyPath() const
443
 
{
444
 
    return storeLocation() + QLatin1String("/id_rsa.pub");
445
 
}
446
 
 
447
 
QString BlackBerrySetupWizard::deviceName() const
448
 
{
449
 
    return field(QLatin1String(BlackBerrySetupWizardDevicePage::NameField)).toString();
450
 
}
451
 
 
452
 
QString BlackBerrySetupWizard::storeLocation() const
453
 
{
454
 
    return Core::ICore::userResourcePath() + QLatin1String("/qnx/") + deviceName();
455
 
}
456
 
 
457
 
QString BlackBerrySetupWizard::certificatePassword() const
458
 
{
459
 
    return field(QLatin1String(BlackBerrySetupWizardCertificatePage::PasswordField)).toString();
460
 
}
461
 
 
462
 
QString BlackBerrySetupWizard::certificateAuthor() const
463
 
{
464
 
    return field(QLatin1String(BlackBerrySetupWizardCertificatePage::AuthorField)).toString();
465
 
}
466
 
 
467
 
QString BlackBerrySetupWizard::hostName() const
468
 
{
469
 
    return field(QLatin1String(BlackBerrySetupWizardDevicePage::IpAddressField)).toString();
470
 
}
471
 
 
472
 
QString BlackBerrySetupWizard::devicePassword() const
473
 
{
474
 
    return field(QLatin1String(BlackBerrySetupWizardDevicePage::PasswordField)).toString();
475
 
}
476
 
 
477
 
bool BlackBerrySetupWizard::isPhysicalDevice() const
478
 
{
479
 
    return field(QLatin1String(BlackBerrySetupWizardDevicePage::PhysicalDeviceField)).toBool();
480
 
}
481
 
 
482
 
IDevice::Ptr BlackBerrySetupWizard::device()
483
 
{
484
 
    QSsh::SshConnectionParameters sshParams;
485
 
    sshParams.options = QSsh::SshIgnoreDefaultProxy;
486
 
    sshParams.host = hostName();
487
 
    sshParams.password = devicePassword();
488
 
    sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePublicKey;
489
 
    sshParams.privateKeyFile = privateKeyPath();
490
 
    sshParams.userName = QLatin1String("devuser");
491
 
    sshParams.timeout = 10;
492
 
    sshParams.port = 22;
493
 
 
494
 
    IDevice::MachineType machineType = (isPhysicalDevice()) ? IDevice::Hardware : IDevice::Emulator;
495
 
 
496
 
    BlackBerryDeviceConfiguration::Ptr configuration = BlackBerryDeviceConfiguration::create(
497
 
            deviceName(), Core::Id(Constants::QNX_BB_OS_TYPE), machineType);
498
 
 
499
 
    configuration->setSshParameters(sshParams);
500
 
    configuration->setDebugToken(BlackBerryConfigurationManager::instance().defaultDebugTokenPath());
501
 
 
502
 
    return configuration;
503
 
}