~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to wpa_supplicant/wpa_gui-qt4/wpagui.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2008-03-12 20:03:04 UTC
  • mfrom: (1.1.10 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20080312200304-4331y9wj46pdd34z
Tags: 0.6.3-1
* New upstream release.
* Drop patches applied upstream:
  - debian/patches/30_wpa_gui_qt4_eventhistoryui_rework.patch
  - debian/patches/31_wpa_gui_qt4_eventhistory_always_scrollbar.patch
  - debian/patches/32_wpa_gui_qt4_eventhistory_scroll_with_events.patch
  - debian/patches/40_dbus_ssid_data.patch
* Tidy up the clean target of debian/rules. Now that the madwifi headers are
  handled differently we no longer need to do any cleanup.
* Fix formatting error in debian/ifupdown/wpa_action.8 to make lintian
  quieter.
* Add patch to fix formatting errors in manpages build from sgml source. Use
  <emphasis> tags to hightlight keywords instead of surrounding them in
  strong quotes.
  - debian/patches/41_manpage_format_fixes.patch
* wpasupplicant binary package no longer suggests pcscd, guessnet, iproute
  or wireless-tools, nor does it recommend dhcp3-client. These are not
  needed.
* Add debian/patches/10_silence_siocsiwauth_icotl_failure.patch to disable
  ioctl failure messages that occur under normal conditions.
* Cherry pick two upstream git commits concerning the dbus interface:
  - debian/patches/11_avoid_dbus_version_namespace.patch
  - debian/patches/12_fix_potential_use_after_free.patch
* Add debian/patches/42_manpage_explain_available_drivers.patch to explain
  that not all of the driver backends are available in the provided
  wpa_supplicant binary, and that the canonical list of supported driver
  backends can be retrieved from the wpa_supplicant -h (help) output.
  (Closes: #466910)
* Add debian/patches/20_wpa_gui_qt4_disable_link_prl.patch to remove
  link_prl CONFIG compile flag added by qmake-qt4 >= 4.3.4-2 to avoid excess
  linking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * wpa_gui - WpaGui class
 
3
 * Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#ifdef __MINGW32__
 
16
/* Need to get getopt() */
 
17
#include <unistd.h>
 
18
#endif
 
19
 
 
20
#include <QMessageBox>
 
21
#include <QCloseEvent>
 
22
 
 
23
#include "wpagui.h"
 
24
#include "dirent.h"
 
25
#include "wpa_ctrl.h"
 
26
#include "userdatarequest.h"
 
27
#include "networkconfig.h"
 
28
 
 
29
WpaGui::WpaGui(QWidget *parent, const char *, Qt::WFlags)
 
30
        : QMainWindow(parent)
 
31
{
 
32
        setupUi(this);
 
33
 
 
34
        (void) statusBar();
 
35
 
 
36
        connect(fileEventHistoryAction, SIGNAL(triggered()), this,
 
37
                SLOT(eventHistory()));
 
38
        connect(fileSaveConfigAction, SIGNAL(triggered()), this,
 
39
                SLOT(saveConfig()));
 
40
        connect(fileExitAction, SIGNAL(triggered()), this, SLOT(close()));
 
41
        connect(networkAddAction, SIGNAL(triggered()), this,
 
42
                SLOT(addNetwork()));
 
43
        connect(networkEditAction, SIGNAL(triggered()), this,
 
44
                SLOT(editSelectedNetwork()));
 
45
        connect(networkRemoveAction, SIGNAL(triggered()), this,
 
46
                SLOT(removeSelectedNetwork()));
 
47
        connect(networkEnableAllAction, SIGNAL(triggered()), this,
 
48
                SLOT(enableAllNetworks()));
 
49
        connect(networkDisableAllAction, SIGNAL(triggered()), this,
 
50
                SLOT(disableAllNetworks()));
 
51
        connect(networkRemoveAllAction, SIGNAL(triggered()), this,
 
52
                SLOT(removeAllNetworks()));
 
53
        connect(helpIndexAction, SIGNAL(triggered()), this, SLOT(helpIndex()));
 
54
        connect(helpContentsAction, SIGNAL(triggered()), this,
 
55
                SLOT(helpContents()));
 
56
        connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(helpAbout()));
 
57
        connect(disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect()));
 
58
        connect(scanButton, SIGNAL(clicked()), this, SLOT(scan()));
 
59
        connect(connectButton, SIGNAL(clicked()), this, SLOT(connectB()));
 
60
        connect(adapterSelect, SIGNAL(activated(const QString&)), this,
 
61
                SLOT(selectAdapter(const QString&)));
 
62
        connect(networkSelect, SIGNAL(activated(const QString&)), this,
 
63
                SLOT(selectNetwork(const QString&)));
 
64
        connect(addNetworkButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
 
65
        connect(editNetworkButton, SIGNAL(clicked()), this,
 
66
                SLOT(editListedNetwork()));
 
67
        connect(removeNetworkButton, SIGNAL(clicked()), this,
 
68
                SLOT(removeListedNetwork()));
 
69
        connect(networkList, SIGNAL(itemSelectionChanged()), this,
 
70
                SLOT(updateNetworkDisabledStatus()));
 
71
        connect(enableRadioButton, SIGNAL(toggled(bool)), this,
 
72
                SLOT(enableListedNetwork(bool)));
 
73
        connect(disableRadioButton, SIGNAL(toggled(bool)), this,
 
74
                SLOT(disableListedNetwork(bool)));
 
75
        connect(scanNetworkButton, SIGNAL(clicked()), this, SLOT(scan()));
 
76
        connect(networkList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
 
77
                this, SLOT(editListedNetwork()));
 
78
 
 
79
        eh = NULL;
 
80
        scanres = NULL;
 
81
        udr = NULL;
 
82
        ctrl_iface = NULL;
 
83
        ctrl_conn = NULL;
 
84
        monitor_conn = NULL;
 
85
        msgNotifier = NULL;
 
86
        ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
 
87
 
 
88
        parse_argv();
 
89
 
 
90
        textStatus->setText("connecting to wpa_supplicant");
 
91
        timer = new QTimer(this);
 
92
        connect(timer, SIGNAL(timeout()), SLOT(ping()));
 
93
        timer->setSingleShot(FALSE);
 
94
        timer->start(1000);
 
95
 
 
96
        if (openCtrlConnection(ctrl_iface) < 0) {
 
97
                printf("Failed to open control connection to "
 
98
                       "wpa_supplicant.\n");
 
99
        }
 
100
 
 
101
        updateStatus();
 
102
        networkMayHaveChanged = true;
 
103
        updateNetworks();
 
104
}
 
105
 
 
106
 
 
107
WpaGui::~WpaGui()
 
108
{
 
109
        delete msgNotifier;
 
110
 
 
111
        if (monitor_conn) {
 
112
                wpa_ctrl_detach(monitor_conn);
 
113
                wpa_ctrl_close(monitor_conn);
 
114
                monitor_conn = NULL;
 
115
        }
 
116
        if (ctrl_conn) {
 
117
                wpa_ctrl_close(ctrl_conn);
 
118
                ctrl_conn = NULL;
 
119
        }
 
120
 
 
121
        if (eh) {
 
122
                eh->close();
 
123
                delete eh;
 
124
                eh = NULL;
 
125
        }
 
126
 
 
127
        if (scanres) {
 
128
                scanres->close();
 
129
                delete scanres;
 
130
                scanres = NULL;
 
131
        }
 
132
 
 
133
        if (udr) {
 
134
                udr->close();
 
135
                delete udr;
 
136
                udr = NULL;
 
137
        }
 
138
 
 
139
        free(ctrl_iface);
 
140
        ctrl_iface = NULL;
 
141
 
 
142
        free(ctrl_iface_dir);
 
143
        ctrl_iface_dir = NULL;
 
144
}
 
145
 
 
146
 
 
147
void WpaGui::languageChange()
 
148
{
 
149
        retranslateUi(this);
 
150
}
 
151
 
 
152
 
 
153
void WpaGui::parse_argv()
 
154
{
 
155
        int c;
 
156
        for (;;) {
 
157
                c = getopt(qApp->argc(), qApp->argv(), "i:p:");
 
158
                if (c < 0)
 
159
                        break;
 
160
                switch (c) {
 
161
                case 'i':
 
162
                        free(ctrl_iface);
 
163
                        ctrl_iface = strdup(optarg);
 
164
                        break;
 
165
                case 'p':
 
166
                        free(ctrl_iface_dir);
 
167
                        ctrl_iface_dir = strdup(optarg);
 
168
                        break;
 
169
                }
 
170
        }
 
171
}
 
172
 
 
173
 
 
174
int WpaGui::openCtrlConnection(const char *ifname)
 
175
{
 
176
        char *cfile;
 
177
        int flen;
 
178
        char buf[2048], *pos, *pos2;
 
179
        size_t len;
 
180
 
 
181
        if (ifname) {
 
182
                if (ifname != ctrl_iface) {
 
183
                        free(ctrl_iface);
 
184
                        ctrl_iface = strdup(ifname);
 
185
                }
 
186
        } else {
 
187
#ifdef CONFIG_CTRL_IFACE_UDP
 
188
                free(ctrl_iface);
 
189
                ctrl_iface = strdup("udp");
 
190
#endif /* CONFIG_CTRL_IFACE_UDP */
 
191
#ifdef CONFIG_CTRL_IFACE_UNIX
 
192
                struct dirent *dent;
 
193
                DIR *dir = opendir(ctrl_iface_dir);
 
194
                free(ctrl_iface);
 
195
                ctrl_iface = NULL;
 
196
                if (dir) {
 
197
                        while ((dent = readdir(dir))) {
 
198
#ifdef _DIRENT_HAVE_D_TYPE
 
199
                                /* Skip the file if it is not a socket.
 
200
                                 * Also accept DT_UNKNOWN (0) in case
 
201
                                 * the C library or underlying file
 
202
                                 * system does not support d_type. */
 
203
                                if (dent->d_type != DT_SOCK &&
 
204
                                    dent->d_type != DT_UNKNOWN)
 
205
                                        continue;
 
206
#endif /* _DIRENT_HAVE_D_TYPE */
 
207
 
 
208
                                if (strcmp(dent->d_name, ".") == 0 ||
 
209
                                    strcmp(dent->d_name, "..") == 0)
 
210
                                        continue;
 
211
                                printf("Selected interface '%s'\n",
 
212
                                       dent->d_name);
 
213
                                ctrl_iface = strdup(dent->d_name);
 
214
                                break;
 
215
                        }
 
216
                        closedir(dir);
 
217
                }
 
218
#endif /* CONFIG_CTRL_IFACE_UNIX */
 
219
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
 
220
                struct wpa_ctrl *ctrl;
 
221
                int ret;
 
222
 
 
223
                free(ctrl_iface);
 
224
                ctrl_iface = NULL;
 
225
 
 
226
                ctrl = wpa_ctrl_open(NULL);
 
227
                if (ctrl) {
 
228
                        len = sizeof(buf) - 1;
 
229
                        ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf,
 
230
                                               &len, NULL);
 
231
                        if (ret >= 0) {
 
232
                                buf[len] = '\0';
 
233
                                pos = strchr(buf, '\n');
 
234
                                if (pos)
 
235
                                        *pos = '\0';
 
236
                                ctrl_iface = strdup(buf);
 
237
                        }
 
238
                        wpa_ctrl_close(ctrl);
 
239
                }
 
240
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 
241
        }
 
242
 
 
243
        if (ctrl_iface == NULL)
 
244
                return -1;
 
245
 
 
246
#ifdef CONFIG_CTRL_IFACE_UNIX
 
247
        flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
 
248
        cfile = (char *) malloc(flen);
 
249
        if (cfile == NULL)
 
250
                return -1;
 
251
        snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
 
252
#else /* CONFIG_CTRL_IFACE_UNIX */
 
253
        flen = strlen(ctrl_iface) + 1;
 
254
        cfile = (char *) malloc(flen);
 
255
        if (cfile == NULL)
 
256
                return -1;
 
257
        snprintf(cfile, flen, "%s", ctrl_iface);
 
258
#endif /* CONFIG_CTRL_IFACE_UNIX */
 
259
 
 
260
        if (ctrl_conn) {
 
261
                wpa_ctrl_close(ctrl_conn);
 
262
                ctrl_conn = NULL;
 
263
        }
 
264
 
 
265
        if (monitor_conn) {
 
266
                delete msgNotifier;
 
267
                msgNotifier = NULL;
 
268
                wpa_ctrl_detach(monitor_conn);
 
269
                wpa_ctrl_close(monitor_conn);
 
270
                monitor_conn = NULL;
 
271
        }
 
272
 
 
273
        printf("Trying to connect to '%s'\n", cfile);
 
274
        ctrl_conn = wpa_ctrl_open(cfile);
 
275
        if (ctrl_conn == NULL) {
 
276
                free(cfile);
 
277
                return -1;
 
278
        }
 
279
        monitor_conn = wpa_ctrl_open(cfile);
 
280
        free(cfile);
 
281
        if (monitor_conn == NULL) {
 
282
                wpa_ctrl_close(ctrl_conn);
 
283
                return -1;
 
284
        }
 
285
        if (wpa_ctrl_attach(monitor_conn)) {
 
286
                printf("Failed to attach to wpa_supplicant\n");
 
287
                wpa_ctrl_close(monitor_conn);
 
288
                monitor_conn = NULL;
 
289
                wpa_ctrl_close(ctrl_conn);
 
290
                ctrl_conn = NULL;
 
291
                return -1;
 
292
        }
 
293
 
 
294
#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
 
295
        msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
 
296
                                          QSocketNotifier::Read, this);
 
