1 /* 2 * wpa_gui - NetworkConfig class 3 * Copyright (c) 2005-2006, Jouni Malinen <j (at) 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 #include <cstdio> 16 #include <QMessageBox> 17 18 #include "networkconfig.h" 19 #include "wpagui.h" 20 21 enum { 22 AUTH_NONE_OPEN, 23 AUTH_NONE_WEP, 24 AUTH_NONE_WEP_SHARED, 25 AUTH_IEEE8021X, 26 AUTH_WPA_PSK, 27 AUTH_WPA_EAP, 28 AUTH_WPA2_PSK, 29 AUTH_WPA2_EAP 30 }; 31 32 #define WPA_GUI_KEY_DATA "[key is configured]" 33 34 35 NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool, Qt::WFlags) 36 : QDialog(parent) 37 { 38 setupUi(this); 39 40 encrSelect->setEnabled(false); 41 connect(authSelect, SIGNAL(activated(int)), this, 42 SLOT(authChanged(int))); 43 connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); 44 connect(addButton, SIGNAL(clicked()), this, SLOT(addNetwork())); 45 connect(encrSelect, SIGNAL(activated(const QString &)), this, 46 SLOT(encrChanged(const QString &))); 47 connect(removeButton, SIGNAL(clicked()), this, SLOT(removeNetwork())); 48 connect(eapSelect, SIGNAL(activated(int)), this, 49 SLOT(eapChanged(int))); 50 connect(useWpsButton, SIGNAL(clicked()), this, SLOT(useWps())); 51 52 wpagui = NULL; 53 new_network = false; 54 } 55 56 57 NetworkConfig::~NetworkConfig() 58 { 59 } 60 61 62 void NetworkConfig::languageChange() 63 { 64 retranslateUi(this); 65 } 66 67 68 void NetworkConfig::paramsFromScanResults(QTreeWidgetItem *sel) 69 { 70 new_network = true; 71 72 /* SSID BSSID frequency signal flags */ 73 setWindowTitle(sel->text(0)); 74 ssidEdit->setText(sel->text(0)); 75 76 QString flags = sel->text(4); 77 int auth, encr = 0; 78 if (flags.indexOf("[WPA2-EAP") >= 0) 79 auth = AUTH_WPA2_EAP; 80 else if (flags.indexOf("[WPA-EAP") >= 0) 81 auth = AUTH_WPA_EAP; 82 else if (flags.indexOf("[WPA2-PSK") >= 0) 83 auth = AUTH_WPA2_PSK; 84 else if (flags.indexOf("[WPA-PSK") >= 0) 85 auth = AUTH_WPA_PSK; 86 else 87 auth = AUTH_NONE_OPEN; 88 89 if (flags.indexOf("-CCMP") >= 0) 90 encr = 1; 91 else if (flags.indexOf("-TKIP") >= 0) 92 encr = 0; 93 else if (flags.indexOf("WEP") >= 0) { 94 encr = 1; 95 if (auth == AUTH_NONE_OPEN) 96 auth = AUTH_NONE_WEP; 97 } else 98 encr = 0; 99 100 authSelect->setCurrentIndex(auth); 101 authChanged(auth); 102 encrSelect->setCurrentIndex(encr); 103 104 wepEnabled(auth == AUTH_NONE_WEP); 105 106 getEapCapa(); 107 108 if (flags.indexOf("[WPS") >= 0) 109 useWpsButton->setEnabled(true); 110 bssid = sel->text(1); 111 } 112 113 114 void NetworkConfig::authChanged(int sel) 115 { 116 encrSelect->setEnabled(sel != AUTH_NONE_OPEN && sel != AUTH_NONE_WEP && 117 sel != AUTH_NONE_WEP_SHARED); 118 pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK); 119 bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP || 120 sel == AUTH_WPA2_EAP; 121 eapSelect->setEnabled(eap); 122 identityEdit->setEnabled(eap); 123 passwordEdit->setEnabled(eap); 124 cacertEdit->setEnabled(eap); 125 phase2Select->setEnabled(eap); 126 if (eap) 127 eapChanged(eapSelect->currentIndex()); 128 129 while (encrSelect->count()) 130 encrSelect->removeItem(0); 131 132 if (sel == AUTH_NONE_OPEN || sel == AUTH_NONE_WEP || 133 sel == AUTH_NONE_WEP_SHARED || sel == AUTH_IEEE8021X) { 134 encrSelect->addItem("None"); 135 encrSelect->addItem("WEP"); 136 encrSelect->setCurrentIndex(sel == AUTH_NONE_OPEN ? 0 : 1); 137 } else { 138 encrSelect->addItem("TKIP"); 139 encrSelect->addItem("CCMP"); 140 encrSelect->setCurrentIndex((sel == AUTH_WPA2_PSK || 141 sel == AUTH_WPA2_EAP) ? 1 : 0); 142 } 143 144 wepEnabled(sel == AUTH_NONE_WEP || sel == AUTH_NONE_WEP_SHARED); 145 } 146 147 148 void NetworkConfig::eapChanged(int sel) 149 { 150 QString prev_val = phase2Select->currentText(); 151 while (phase2Select->count()) 152 phase2Select->removeItem(0); 153 154 QStringList inner; 155 inner << "PEAP" << "TTLS" << "FAST"; 156 if (!inner.contains(eapSelect->itemText(sel))) 157 return; 158 159 phase2Select->addItem("[ any ]"); 160 161 /* Add special cases based on outer method */ 162 if (eapSelect->currentText().compare("TTLS") == 0) { 163 phase2Select->addItem("PAP"); 164 phase2Select->addItem("CHAP"); 165 phase2Select->addItem("MSCHAP"); 166 phase2Select->addItem("MSCHAPv2"); 167 } else if (eapSelect->currentText().compare("FAST") == 0) 168 phase2Select->addItem("GTC(auth) + MSCHAPv2(prov)"); 169 170 /* Add all enabled EAP methods that can be used in the tunnel */ 171 int i; 172 QStringList allowed; 173 allowed << "MSCHAPV2" << "MD5" << "GTC" << "TLS" << "OTP" << "SIM" 174 << "AKA"; 175 for (i = 0; i < eapSelect->count(); i++) { 176 if (allowed.contains(eapSelect->itemText(i))) { 177 phase2Select->addItem("EAP-" + eapSelect->itemText(i)); 178 } 179 } 180 181 for (i = 0; i < phase2Select->count(); i++) { 182 if (phase2Select->itemText(i).compare(prev_val) == 0) { 183 phase2Select->setCurrentIndex(i); 184 break; 185 } 186 } 187 } 188 189 190 void NetworkConfig::addNetwork() 191 { 192 char reply[10], cmd[256]; 193 size_t reply_len; 194 int id; 195 int psklen = pskEdit->text().length(); 196 int auth = authSelect->currentIndex(); 197 198 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) { 199 if (psklen < 8 || psklen > 64) { 200 QMessageBox::warning( 201 this, 202 tr("WPA Pre-Shared Key Error"), 203 tr("WPA-PSK requires a passphrase of 8 to 63 " 204 "characters\n" 205 "or 64 hex digit PSK")); 206 pskEdit->setFocus(); 207 return; 208 } 209 } 210 211 if (idstrEdit->isEnabled() && !idstrEdit->text().isEmpty()) { 212 QRegExp rx("^(\\w|-)+$"); 213 if (rx.indexIn(idstrEdit->text()) < 0) { 214 QMessageBox::warning( 215 this, tr("Network ID Error"), 216 tr("Network ID String contains non-word " 217 "characters.\n" 218 "It must be a simple string, " 219 "without spaces, containing\n" 220 "only characters in this range: " 221 "[A-Za-z0-9_-]\n")); 222 idstrEdit->setFocus(); 223 return; 224 } 225 } 226 227 if (wpagui == NULL) 228 return; 229 230 memset(reply, 0, sizeof(reply)); 231 reply_len = sizeof(reply) - 1; 232 233 if (new_network) { 234 wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len); 235 if (reply[0] == 'F') { 236 QMessageBox::warning(this, "wpa_gui", 237 tr("Failed to add " 238 "network to wpa_supplicant\n" 239 "configuration.")); 240 return; 241 } 242 id = atoi(reply); 243 } else 244 id = edit_network_id; 245 246 setNetworkParam(id, "ssid", ssidEdit->text().toAscii().constData(), 247 true); 248 249 const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL; 250 switch (auth) { 251 case AUTH_NONE_OPEN: 252 case AUTH_NONE_WEP: 253 case AUTH_NONE_WEP_SHARED: 254 key_mgmt = "NONE"; 255 break; 256 case AUTH_IEEE8021X: 257 key_mgmt = "IEEE8021X"; 258 break; 259 case AUTH_WPA_PSK: 260 key_mgmt = "WPA-PSK"; 261 proto = "WPA"; 262 break; 263 case AUTH_WPA_EAP: 264 key_mgmt = "WPA-EAP"; 265 proto = "WPA"; 266 break; 267 case AUTH_WPA2_PSK: 268 key_mgmt = "WPA-PSK"; 269 proto = "WPA2"; 270 break; 271 case AUTH_WPA2_EAP: 272 key_mgmt = "WPA-EAP"; 273 proto = "WPA2"; 274 break; 275 } 276 277 if (auth == AUTH_NONE_WEP_SHARED) 278 setNetworkParam(id, "auth_alg", "SHARED", false); 279 else 280 setNetworkParam(id, "auth_alg", "OPEN", false); 281 282 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP || 283 auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) { 284 int encr = encrSelect->currentIndex(); 285 if (encr == 0) 286 pairwise = "TKIP"; 287 else 288 pairwise = "CCMP"; 289 } 290 291 if (proto) 292 setNetworkParam(id, "proto", proto, false); 293 if (key_mgmt) 294 setNetworkParam(id, "key_mgmt", key_mgmt, false); 295 if (pairwise) { 296 setNetworkParam(id, "pairwise", pairwise, false); 297 setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false); 298 } 299 if (pskEdit->isEnabled() && 300 strcmp(pskEdit->text().toAscii().constData(), 301 WPA_GUI_KEY_DATA) != 0) 302 setNetworkParam(id, "psk", 303 pskEdit->text().toAscii().constData(), 304 psklen != 64); 305 if (eapSelect->isEnabled()) { 306 const char *eap = 307 eapSelect->currentText().toAscii().constData(); 308 setNetworkParam(id, "eap", eap, false); 309 if (strcmp(eap, "SIM") == 0 || strcmp(eap, "AKA") == 0) 310 setNetworkParam(id, "pcsc", "", true); 311 else 312 setNetworkParam(id, "pcsc", "NULL", false); 313 } 314 if (phase2Select->isEnabled()) { 315 QString eap = eapSelect->currentText(); 316 QString inner = phase2Select->currentText(); 317 char phase2[32]; 318 phase2[0] = '\0'; 319 if (eap.compare("PEAP") == 0) { 320 if (inner.startsWith("EAP-")) 321 snprintf(phase2, sizeof(phase2), "auth=%s", 322 inner.right(inner.size() - 4). 323 toAscii().constData()); 324 } else if (eap.compare("TTLS") == 0) { 325 if (inner.startsWith("EAP-")) 326 snprintf(phase2, sizeof(phase2), "autheap=%s", 327 inner.right(inner.size() - 4). 328 toAscii().constData()); 329 else 330 snprintf(phase2, sizeof(phase2), "auth=%s", 331 inner.toAscii().constData()); 332 } else if (eap.compare("FAST") == 0) { 333 const char *provisioning = NULL; 334 if (inner.startsWith("EAP-")) { 335 snprintf(phase2, sizeof(phase2), "auth=%s", 336 inner.right(inner.size() - 4). 337 toAscii().constData()); 338 provisioning = "fast_provisioning=2"; 339 } else if (inner.compare("GTC(auth) + MSCHAPv2(prov)") 340 == 0) { 341 snprintf(phase2, sizeof(phase2), 342 "auth=GTC auth=MSCHAPV2"); 343 provisioning = "fast_provisioning=1"; 344 } else 345 provisioning = "fast_provisioning=3"; 346 if (provisioning) { 347 char blob[32]; 348 setNetworkParam(id, "phase1", provisioning, 349 true); 350 snprintf(blob, sizeof(blob), 351 "blob://fast-pac-%d", id); 352 setNetworkParam(id, "pac_file", blob, true); 353 } 354 } 355 if (phase2[0]) 356 setNetworkParam(id, "phase2", phase2, true); 357 else 358 setNetworkParam(id, "phase2", "NULL", false); 359 } else 360 setNetworkParam(id, "phase2", "NULL", false); 361 if (identityEdit->isEnabled() && identityEdit->text().length() > 0) 362 setNetworkParam(id, "identity", 363 identityEdit->text().toAscii().constData(), 364 true); 365 else 366 setNetworkParam(id, "identity", "NULL", false); 367 if (passwordEdit->isEnabled() && passwordEdit->text().length() > 0 && 368 strcmp(passwordEdit->text().toAscii().constData(), 369 WPA_GUI_KEY_DATA) != 0) 370 setNetworkParam(id, "password", 371 passwordEdit->text().toAscii().constData(), 372 true); 373 else if (passwordEdit->text().length() == 0) 374 setNetworkParam(id, "password", "NULL", false); 375 if (cacertEdit->isEnabled() && cacertEdit->text().length() > 0) 376 setNetworkParam(id, "ca_cert", 377 cacertEdit->text().toAscii().constData(), 378 true); 379 else 380 setNetworkParam(id, "ca_cert", "NULL", false); 381 writeWepKey(id, wep0Edit, 0); 382 writeWepKey(id, wep1Edit, 1); 383 writeWepKey(id, wep2Edit, 2); 384 writeWepKey(id, wep3Edit, 3); 385 386 if (wep0Radio->isEnabled() && wep0Radio->isChecked()) 387 setNetworkParam(id, "wep_tx_keyidx", "0", false); 388 else if (wep1Radio->isEnabled() && wep1Radio->isChecked()) 389 setNetworkParam(id, "wep_tx_keyidx", "1", false); 390 else if (wep2Radio->isEnabled() && wep2Radio->isChecked()) 391 setNetworkParam(id, "wep_tx_keyidx", "2", false); 392 else if (wep3Radio->isEnabled() && wep3Radio->isChecked()) 393 setNetworkParam(id, "wep_tx_keyidx", "3", false); 394 395 if (idstrEdit->isEnabled() && idstrEdit->text().length() > 0) 396 setNetworkParam(id, "id_str", 397 idstrEdit->text().toAscii().constData(), 398 true); 399 else 400 setNetworkParam(id, "id_str", "NULL", false); 401 402 if (prioritySpinBox->isEnabled()) { 403 QString prio; 404 prio = prio.setNum(prioritySpinBox->value()); 405 setNetworkParam(id, "priority", prio.toAscii().constData(), 406 false); 407 } 408 409 snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id); 410 reply_len = sizeof(reply); 411 wpagui->ctrlRequest(cmd, reply, &reply_len); 412 if (strncmp(reply, "OK", 2) != 0) { 413 QMessageBox::warning(this, "wpa_gui", 414 tr("Failed to enable " 415 "network in wpa_supplicant\n" 416 "configuration.")); 417 /* Network was added, so continue anyway */ 418 } 419 wpagui->triggerUpdate(); 420 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len); 421 422 close(); 423 } 424 425 426 void NetworkConfig::setWpaGui(WpaGui *_wpagui) 427 { 428 wpagui = _wpagui; 429 } 430 431 432 int NetworkConfig::setNetworkParam(int id, const char *field, 433 const char *value, bool quote) 434 { 435 char reply[10], cmd[256]; 436 size_t reply_len; 437 snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s", 438 id, field, quote ? "\"" : "", value, quote ? "\"" : ""); 439 reply_len = sizeof(reply); 440 wpagui->ctrlRequest(cmd, reply, &reply_len); 441 return strncmp(reply, "OK", 2) == 0 ? 0 : -1; 442 } 443 444 445 void NetworkConfig::encrChanged(const QString &) 446 { 447 } 448 449 450 void NetworkConfig::wepEnabled(bool enabled) 451 { 452 wep0Edit->setEnabled(enabled); 453 wep1Edit->setEnabled(enabled); 454 wep2Edit->setEnabled(enabled); 455 wep3Edit->setEnabled(enabled); 456 wep0Radio->setEnabled(enabled); 457 wep1Radio->setEnabled(enabled); 458 wep2Radio->setEnabled(enabled); 459 wep3Radio->setEnabled(enabled); 460 } 461 462 463 void NetworkConfig::writeWepKey(int network_id, QLineEdit *edit, int id) 464 { 465 char buf[10]; 466 bool hex; 467 const char *txt, *pos; 468 size_t len; 469 470 if (!edit->isEnabled() || edit->text().isEmpty()) 471 return; 472 473 /* 474 * Assume hex key if only hex characters are present and length matches 475 * with 40, 104, or 128-bit key 476 */ 477 txt = edit->text().toAscii().constData(); 478 if (strcmp(txt, WPA_GUI_KEY_DATA) == 0) 479 return; 480 len = strlen(txt); 481 if (len == 0) 482 return; 483 pos = txt; 484 hex = true; 485 while (*pos) { 486 if (!((*pos >= '0' && *pos <= '9') || 487 (*pos >= 'a' && *pos <= 'f') || 488 (*pos >= 'A' && *pos <= 'F'))) { 489 hex = false; 490 break; 491 } 492 pos++; 493 } 494 if (hex && len != 10 && len != 26 && len != 32) 495 hex = false; 496 snprintf(buf, sizeof(buf), "wep_key%d", id); 497 setNetworkParam(network_id, buf, txt, !hex); 498 } 499 500 501 static int key_value_isset(const char *reply, size_t reply_len) 502 { 503 return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0); 504 } 505 506 507 void NetworkConfig::paramsFromConfig(int network_id) 508 { 509 int i, res; 510 511 edit_network_id = network_id; 512 getEapCapa(); 513 514 char reply[1024], cmd[256], *pos; 515 size_t reply_len; 516 517 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id); 518 reply_len = sizeof(reply) - 1; 519 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && 520 reply_len >= 2 && reply[0] == '"') { 521 reply[reply_len] = '\0'; 522 pos = strchr(reply + 1, '"'); 523 if (pos) 524 *pos = '\0'; 525 ssidEdit->setText(reply + 1); 526 } 527 528 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id); 529 reply_len = sizeof(reply) - 1; 530 int wpa = 0; 531 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) { 532 reply[reply_len] = '\0'; 533 if (strstr(reply, "RSN") || strstr(reply, "WPA2")) 534 wpa = 2; 535 else if (strstr(reply, "WPA")) 536 wpa = 1; 537 } 538 539 int auth = AUTH_NONE_OPEN, encr = 0; 540 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id); 541 reply_len = sizeof(reply) - 1; 542 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) { 543 reply[reply_len] = '\0'; 544 if (strstr(reply, "WPA-EAP")) 545 auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP; 546 else if (strstr(reply, "WPA-PSK")) 547 auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK; 548 else if (strstr(reply, "IEEE8021X")) { 549 auth = AUTH_IEEE8021X; 550 encr = 1; 551 } 552 } 553 554 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id); 555 reply_len = sizeof(reply) - 1; 556 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) { 557 reply[reply_len] = '\0'; 558 if (strstr(reply, "CCMP") && auth != AUTH_NONE_OPEN && 559 auth != AUTH_NONE_WEP && auth != AUTH_NONE_WEP_SHARED) 560 encr = 1; 561 else if (strstr(reply, "TKIP")) 562 encr = 0; 563 else if (strstr(reply, "WEP")) 564 encr = 1; 565 else 566 encr = 0; 567 } 568 569 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id); 570 reply_len = sizeof(reply) - 1; 571 res = wpagui->ctrlRequest(cmd, reply, &reply_len); 572 if (res >= 0 && reply_len >= 2 && reply[0] == '"') { 573 reply[reply_len] = '\0'; 574 pos = strchr(reply + 1, '"'); 575 if (pos) 576 *pos = '\0'; 577 pskEdit->setText(reply + 1); 578 } else if (res >= 0 && key_value_isset(reply, reply_len)) { 579 pskEdit->setText(WPA_GUI_KEY_DATA); 580 } 581 582 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id); 583 reply_len = sizeof(reply) - 1; 584 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && 585 reply_len >= 2 && reply[0] == '"') { 586 reply[reply_len] = '\0'; 587 pos = strchr(reply + 1, '"'); 588 if (pos) 589 *pos = '\0'; 590 identityEdit->setText(reply + 1); 591 } 592 593 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id); 594 reply_len = sizeof(reply) - 1; 595 res = wpagui->ctrlRequest(cmd, reply, &reply_len); 596 if (res >= 0 && reply_len >= 2 && reply[0] == '"') { 597 reply[reply_len] = '\0'; 598 pos = strchr(reply + 1, '"'); 599 if (pos) 600 *pos = '\0'; 601 passwordEdit->setText(reply + 1); 602 } else if (res >= 0 && key_value_isset(reply, reply_len)) { 603 passwordEdit->setText(WPA_GUI_KEY_DATA); 604 } 605 606 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id); 607 reply_len = sizeof(reply) - 1; 608 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && 609 reply_len >= 2 && reply[0] == '"') { 610 reply[reply_len] = '\0'; 611 pos = strchr(reply + 1, '"'); 612 if (pos) 613 *pos = '\0'; 614 cacertEdit->setText(reply + 1); 615 } 616 617 enum { NO_INNER, PEAP_INNER, TTLS_INNER, FAST_INNER } eap = NO_INNER; 618 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id); 619 reply_len = sizeof(reply) - 1; 620 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && 621 reply_len >= 1) { 622 reply[reply_len] = '\0'; 623 for (i = 0; i < eapSelect->count(); i++) { 624 if (eapSelect->itemText(i).compare(reply) == 0) { 625 eapSelect->setCurrentIndex(i); 626 if (strcmp(reply, "PEAP") == 0) 627 eap = PEAP_INNER; 628 else if (strcmp(reply, "TTLS") == 0) 629 eap = TTLS_INNER; 630 else if (strcmp(reply, "FAST") == 0) 631 eap = FAST_INNER; 632 break; 633 } 634 } 635 } 636 637 if (eap != NO_INNER) { 638 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d phase2", 639 network_id); 640 reply_len = sizeof(reply) - 1; 641 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && 642 reply_len >= 1) { 643 reply[reply_len] = '\0'; 644 eapChanged(eapSelect->currentIndex()); 645 } else 646 eap = NO_INNER; 647 } 648 649 char *val; 650 val = reply + 1; 651 while (*(val + 1)) 652 val++; 653 if (*val == '"') 654 *val = '\0'; 655 656 switch (eap) { 657 case PEAP_INNER: 658 if (strncmp(reply, "\"auth=", 6)) 659 break; 660 val = reply + 2; 661 memcpy(val, "EAP-", 4); 662 break; 663 case TTLS_INNER: 664 if (strncmp(reply, "\"autheap=", 9) == 0) { 665 val = reply + 5; 666 memcpy(val, "EAP-", 4); 667 } else if (strncmp(reply, "\"auth=", 6) == 0) 668 val = reply + 6; 669 break; 670 case FAST_INNER: 671 if (strncmp(reply, "\"auth=", 6)) 672 break; 673 if (strcmp(reply + 6, "GTC auth=MSCHAPV2") == 0) { 674 val = (char *) "GTC(auth) + MSCHAPv2(prov)"; 675 break; 676 } 677 val = reply + 2; 678 memcpy(val, "EAP-", 4); 679 break; 680 case NO_INNER: 681 break; 682 } 683 684 for (i = 0; i < phase2Select->count(); i++) { 685 if (phase2Select->itemText(i).compare(val) == 0) { 686 phase2Select->setCurrentIndex(i); 687 break; 688 } 689 } 690 691 for (i = 0; i < 4; i++) { 692 QLineEdit *wepEdit; 693 switch (i) { 694 default: 695 case 0: 696 wepEdit = wep0Edit; 697 break; 698 case 1: 699 wepEdit = wep1Edit; 700 break; 701 case 2: 702 wepEdit = wep2Edit; 703 break; 704 case 3: 705 wepEdit = wep3Edit; 706 break; 707 } 708 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d", 709 network_id, i); 710 reply_len = sizeof(reply) - 1; 711 res = wpagui->ctrlRequest(cmd, reply, &reply_len); 712 if (res >= 0 && reply_len >= 2 && reply[0] == '"') { 713 reply[reply_len] = '\0'; 714 pos = strchr(reply + 1, '"'); 715 if (pos) 716 *pos = '\0'; 717 if (auth == AUTH_NONE_OPEN || auth == AUTH_IEEE8021X) { 718 if (auth == AUTH_NONE_OPEN) 719 auth = AUTH_NONE_WEP; 720 encr = 1; 721 } 722 723 wepEdit->setText(reply + 1); 724 } else if (res >= 0 && key_value_isset(reply, reply_len)) { 725 if (auth == AUTH_NONE_OPEN || auth == AUTH_IEEE8021X) { 726 if (auth == AUTH_NONE_OPEN) 727 auth = AUTH_NONE_WEP; 728 encr = 1; 729 } 730 wepEdit->setText(WPA_GUI_KEY_DATA); 731 } 732 } 733 734 if (auth == AUTH_NONE_WEP) { 735 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d auth_alg", 736 network_id); 737 reply_len = sizeof(reply) - 1; 738 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) { 739 reply[reply_len] = '\0'; 740 if (strcmp(reply, "SHARED") == 0) 741 auth = AUTH_NONE_WEP_SHARED; 742 } 743 } 744 745 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id); 746 reply_len = sizeof(reply) - 1; 747 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) 748 { 749 reply[reply_len] = '\0'; 750 switch (atoi(reply)) { 751 case 0: 752 wep0Radio->setChecked(true); 753 break; 754 case 1: 755 wep1Radio->setChecked(true); 756 break; 757 case 2: 758 wep2Radio->setChecked(true); 759 break; 760 case 3: 761 wep3Radio->setChecked(true); 762 break; 763 } 764 } 765 766 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id); 767 reply_len = sizeof(reply) - 1; 768 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && 769 reply_len >= 2 && reply[0] == '"') { 770 reply[reply_len] = '\0'; 771 pos = strchr(reply + 1, '"'); 772 if (pos) 773 *pos = '\0'; 774 idstrEdit->setText(reply + 1); 775 } 776 777 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d priority", network_id); 778 reply_len = sizeof(reply) - 1; 779 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) 780 { 781 reply[reply_len] = '\0'; 782 prioritySpinBox->setValue(atoi(reply)); 783 } 784 785 authSelect->setCurrentIndex(auth); 786 authChanged(auth); 787 encrSelect->setCurrentIndex(encr); 788 wepEnabled(auth == AUTH_NONE_WEP || auth == AUTH_NONE_WEP_SHARED); 789 790 removeButton->setEnabled(true); 791 addButton->setText("Save"); 792 } 793 794 795 void NetworkConfig::removeNetwork() 796 { 797 char reply[10], cmd[256]; 798 size_t reply_len; 799 800 if (QMessageBox::information( 801 this, "wpa_gui", 802 tr("This will permanently remove the network\n" 803 "from the configuration. Do you really want\n" 804 "to remove this network?"), 805 tr("Yes"), tr("No")) != 0) 806 return; 807 808 snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id); 809 reply_len = sizeof(reply); 810 wpagui->ctrlRequest(cmd, reply, &reply_len); 811 if (strncmp(reply, "OK", 2) != 0) { 812 QMessageBox::warning(this, "wpa_gui", 813 tr("Failed to remove network from " 814 "wpa_supplicant\n" 815 "configuration.")); 816 } else { 817 wpagui->triggerUpdate(); 818 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len); 819 } 820 821 close(); 822 } 823 824 825 void NetworkConfig::newNetwork() 826 { 827 new_network = true; 828 getEapCapa(); 829 } 830 831 832 void NetworkConfig::getEapCapa() 833 { 834 char reply[256]; 835 size_t reply_len; 836 837 if (wpagui == NULL) 838 return; 839 840 reply_len = sizeof(reply) - 1; 841 if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0) 842 return; 843 reply[reply_len] = '\0'; 844 845 QString res(reply); 846 QStringList types = res.split(QChar(' ')); 847 eapSelect->insertItems(-1, types); 848 } 849 850 851 void NetworkConfig::useWps() 852 { 853 if (wpagui == NULL) 854 return; 855 wpagui->setBssFromScan(bssid); 856 wpagui->wpsDialog(); 857 close(); 858 } 859