1 /**************************************************************************** 2 ** ui.h extension file, included from the uic-generated form implementation. 3 ** 4 ** If you want to add, delete, or rename functions or slots, use 5 ** Qt Designer to update this file, preserving your code. 6 ** 7 ** You should not define a constructor or destructor in this file. 8 ** Instead, write your code in functions called init() and destroy(). 9 ** These will automatically be called by the form's constructor and 10 ** destructor. 11 *****************************************************************************/ 12 13 #include <stdlib.h> 14 15 enum { 16 AUTH_NONE = 0, 17 AUTH_IEEE8021X = 1, 18 AUTH_WPA_PSK = 2, 19 AUTH_WPA_EAP = 3, 20 AUTH_WPA2_PSK = 4, 21 AUTH_WPA2_EAP = 5 22 }; 23 24 #define WPA_GUI_KEY_DATA "[key is configured]" 25 26 void NetworkConfig::init() 27 { 28 wpagui = NULL; 29 new_network = false; 30 } 31 32 void NetworkConfig::paramsFromScanResults(Q3ListViewItem *sel) 33 { 34 new_network = true; 35 36 /* SSID BSSID frequency signal flags */ 37 setCaption(sel->text(0)); 38 ssidEdit->setText(sel->text(0)); 39 40 QString flags = sel->text(4); 41 int auth, encr = 0; 42 if (flags.find("[WPA2-EAP") >= 0) 43 auth = AUTH_WPA2_EAP; 44 else if (flags.find("[WPA-EAP") >= 0) 45 auth = AUTH_WPA_EAP; 46 else if (flags.find("[WPA2-PSK") >= 0) 47 auth = AUTH_WPA2_PSK; 48 else if (flags.find("[WPA-PSK") >= 0) 49 auth = AUTH_WPA_PSK; 50 else 51 auth = AUTH_NONE; 52 53 if (flags.find("-CCMP") >= 0) 54 encr = 1; 55 else if (flags.find("-TKIP") >= 0) 56 encr = 0; 57 else if (flags.find("WEP") >= 0) 58 encr = 1; 59 else 60 encr = 0; 61 62 authSelect->setCurrentItem(auth); 63 authChanged(auth); 64 encrSelect->setCurrentItem(encr); 65 66 getEapCapa(); 67 } 68 69 70 void NetworkConfig::authChanged(int sel) 71 { 72 pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK); 73 bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP || 74 sel == AUTH_WPA2_EAP; 75 eapSelect->setEnabled(eap); 76 identityEdit->setEnabled(eap); 77 passwordEdit->setEnabled(eap); 78 cacertEdit->setEnabled(eap); 79 80 while (encrSelect->count()) 81 encrSelect->removeItem(0); 82 83 if (sel == AUTH_NONE || sel == AUTH_IEEE8021X) { 84 encrSelect->insertItem("None"); 85 encrSelect->insertItem("WEP"); 86 encrSelect->setCurrentItem(sel == AUTH_NONE ? 0 : 1); 87 } else { 88 encrSelect->insertItem("TKIP"); 89 encrSelect->insertItem("CCMP"); 90 encrSelect->setCurrentItem((sel == AUTH_WPA2_PSK || 91 sel == AUTH_WPA2_EAP) ? 1 : 0); 92 } 93 94 wepEnabled(sel == AUTH_IEEE8021X); 95 } 96 97 98 void NetworkConfig::addNetwork() 99 { 100 char reply[10], cmd[256]; 101 size_t reply_len; 102 int id; 103 int psklen = pskEdit->text().length(); 104 int auth = authSelect->currentItem(); 105 106 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) { 107 if (psklen < 8 || psklen > 64) { 108 QMessageBox::warning(this, "wpa_gui", "WPA-PSK requires a passphrase " 109 "of 8 to 63 characters\n" 110 "or 64 hex digit PSK"); 111 return; 112 } 113 } 114 115 if (wpagui == NULL) 116 return; 117 118 memset(reply, 0, sizeof(reply)); 119 reply_len = sizeof(reply) - 1; 120 121 if (new_network) { 122 wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len); 123 if (reply[0] == 'F') { 124 QMessageBox::warning(this, "wpa_gui", "Failed to add network to wpa_supplicant\n" 125 "configuration."); 126 return; 127 } 128 id = atoi(reply); 129 } else { 130 id = edit_network_id; 131 } 132 133 setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true); 134 135 if (idstrEdit->isEnabled()) 136 setNetworkParam(id, "id_str", idstrEdit->text().ascii(), true); 137 138 const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL; 139 switch (auth) { 140 case AUTH_NONE: 141 key_mgmt = "NONE"; 142 break; 143 case AUTH_IEEE8021X: 144 key_mgmt = "IEEE8021X"; 145 break; 146 case AUTH_WPA_PSK: 147 key_mgmt = "WPA-PSK"; 148 proto = "WPA"; 149 break; 150 case AUTH_WPA_EAP: 151 key_mgmt = "WPA-EAP"; 152 proto = "WPA"; 153 break; 154 case AUTH_WPA2_PSK: 155 key_mgmt = "WPA-PSK"; 156 proto = "WPA2"; 157 break; 158 case AUTH_WPA2_EAP: 159 key_mgmt = "WPA-EAP"; 160 proto = "WPA2"; 161 break; 162 } 163 164 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP || 165 auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) { 166 int encr = encrSelect->currentItem(); 167 if (encr == 0) 168 pairwise = "TKIP"; 169 else 170 pairwise = "CCMP"; 171 } 172 173 if (proto) 174 setNetworkParam(id, "proto", proto, false); 175 if (key_mgmt) 176 setNetworkParam(id, "key_mgmt", key_mgmt, false); 177 if (pairwise) { 178 setNetworkParam(id, "pairwise", pairwise, false); 179 setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false); 180 } 181 if (pskEdit->isEnabled() && 182 strcmp(pskEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0) 183 setNetworkParam(id, "psk", pskEdit->text().ascii(), psklen != 64); 184 if (eapSelect->isEnabled()) 185 setNetworkParam(id, "eap", eapSelect->currentText().ascii(), false); 186 if (identityEdit->isEnabled()) 187 setNetworkParam(id, "identity", identityEdit->text().ascii(), true); 188 if (passwordEdit->isEnabled() && 189 strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0) 190 setNetworkParam(id, "password", passwordEdit->text().ascii(), true); 191 if (cacertEdit->isEnabled()) 192 setNetworkParam(id, "ca_cert", cacertEdit->text().ascii(), true); 193 writeWepKey(id, wep0Edit, 0); 194 writeWepKey(id, wep1Edit, 1); 195 writeWepKey(id, wep2Edit, 2); 196 writeWepKey(id, wep3Edit, 3); 197 198 if (wep0Radio->isEnabled() && wep0Radio->isChecked()) 199 setNetworkParam(id, "wep_tx_keyidx", "0", false); 200 else if (wep1Radio->isEnabled() && wep1Radio->isChecked()) 201 setNetworkParam(id, "wep_tx_keyidx", "1", false); 202 else if (wep2Radio->isEnabled() && wep2Radio->isChecked()) 203 setNetworkParam(id, "wep_tx_keyidx", "2", false); 204 else if (wep3Radio->isEnabled() && wep3Radio->isChecked()) 205 setNetworkParam(id, "wep_tx_keyidx", "3", false); 206 207 snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id); 208 reply_len = sizeof(reply); 209 wpagui->ctrlRequest(cmd, reply, &reply_len); 210 if (strncmp(reply, "OK", 2) != 0) { 211 QMessageBox::warning(this, "wpa_gui", "Failed to enable network in wpa_supplicant\n" 212 "configuration."); 213 /* Network was added, so continue anyway */ 214 } 215 wpagui->triggerUpdate(); 216 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len); 217 218 close(); 219 } 220 221 222 void NetworkConfig::setWpaGui( WpaGui *_wpagui ) 223 { 224 wpagui = _wpagui; 225 } 226 227 228 int NetworkConfig::setNetworkParam(int id, const char *field, const char *value, bool quote) 229 { 230 char reply[10], cmd[256]; 231 size_t reply_len; 232 snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s", 233 id, field, quote ? "\"" : "", value, quote ? "\"" : ""); 234 reply_len = sizeof(reply); 235 wpagui->ctrlRequest(cmd, reply, &reply_len); 236 return strncmp(reply, "OK", 2) == 0 ? 0 : -1; 237 } 238 239 240 void NetworkConfig::encrChanged( const QString &sel ) 241 { 242 wepEnabled(sel.find("WEP") == 0); 243 } 244 245 246 void NetworkConfig::wepEnabled( bool enabled ) 247 { 248 wep0Edit->setEnabled(enabled); 249 wep1Edit->setEnabled(enabled); 250 wep2Edit->setEnabled(enabled); 251 wep3Edit->setEnabled(enabled); 252 wep0Radio->setEnabled(enabled); 253 wep1Radio->setEnabled(enabled); 254 wep2Radio->setEnabled(enabled); 255 wep3Radio->setEnabled(enabled); 256 } 257 258 259 void NetworkConfig::writeWepKey( int network_id, QLineEdit *edit, int id ) 260 { 261 char buf[10]; 262 bool hex; 263 const char *txt, *pos; 264 size_t len; 265 266 if (!edit->isEnabled() || edit->text().isEmpty()) 267 return; 268 269 /* 270 * Assume hex key if only hex characters are present and length matches 271 * with 40, 104, or 128-bit key 272 */ 273 txt = edit->text().ascii(); 274 if (strcmp(txt, WPA_GUI_KEY_DATA) == 0) 275 return; 276 len = strlen(txt); 277 if (len == 0) 278 return; 279 pos = txt; 280 hex = true; 281 while (*pos) { 282 if (!((*pos >= '0' && *pos <= '9') || (*pos >= 'a' && *pos <= 'f') || 283 (*pos >= 'A' && *pos <= 'F'))) { 284 hex = false; 285 break; 286 } 287 pos++; 288 } 289 if (hex && len != 10 && len != 26 && len != 32) 290 hex = false; 291 snprintf(buf, sizeof(buf), "wep_key%d", id); 292 setNetworkParam(network_id, buf, txt, !hex); 293 } 294 295 296 static int key_value_isset(const char *reply, size_t reply_len) 297 { 298 return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0); 299 } 300 301 302 void NetworkConfig::paramsFromConfig( int network_id ) 303 { 304 int i, res; 305 306 edit_network_id = network_id; 307 getEapCapa(); 308 309 char reply[1024], cmd[256], *pos; 310 size_t reply_len; 311 312 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id); 313 reply_len = sizeof(reply) - 1; 314 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 && 315 reply[0] == '"') { 316 reply[reply_len] = '\0'; 317 pos = strchr(reply + 1, '"'); 318 if (pos) 319 *pos = '\0'; 320 ssidEdit->setText(reply + 1); 321 } 322 323 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id); 324 reply_len = sizeof(reply) - 1; 325 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 && 326 reply[0] == '"') { 327 reply[reply_len] = '\0'; 328 pos = strchr(reply + 1, '"'); 329 if (pos) 330 *pos = '\0'; 331 idstrEdit->setText(reply + 1); 332 } 333 334 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id); 335 reply_len = sizeof(reply) - 1; 336 int wpa = 0; 337 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) { 338 reply[reply_len] = '\0'; 339 if (strstr(reply, "RSN") || strstr(reply, "WPA2")) 340 wpa = 2; 341 else if (strstr(reply, "WPA")) 342 wpa = 1; 343 } 344 345 int auth = AUTH_NONE, encr = 0; 346 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id); 347 reply_len = sizeof(reply) - 1; 348 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) { 349 reply[reply_len] = '\0'; 350 if (strstr(reply, "WPA-EAP")) 351 auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP; 352 else if (strstr(reply, "WPA-PSK")) 353 auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK; 354 else if (strstr(reply, "IEEE8021X")) { 355 auth = AUTH_IEEE8021X; 356 encr = 1; 357 } 358 } 359 360 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id); 361 reply_len = sizeof(reply) - 1; 362 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) { 363 reply[reply_len] = '\0'; 364 if (strstr(reply, "CCMP") && auth != AUTH_NONE) 365 encr = 1; 366 else if (strstr(reply, "TKIP")) 367 encr = 0; 368 else if (strstr(reply, "WEP")) 369 encr = 1; 370 else 371 encr = 0; 372 } 373 374 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id); 375 reply_len = sizeof(reply) - 1; 376 res = wpagui->ctrlRequest(cmd, reply, &reply_len); 377 if (res >= 0 && reply_len >= 2 && reply[0] == '"') { 378 reply[reply_len] = '\0'; 379 pos = strchr(reply + 1, '"'); 380 if (pos) 381 *pos = '\0'; 382 pskEdit->setText(reply + 1); 383 } else if (res >= 0 && key_value_isset(reply, reply_len)) { 384 pskEdit->setText(WPA_GUI_KEY_DATA); 385 } 386 387 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id); 388 reply_len = sizeof(reply) - 1; 389 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 && 390 reply[0] == '"') { 391 reply[reply_len] = '\0'; 392 pos = strchr(reply + 1, '"'); 393 if (pos) 394 *pos = '\0'; 395 identityEdit->setText(reply + 1); 396 } 397 398 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id); 399 reply_len = sizeof(reply) - 1; 400 res = wpagui->ctrlRequest(cmd, reply, &reply_len); 401 if (res >= 0 && reply_len >= 2 && 402 reply[0] == '"') { 403 reply[reply_len] = '\0'; 404 pos = strchr(reply + 1, '"'); 405 if (pos) 406 *pos = '\0'; 407 passwordEdit->setText(reply + 1); 408 } else if (res >= 0 && key_value_isset(reply, reply_len)) { 409 passwordEdit->setText(WPA_GUI_KEY_DATA); 410 } 411 412 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id); 413 reply_len = sizeof(reply) - 1; 414 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 && 415 reply[0] == '"') { 416 reply[reply_len] = '\0'; 417 pos = strchr(reply + 1, '"'); 418 if (pos) 419 *pos = '\0'; 420 cacertEdit->setText(reply + 1); 421 } 422 423 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id); 424 reply_len = sizeof(reply) - 1; 425 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) { 426 reply[reply_len] = '\0'; 427 for (i = 0; i < eapSelect->count(); i++) { 428 if (eapSelect->text(i).compare(reply) == 0) { 429 eapSelect->setCurrentItem(i); 430 break; 431 } 432 } 433 } 434 435 for (i = 0; i < 4; i++) { 436 QLineEdit *wepEdit; 437 switch (i) { 438 default: 439 case 0: 440 wepEdit = wep0Edit; 441 break; 442 case 1: 443 wepEdit = wep1Edit; 444 break; 445 case 2: 446 wepEdit = wep2Edit; 447 break; 448 case 3: 449 wepEdit = wep3Edit; 450 break; 451 } 452 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d", network_id, i); 453 reply_len = sizeof(reply) - 1; 454 res = wpagui->ctrlRequest(cmd, reply, &reply_len); 455 if (res >= 0 && reply_len >= 2 && reply[0] == '"') { 456 reply[reply_len] = '\0'; 457 pos = strchr(reply + 1, '"'); 458 if (pos) 459 *pos = '\0'; 460 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X) 461 encr = 1; 462 463 wepEdit->setText(reply + 1); 464 } else if (res >= 0 && key_value_isset(reply, reply_len)) { 465 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X) 466 encr = 1; 467 wepEdit->setText(WPA_GUI_KEY_DATA); 468 } 469 } 470 471 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id); 472 reply_len = sizeof(reply) - 1; 473 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) { 474 reply[reply_len] = '\0'; 475 switch (atoi(reply)) { 476 case 0: 477 wep0Radio->setChecked(true); 478 break; 479 case 1: 480 wep1Radio->setChecked(true); 481 break; 482 case 2: 483 wep2Radio->setChecked(true); 484 break; 485 case 3: 486 wep3Radio->setChecked(true); 487 break; 488 } 489 } 490 491 authSelect->setCurrentItem(auth); 492 authChanged(auth); 493 encrSelect->setCurrentItem(encr); 494 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X) 495 wepEnabled(encr == 1); 496 497 removeButton->setEnabled(true); 498 addButton->setText("Save"); 499 } 500 501 502 void NetworkConfig::removeNetwork() 503 { 504 char reply[10], cmd[256]; 505 size_t reply_len; 506 507 if (QMessageBox::information(this, "wpa_gui", 508 "This will permanently remove the network\n" 509 "from the configuration. Do you really want\n" 510 "to remove this network?", "Yes", "No") != 0) 511 return; 512 513 snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id); 514 reply_len = sizeof(reply); 515 wpagui->ctrlRequest(cmd, reply, &reply_len); 516 if (strncmp(reply, "OK", 2) != 0) { 517 QMessageBox::warning(this, "wpa_gui", 518 "Failed to remove network from wpa_supplicant\n" 519 "configuration."); 520 } else { 521 wpagui->triggerUpdate(); 522 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len); 523 } 524 525 close(); 526 } 527 528 529 void NetworkConfig::newNetwork() 530 { 531 new_network = true; 532 getEapCapa(); 533 } 534 535 536 void NetworkConfig::getEapCapa() 537 { 538 char reply[256]; 539 size_t reply_len; 540 541 if (wpagui == NULL) 542 return; 543 544 reply_len = sizeof(reply) - 1; 545 if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0) 546 return; 547 reply[reply_len] = '\0'; 548 549 QString res(reply); 550 QStringList types = QStringList::split(QChar(' '), res); 551 eapSelect->insertStringList(types); 552 } 553