297
        connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
 
298
#endif
 
299
 
 
300
        adapterSelect->clear();
 
301
        adapterSelect->addItem(ctrl_iface);
 
302
        adapterSelect->setCurrentIndex(0);
 
303
 
 
304
        len = sizeof(buf) - 1;
 
305
        if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >=
 
306
            0) {
 
307
                buf[len] = '\0';
 
308
                pos = buf;
 
309
                while (*pos) {
 
310
                        pos2 = strchr(pos, '\n');
 
311
                        if (pos2)
 
312
                                *pos2 = '\0';
 
313
                        if (strcmp(pos, ctrl_iface) != 0)
 
314
                                adapterSelect->addItem(pos);
 
315
                        if (pos2)
 
316
                                pos = pos2 + 1;
 
317
                        else
 
318
                                break;
 
319
                }
 
320
        }
 
321
 
 
322
        return 0;
 
323
}
 
324
 
 
325
 
 
326
static void wpa_gui_msg_cb(char *msg, size_t)
 
327
{
 
328
        /* This should not happen anymore since two control connections are
 
329
         * used. */
 
330
        printf("missed message: %s\n", msg);
 
331
}
 
332
 
 
333
 
 
334
int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
 
335
{
 
336
        int ret;
 
337
 
 
338
        if (ctrl_conn == NULL)
 
339
                return -3;
 
340
        ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
 
341
                               wpa_gui_msg_cb);
 
342
        if (ret == -2)
 
343
                printf("'%s' command timed out.\n", cmd);
 
344
        else if (ret < 0)
 
345
                printf("'%s' command failed.\n", cmd);
 
346
 
 
347
        return ret;
 
348
}
 
349
 
 
350
 
 
351
void WpaGui::updateStatus()
 
352
{
 
353
        char buf[2048], *start, *end, *pos;
 
354
        size_t len;
 
355
 
 
356
        pingsToStatusUpdate = 10;
 
357
 
 
358
        len = sizeof(buf) - 1;
 
359
        if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
 
360
                textStatus->setText("Could not get status from "
 
361
                                    "wpa_supplicant");
 
362
                textAuthentication->clear();
 
363
                textEncryption->clear();
 
364
                textSsid->clear();
 
365
                textBssid->clear();
 
366
                textIpAddress->clear();
 
367
                return;
 
368
        }
 
369
 
 
370
        buf[len] = '\0';
 
371
 
 
372
        bool auth_updated = false, ssid_updated = false;
 
373
        bool bssid_updated = false, ipaddr_updated = false;
 
374
        bool status_updated = false;
 
375
        char *pairwise_cipher = NULL, *group_cipher = NULL;
 
376
 
 
377
        start = buf;
 
378
        while (*start) {
 
379
                bool last = false;
 
380
                end = strchr(start, '\n');
 
381
                if (end == NULL) {
 
382
                        last = true;
 
383
                        end = start;
 
384
                        while (end[0] && end[1])
 
385
                                end++;
 
386
                }
 
387
                *end = '\0';
 
388
 
 
389
                pos = strchr(start, '=');
 
390
                if (pos) {
 
391
                        *pos++ = '\0';
 
392
                        if (strcmp(start, "bssid") == 0) {
 
393
                                bssid_updated = true;
 
394
                                textBssid->setText(pos);
 
395
                        } else if (strcmp(start, "ssid") == 0) {
 
396
                                ssid_updated = true;
 
397
                                textSsid->setText(pos);
 
398
                        } else if (strcmp(start, "ip_address") == 0) {
 
399
                                ipaddr_updated = true;
 
400
                                textIpAddress->setText(pos);
 
401
                        } else if (strcmp(start, "wpa_state") == 0) {
 
402
                                status_updated = true;
 
403
                                textStatus->setText(pos);
 
404
                        } else if (strcmp(start, "key_mgmt") == 0) {
 
405
                                auth_updated = true;
 
406
                                textAuthentication->setText(pos);
 
407
                                /* TODO: could add EAP status to this */
 
408
                        } else if (strcmp(start, "pairwise_cipher") == 0) {
 
409
                                pairwise_cipher = pos;
 
410
                        } else if (strcmp(start, "group_cipher") == 0) {
 
411
                                group_cipher = pos;
 
412
                        }
 
413
                }
 
414
 
 
415
                if (last)
 
416
                        break;
 
417
                start = end + 1;
 
418
        }
 
419
 
 
420
        if (pairwise_cipher || group_cipher) {
 
421
                QString encr;
 
422
                if (pairwise_cipher && group_cipher &&
 
423
                    strcmp(pairwise_cipher, group_cipher) != 0) {
 
424
                        encr.append(pairwise_cipher);
 
425
                        encr.append(" + ");
 
426
                        encr.append(group_cipher);
 
427
                } else if (pairwise_cipher) {
 
428
                        encr.append(pairwise_cipher);
 
429
                } else {
 
430
                        encr.append(group_cipher);
 
431
                        encr.append(" [group key only]");
 
432
                }
 
433
                textEncryption->setText(encr);
 
434
        } else
 
435
                textEncryption->clear();
 
436
 
 
437
        if (!status_updated)
 
438
                textStatus->clear();
 
439
        if (!auth_updated)
 
440
                textAuthentication->clear();
 
441
        if (!ssid_updated)
 
442
                textSsid->clear();
 
443
        if (!bssid_updated)
 
444
                textBssid->clear();
 
445
        if (!ipaddr_updated)
 
446
                textIpAddress->clear();
 
447
}
 
448
 
 
449
 
 
450
void WpaGui::updateNetworks()
 
451
{
 
452
        char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
 
453
        size_t len;
 
454
        int first_active = -1;
 
455
        int was_selected = -1;
 
456
        bool current = false;
 
457
 
 
458
        if (!networkMayHaveChanged)
 
459
                return;
 
460
 
 
461
        if (networkList->currentRow() >= 0)
 
462
                was_selected = networkList->currentRow();
 
463
 
 
464
        networkSelect->clear();
 
465
        networkList->clear();
 
466
 
 
467
        if (ctrl_conn == NULL)
 
468
                return;
 
469
 
 
470
        len = sizeof(buf) - 1;
 
471
        if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
 
472
                return;
 
473
 
 
474
        buf[len] = '\0';
 
475
        start = strchr(buf, '\n');
 
476
        if (start == NULL)
 
477
                return;
 
478
        start++;
 
479
 
 
480
        while (*start) {
 
481
                bool last = false;
 
482
                end = strchr(start, '\n');
 
483
                if (end == NULL) {
 
484
                        last = true;
 
485
                        end = start;
 
486
                        while (end[0] && end[1])
 
487
                                end++;
 
488
                }
 
489
                *end = '\0';
 
490
 
 
491
                id = start;
 
492
                ssid = strchr(id, '\t');
 
493
                if (ssid == NULL)
 
494
                        break;
 
495
                *ssid++ = '\0';
 
496
                bssid = strchr(ssid, '\t');
 
497
                if (bssid == NULL)
 
498
                        break;
 
499
                *bssid++ = '\0';
 
500
                flags = strchr(bssid, '\t');
 
501
                if (flags == NULL)
 
502
                        break;
 
503
                *flags++ = '\0';
 
504
 
 
505
                QString network(id);
 
506
                network.append(": ");
 
507
                network.append(ssid);
 
508
                networkSelect->addItem(network);
 
509
                networkList->addItem(network);
 
510
 
 
511
                if (strstr(flags, "[CURRENT]")) {
 
512
                        networkSelect->setCurrentIndex(networkSelect->count() -
 
513
                                                      1);
 
514
                        current = true;
 
515
                } else if (first_active < 0 &&
 
516
                           strstr(flags, "[DISABLED]") == NULL)
 
517
                        first_active = networkSelect->count() - 1;
 
518
 
 
519
                if (last)
 
520
                        break;
 
521
                start = end + 1;
 
522
        }
 
523
 
 
524
        if (networkSelect->count() > 1)
 
525
                networkSelect->addItem("Select any network");
 
526
 
 
527
        if (!current && first_active >= 0)
 
528
                networkSelect->setCurrentIndex(first_active);
 
529
 
 
530
        if (was_selected >= 0 && networkList->count() > 0) {
 
531
                if (was_selected < networkList->count())
 
532
                        networkList->setCurrentRow(was_selected);
 
533
                else
 
534
                        networkList->setCurrentRow(networkList->count() - 1);
 
535
        }
 
536
        else
 
537
                networkList->setCurrentRow(networkSelect->currentIndex());
 
538
 
 
539
        networkMayHaveChanged = false;
 
540
}
 
541
 
 
542
 
 
543
void WpaGui::helpIndex()
 
544
{
 
545
        printf("helpIndex\n");
 
546
}
 
547
 
 
548
 
 
549
void WpaGui::helpContents()
 
550
{
 
551
        printf("helpContents\n");
 
552
}
 
553
 
 
554
 
 
555
void WpaGui::helpAbout()
 
556
{
 
557
        QMessageBox::about(this, "wpa_gui for wpa_supplicant",
 
558
                           "Copyright (c) 2003-2008,\n"
 
559
                           "Jouni Malinen <j@w1.fi>\n"
 
560
                           "and contributors.\n"
 
561
                           "\n"
 
562
                           "This program is free software. You can\n"
 
563
                           "distribute it and/or modify it under the terms "
 
564
                           "of\n"
 
565
                           "the GNU General Public License version 2.\n"
 
566
                           "\n"
 
567
                           "Alternatively, this software may be distributed\n"
 
568
                           "under the terms of the BSD license.\n"
 
569
                           "\n"
 
570
                           "This product includes software developed\n"
 
571
                           "by the OpenSSL Project for use in the\n"
 
572
                           "OpenSSL Toolkit (http://www.openssl.org/)\n");
 
573
}
 
574
 
 
575
 
 
576
void WpaGui::disconnect()
 
577
{
 
578
        char reply[10];
 
579
        size_t reply_len = sizeof(reply);
 
580
        ctrlRequest("DISCONNECT", reply, &reply_len);
 
581
}
 
582
 
 
583
 
 
584
void WpaGui::scan()
 
585
{
 
586
        if (scanres) {
 
587
                scanres->close();
 
588
                delete scanres;
 
589
        }
 
590
 
 
591
        scanres = new ScanResults();
 
592
        if (scanres == NULL)
 
593
                return;
 
594
        scanres->setWpaGui(this);
 
595
        scanres->show();
 
596
        scanres->exec();
 
597
}
 
598
 
 
599
 
 
600
void WpaGui::eventHistory()
 
601
{
 
602
        if (eh) {
 
603
                eh->close();
 
604
                delete eh;
 
605
        }
 
606
 
 
607
        eh = new EventHistory();
 
608
        if (eh == NULL)
 
609
                return;
 
610
        eh->addEvents(msgs);
 
611
        eh->show();
 
612
        eh->exec();
 
613
}
 
614
 
 
615
 
 
616
void WpaGui::ping()
 
617
{
 
618
        char buf[10];
 
619
        size_t len;
 
620
 
 
621
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
 
622
        /*
 
623
         * QSocketNotifier cannot be used with Windows named pipes, so use a
 
624
         * timer to check for received messages for now. This could be
 
625
         * optimized be doing something specific to named pipes or Windows
 
626
         * events, but it is not clear what would be the best way of doing that
 
627
         * in Qt.
 
628
         */
 
629
        receiveMsgs();
 
630
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 
631
 
 
632
        if (scanres && !scanres->isVisible()) {
 
633
                delete scanres;
 
634
                scanres = NULL;
 
635
        }
 
636
 
 
637
        if (eh && !eh->isVisible()) {
 
638
                delete eh;
 
639
                eh = NULL;
 
640
        }
 
641
 
 
642
        if (udr && !udr->isVisible()) {
 
643
                delete udr;
 
644
                udr = NULL;
 
645
        }
 
646
 
 
647
        len = sizeof(buf) - 1;
 
648
        if (ctrlRequest("PING", buf, &len) < 0) {
 
649
                printf("PING failed - trying to reconnect\n");
 
650
                if (openCtrlConnection(ctrl_iface) >= 0) {
 
651
                        printf("Reconnected successfully\n");
 
652
                        pingsToStatusUpdate = 0;
 
653
                }
 
654
        }
 
655
 
 
656
        pingsToStatusUpdate--;
 
657
        if (pingsToStatusUpdate <= 0) {
 
658
                updateStatus();
 
659
                updateNetworks();
 
660
        }
 
661
}
 
662
 
 
663
 
 
664
static int str_match(const char *a, const char *b)
 
665
{
 
666
        return strncmp(a, b, strlen(b)) == 0;
 
667
}
 
668
 
 
669
 
 
670
void WpaGui::processMsg(char *msg)
 
671
{
 
672
        char *pos = msg, *pos2;
 
673
        int priority = 2;
 
674
 
 
675
        if (*pos == '<') {
 
676
                /* skip priority */
 
677
                pos++;
 
678
                priority = atoi(pos);
 
679
                pos = strchr(pos, '>');
 
680
                if (pos)
 
681
                        pos++;
 
682
                else
 
683
                        pos = msg;
 
684
        }
 
685
 
 
686
        WpaMsg wm(pos, priority);
 
687
        if (eh)
 
688
                eh->addEvent(wm);
 
689
        msgs.append(wm);
 
690
        while (msgs.count() > 100)
 
691
                msgs.pop_front();
 
692
 
 
693
        /* Update last message with truncated version of the event */
 
694
        if (strncmp(pos, "CTRL-", 5) == 0) {
 
695
                pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
 
696
                if (pos2)
 
697
                        pos2++;
 
698
                else
 
699
                        pos2 = pos;
 
700
        } else
 
701
                pos2 = pos;
 
702
        QString lastmsg = pos2;
 
703
        lastmsg.truncate(40);
 
704
        textLastMessage->setText(lastmsg);
 
705
 
 
706
        pingsToStatusUpdate = 0;
 
707
        networkMayHaveChanged = true;
 
708
 
 
709
        if (str_match(pos, WPA_CTRL_REQ))
 
710
                processCtrlReq(pos + strlen(WPA_CTRL_REQ));
 
711
        else if (str_match(pos, WPA_EVENT_SCAN_RESULTS) && scanres)
 
712
                scanres->updateResults();
 
713
}
 
714
 
 
715
 
 
716
void WpaGui::processCtrlReq(const char *req)
 
717
{
 
718
        if (udr) {
 
719
                udr->close();
 
720
                delete udr;
 
721
        }
 
722
        udr = new UserDataRequest();
 
723
        if (udr == NULL)
 
724
                return;
 
725
        if (udr->setParams(this, req) < 0) {
 
726
                delete udr;
 
727
                udr = NULL;
 
728
                return;
 
729
        }
 
730
        udr->show();
 
731
        udr->exec();
 
732
}
 
733
 
 
734
 
 
735
void WpaGui::receiveMsgs()
 
736
{
 
737
        char buf[256];
 
738
        size_t len;
 
739
 
 
740
        while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
 
741
                len = sizeof(buf) - 1;
 
742
                if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
 
743
                        buf[len] = '\0';
 
744
                        processMsg(buf);
 
745
                }
 
746
        }
 
747
}
 
748
 
 
749
 
 
750
void WpaGui::connectB()
 
751
{
 
752
        char reply[10];
 
753
        size_t reply_len = sizeof(reply);
 
754
        ctrlRequest("REASSOCIATE", reply, &reply_len);
 
755
}
 
756
 
 
757
 
 
758
void WpaGui::selectNetwork( const QString &sel )
 
759
{
 
760
        QString cmd(sel);
 
761
        char reply[10];
 
762
        size_t reply_len = sizeof(reply);
 
763
 
 
764
        if (cmd.startsWith("Select any")) {
 
765
                cmd = "any";
 
766
        } else {
 
767
                int pos = cmd.indexOf(':');
 
768
                if (pos < 0) {
 
769
                        printf("Invalid selectNetwork '%s'\n",
 
770
                               cmd.toAscii().constData());
 
771
                        return;
 
772
                }
 
773
                cmd.truncate(pos);
 
774
        }
 
775
        cmd.prepend("SELECT_NETWORK ");
 
776
        ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 
777
        triggerUpdate();
 
778
}
 
779
 
 
780
 
 
781
void WpaGui::enableNetwork(const QString &sel)
 
782
{
 
783
        QString cmd(sel);
 
784
        char reply[10];
 
785
        size_t reply_len = sizeof(reply);
 
786
 
 
787
        if (!cmd.startsWith("all")) {
 
788
                int pos = cmd.indexOf(':');
 
789
                if (pos < 0) {
 
790
                        printf("Invalid enableNetwork '%s'\n",
 
791
                               cmd.toAscii().constData());
 
792
                        return;
 
793
                }
 
794
                cmd.truncate(pos);
 
795
        }
 
796
        cmd.prepend("ENABLE_NETWORK ");
 
797
        ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 
798
        triggerUpdate();
 
799
}
 
800
 
 
801
 
 
802
void WpaGui::disableNetwork(const QString &sel)
 
803
{
 
804
        QString cmd(sel);
 
805
        char reply[10];
 
806
        size_t reply_len = sizeof(reply);
 
807
 
 
808
        if (!cmd.startsWith("all")) {
 
809
                int pos = cmd.indexOf(':');
 
810
                if (pos < 0) {
 
811
                        printf("Invalid disableNetwork '%s'\n",
 
812
                               cmd.toAscii().constData());
 
813
                        return;
 
814
                }
 
815
                cmd.truncate(pos);
 
816
        }
 
817
        cmd.prepend("DISABLE_NETWORK ");
 
818
        ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 
819
        triggerUpdate();
 
820
}
 
821
 
 
822
 
 
823
void WpaGui::editNetwork(const QString &sel)
 
824
{
 
825
        QString cmd(sel);
 
826
        int id = -1;
 
827
 
 
828
        if (!cmd.startsWith("Select any")) {
 
829
                int pos = sel.indexOf(':');
 
830
                if (pos < 0) {
 
831
                        printf("Invalid editNetwork '%s'\n",
 
832
                               cmd.toAscii().constData());
 
833
                        return;
 
834
                }
 
835
                cmd.truncate(pos);
 
836
                id = cmd.toInt();
 
837
        }
 
838
 
 
839
        NetworkConfig *nc = new NetworkConfig();
 
840
        if (nc == NULL)
 
841
                return;
 
842
        nc->setWpaGui(this);
 
843
 
 
844
        if (id >= 0)
 
845
                nc->paramsFromConfig(id);
 
846
        else
 
847
                nc->newNetwork();
 
848
 
 
849
        nc->show();
 
850
        nc->exec();
 
851
}
 
852
 
 
853
 
 
854
void WpaGui::editSelectedNetwork()
 
855
{
 
856
        if (networkSelect->count() < 1) {
 
857
                QMessageBox::information(this, "No Networks",
 
858
                                         "There are no networks to edit.\n");
 
859
                return;
 
860
        }
 
861
        QString sel(networkSelect->currentText());
 
862
        editNetwork(sel);
 
863
}
 
864
 
 
865
 
 
866
void WpaGui::editListedNetwork()
 
867
{
 
868
        if (networkList->currentRow() < 0) {
 
869
                QMessageBox::information(this, "Select A Network",
 
870
                                         "Select a network from the list to"
 
871
                                         " edit it.\n");
 
872
                return;
 
873
        }
 
874
        QString sel(networkList->currentItem()->text());
 
875
        editNetwork(sel);
 
876
}
 
877
 
 
878
 
 
879
void WpaGui::triggerUpdate()
 
880
{
 
881
        updateStatus();
 
882
        networkMayHaveChanged = true;
 
883
        updateNetworks();
 
884
}
 
885
 
 
886
 
 
887
void WpaGui::addNetwork()
 
888
{
 
889
        NetworkConfig *nc = new NetworkConfig();
 
890
        if (nc == NULL)
 
891
                return;
 
892
        nc->setWpaGui(this);
 
893
        nc->newNetwork();
 
894
        nc->show();
 
895
        nc->exec();
 
896
}
 
897
 
 
898
 
 
899
void WpaGui::removeNetwork(const QString &sel)
 
900
{
 
901
        QString cmd(sel);
 
902
        char reply[10];
 
903
        size_t reply_len = sizeof(reply);
 
904
 
 
905
        if (cmd.startsWith("Select any"))
 
906
                return;
 
907
 
 
908
        if (!cmd.startsWith("all")) {
 
909
                int pos = cmd.indexOf(':');
 
910
                if (pos < 0) {
 
911
                        printf("Invalid removeNetwork '%s'\n",
 
912
                               cmd.toAscii().constData());
 
913
                        return;
 
914
                }
 
915
                cmd.truncate(pos);
 
916
        }
 
917
        cmd.prepend("REMOVE_NETWORK ");
 
918
        ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 
919
        triggerUpdate();
 
920
}
 
921
 
 
922
 
 
923
void WpaGui::removeSelectedNetwork()
 
924
{
 
925
        if (networkSelect->count() < 1) {
 
926
                QMessageBox::information(this, "No Networks",
 
927
                                         "There are no networks to remove.\n");
 
928
                return;
 
929
        }
 
930
        QString sel(networkSelect->currentText());
 
931
        removeNetwork(sel);
 
932
}
 
933
 
 
934
 
 
935
void WpaGui::removeListedNetwork()
 
936
{
 
937
        if (networkList->currentRow() < 0) {
 
938
                QMessageBox::information(this, "Select A Network",
 
939
                                         "Select a network from the list to"
 
940
                                         " remove it.\n");
 
941
                return;
 
942
        }
 
943
        QString sel(networkList->currentItem()->text());
 
944
        removeNetwork(sel);
 
945
}
 
946
 
 
947
 
 
948
void WpaGui::enableAllNetworks()
 
949
{
 
950
        QString sel("all");
 
951
        enableNetwork(sel);
 
952
}
 
953
 
 
954
 
 
955
void WpaGui::disableAllNetworks()
 
956
{
 
957
        QString sel("all");
 
958
        disableNetwork(sel);
 
959
}
 
960
 
 
961
 
 
962
void WpaGui::removeAllNetworks()
 
963
{
 
964
        QString sel("all");
 
965
        removeNetwork(sel);
 
966
}
 
967
 
 
968
 
 
969
int WpaGui::getNetworkDisabled(const QString &sel)
 
970
{
 
971
        QString cmd(sel);
 
972
        char reply[10];
 
973
        size_t reply_len = sizeof(reply) - 1;
 
974
        int pos = cmd.indexOf(':');
 
975
        if (pos < 0) {
 
976
                printf("Invalid getNetworkDisabled '%s'\n",
 
977
                       cmd.toAscii().constData());
 
978
                return -1;
 
979
        }
 
980
        cmd.truncate(pos);
 
981
        cmd.prepend("GET_NETWORK ");
 
982
        cmd.append(" disabled");
 
983
 
 
984
        if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) >= 0
 
985
            && reply_len >= 1) {
 
986
                reply[reply_len] = '\0';
 
987
                if (!str_match(reply, "FAIL"))
 
988
                        return atoi(reply);
 
989
        }
 
990
 
 
991
        return -1;
 
992
}
 
993
 
 
994
 
 
995
void WpaGui::updateNetworkDisabledStatus()
 
996
{
 
997
        if (networkList->currentRow() < 0)
 
998
                return;
 
999
 
 
1000
        QString sel(networkList->currentItem()->text());
 
1001
 
 
1002
        switch (getNetworkDisabled(sel)) {
 
1003
        case 0:
 
1004
                if (!enableRadioButton->isChecked())
 
1005
                        enableRadioButton->setChecked(true);
 
1006
                return;
 
1007
        case 1:
 
1008
                if (!disableRadioButton->isChecked())
 
1009
                        disableRadioButton->setChecked(true);
 
1010
                return;
 
1011
        }
 
1012
}
 
1013
 
 
1014
 
 
1015
void WpaGui::enableListedNetwork(bool enabled)
 
1016
{
 
1017
        if (networkList->currentRow() < 0 || !enabled)
 
1018
                return;
 
1019
 
 
1020
        QString sel(networkList->currentItem()->text());
 
1021
 
 
1022
        if (getNetworkDisabled(sel) == 1)
 
1023
                enableNetwork(sel);
 
1024
}
 
1025
 
 
1026
 
 
1027
void WpaGui::disableListedNetwork(bool disabled)
 
1028
{
 
1029
        if (networkList->currentRow() < 0 || !disabled)
 
1030
                return;
 
1031
 
 
1032
        QString sel(networkList->currentItem()->text());
 
1033
 
 
1034
        if (getNetworkDisabled(sel) == 0)
 
1035
                disableNetwork(sel);
 
1036
}
 
1037
 
 
1038
 
 
1039
void WpaGui::saveConfig()
 
1040
{
 
1041
        char buf[10];
 
1042
        size_t len;
 
1043
 
 
1044
        len = sizeof(buf) - 1;
 
1045
        ctrlRequest("SAVE_CONFIG", buf, &len);
 
1046
 
 
1047
        buf[len] = '\0';
 
1048
 
 
1049
        if (str_match(buf, "FAIL"))
 
1050
                QMessageBox::warning(this, "Failed to save configuration",
 
1051
                                     "The configuration could not be saved.\n"
 
1052
                                     "\n"
 
1053
                                     "The update_config=1 configuration option\n"
 
1054
                                     "must be used for configuration saving to\n"
 
1055
                                     "be permitted.\n");
 
1056
        else
 
1057
                QMessageBox::information(this, "Saved configuration",
 
1058
                                         "The current configuration was saved."
 
1059
                                         "\n");
 
1060
}
 
1061
 
 
1062
 
 
1063
void WpaGui::selectAdapter( const QString & sel )
 
1064
{
 
1065
        if (openCtrlConnection(sel.toAscii().constData()) < 0)
 
1066
                printf("Failed to open control connection to "
 
1067
                       "wpa_supplicant.\n");
 
1068
        updateStatus();
 
1069
        updateNetworks();
 
1070
}
 
1071
 
 
1072
 
 
1073
void WpaGui::closeEvent(QCloseEvent *event)
 
1074
{
 
1075
        if (eh) {
 
1076
                eh->close();
 
1077
                delete eh;
 
1078
                eh = NULL;
 
1079
        }
 
1080
 
 
1081
        if (scanres) {
 
1082
                scanres->close();
 
1083
                delete scanres;
 
1084
                scanres = NULL;
 
1085
        }
 
1086
 
 
1087
        if (udr) {
 
1088
                udr->close();
 
1089
                delete udr;
 
1090
                udr = NULL;
 
1091
        }
 
1092
 
 
1093
        event->accept();
 
1094
}