00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdlib.h>
00014
00015 enum {
00016 AUTH_NONE = 0,
00017 AUTH_IEEE8021X = 1,
00018 AUTH_WPA_PSK = 2,
00019 AUTH_WPA_EAP = 3,
00020 AUTH_WPA2_PSK = 4,
00021 AUTH_WPA2_EAP = 5
00022 };
00023
00024 #define WPA_GUI_KEY_DATA "[key is configured]"
00025
00026 void NetworkConfig::init()
00027 {
00028 wpagui = NULL;
00029 new_network = false;
00030 }
00031
00032 void NetworkConfig::paramsFromScanResults(Q3ListViewItem *sel)
00033 {
00034 new_network = true;
00035
00036
00037 setCaption(sel->text(0));
00038 ssidEdit->setText(sel->text(0));
00039
00040 QString flags = sel->text(4);
00041 int auth, encr = 0;
00042 if (flags.find("[WPA2-EAP") >= 0)
00043 auth = AUTH_WPA2_EAP;
00044 else if (flags.find("[WPA-EAP") >= 0)
00045 auth = AUTH_WPA_EAP;
00046 else if (flags.find("[WPA2-PSK") >= 0)
00047 auth = AUTH_WPA2_PSK;
00048 else if (flags.find("[WPA-PSK") >= 0)
00049 auth = AUTH_WPA_PSK;
00050 else
00051 auth = AUTH_NONE;
00052
00053 if (flags.find("-CCMP") >= 0)
00054 encr = 1;
00055 else if (flags.find("-TKIP") >= 0)
00056 encr = 0;
00057 else if (flags.find("WEP") >= 0)
00058 encr = 1;
00059 else
00060 encr = 0;
00061
00062 authSelect->setCurrentItem(auth);
00063 authChanged(auth);
00064 encrSelect->setCurrentItem(encr);
00065
00066 getEapCapa();
00067 }
00068
00069
00070 void NetworkConfig::authChanged(int sel)
00071 {
00072 pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
00073 bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
00074 sel == AUTH_WPA2_EAP;
00075 eapSelect->setEnabled(eap);
00076 identityEdit->setEnabled(eap);
00077 passwordEdit->setEnabled(eap);
00078 cacertEdit->setEnabled(eap);
00079
00080 while (encrSelect->count())
00081 encrSelect->removeItem(0);
00082
00083 if (sel == AUTH_NONE || sel == AUTH_IEEE8021X) {
00084 encrSelect->insertItem("None");
00085 encrSelect->insertItem("WEP");
00086 encrSelect->setCurrentItem(sel == AUTH_NONE ? 0 : 1);
00087 } else {
00088 encrSelect->insertItem("TKIP");
00089 encrSelect->insertItem("CCMP");
00090 encrSelect->setCurrentItem((sel == AUTH_WPA2_PSK ||
00091 sel == AUTH_WPA2_EAP) ? 1 : 0);
00092 }
00093
00094 wepEnabled(sel == AUTH_IEEE8021X);
00095 }
00096
00097
00098 void NetworkConfig::addNetwork()
00099 {
00100 char reply[10], cmd[256];
00101 size_t reply_len;
00102 int id;
00103 int psklen = pskEdit->text().length();
00104 int auth = authSelect->currentItem();
00105
00106 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
00107 if (psklen < 8 || psklen > 64) {
00108 QMessageBox::warning(this, "wpa_gui", "WPA-PSK requires a passphrase "
00109 "of 8 to 63 characters\n"
00110 "or 64 hex digit PSK");
00111 return;
00112 }
00113 }
00114
00115 if (wpagui == NULL)
00116 return;
00117
00118 memset(reply, 0, sizeof(reply));
00119 reply_len = sizeof(reply) - 1;
00120
00121 if (new_network) {
00122 wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
00123 if (reply[0] == 'F') {
00124 QMessageBox::warning(this, "wpa_gui", "Failed to add network to wpa_supplicant\n"
00125 "configuration.");
00126 return;
00127 }
00128 id = atoi(reply);
00129 } else {
00130 id = edit_network_id;
00131 }
00132
00133 setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
00134
00135 if (idstrEdit->isEnabled())
00136 setNetworkParam(id, "id_str", idstrEdit->text().ascii(), true);
00137
00138 const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
00139 switch (auth) {
00140 case AUTH_NONE:
00141 key_mgmt = "NONE";
00142 break;
00143 case AUTH_IEEE8021X:
00144 key_mgmt = "IEEE8021X";
00145 break;
00146 case AUTH_WPA_PSK:
00147 key_mgmt = "WPA-PSK";
00148 proto = "WPA";
00149 break;
00150 case AUTH_WPA_EAP:
00151 key_mgmt = "WPA-EAP";
00152 proto = "WPA";
00153 break;
00154 case AUTH_WPA2_PSK:
00155 key_mgmt = "WPA-PSK";
00156 proto = "WPA2";
00157 break;
00158 case AUTH_WPA2_EAP:
00159 key_mgmt = "WPA-EAP";
00160 proto = "WPA2";
00161 break;
00162 }
00163
00164 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
00165 auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
00166 int encr = encrSelect->currentItem();
00167 if (encr == 0)
00168 pairwise = "TKIP";
00169 else
00170 pairwise = "CCMP";
00171 }
00172
00173 if (proto)
00174 setNetworkParam(id, "proto", proto, false);
00175 if (key_mgmt)
00176 setNetworkParam(id, "key_mgmt", key_mgmt, false);
00177 if (pairwise) {
00178 setNetworkParam(id, "pairwise", pairwise, false);
00179 setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
00180 }
00181 if (pskEdit->isEnabled() &&
00182 strcmp(pskEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
00183 setNetworkParam(id, "psk", pskEdit->text().ascii(), psklen != 64);
00184 if (eapSelect->isEnabled())
00185 setNetworkParam(id, "eap", eapSelect->currentText().ascii(), false);
00186 if (identityEdit->isEnabled())
00187 setNetworkParam(id, "identity", identityEdit->text().ascii(), true);
00188 if (passwordEdit->isEnabled() &&
00189 strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
00190 setNetworkParam(id, "password", passwordEdit->text().ascii(), true);
00191 if (cacertEdit->isEnabled())
00192 setNetworkParam(id, "ca_cert", cacertEdit->text().ascii(), true);
00193 writeWepKey(id, wep0Edit, 0);
00194 writeWepKey(id, wep1Edit, 1);
00195 writeWepKey(id, wep2Edit, 2);
00196 writeWepKey(id, wep3Edit, 3);
00197
00198 if (wep0Radio->isEnabled() && wep0Radio->isChecked())
00199 setNetworkParam(id, "wep_tx_keyidx", "0", false);
00200 else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
00201 setNetworkParam(id, "wep_tx_keyidx", "1", false);
00202 else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
00203 setNetworkParam(id, "wep_tx_keyidx", "2", false);
00204 else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
00205 setNetworkParam(id, "wep_tx_keyidx", "3", false);
00206
00207 snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
00208 reply_len = sizeof(reply);
00209 wpagui->ctrlRequest(cmd, reply, &reply_len);
00210 if (strncmp(reply, "OK", 2) != 0) {
00211 QMessageBox::warning(this, "wpa_gui", "Failed to enable network in wpa_supplicant\n"
00212 "configuration.");
00213
00214 }
00215 wpagui->triggerUpdate();
00216 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
00217
00218 close();
00219 }
00220
00221
00222 void NetworkConfig::setWpaGui( WpaGui *_wpagui )
00223 {
00224 wpagui = _wpagui;
00225 }
00226
00227
00228 int NetworkConfig::setNetworkParam(int id, const char *field, const char *value, bool quote)
00229 {
00230 char reply[10], cmd[256];
00231 size_t reply_len;
00232 snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
00233 id, field, quote ? "\"" : "", value, quote ? "\"" : "");
00234 reply_len = sizeof(reply);
00235 wpagui->ctrlRequest(cmd, reply, &reply_len);
00236 return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
00237 }
00238
00239
00240 void NetworkConfig::encrChanged( const QString &sel )
00241 {
00242 wepEnabled(sel.find("WEP") == 0);
00243 }
00244
00245
00246 void NetworkConfig::wepEnabled( bool enabled )
00247 {
00248 wep0Edit->setEnabled(enabled);
00249 wep1Edit->setEnabled(enabled);
00250 wep2Edit->setEnabled(enabled);
00251 wep3Edit->setEnabled(enabled);
00252 wep0Radio->setEnabled(enabled);
00253 wep1Radio->setEnabled(enabled);
00254 wep2Radio->setEnabled(enabled);
00255 wep3Radio->setEnabled(enabled);
00256 }
00257
00258
00259 void NetworkConfig::writeWepKey( int network_id, QLineEdit *edit, int id )
00260 {
00261 char buf[10];
00262 bool hex;
00263 const char *txt, *pos;
00264 size_t len;
00265
00266 if (!edit->isEnabled() || edit->text().isEmpty())
00267 return;
00268
00269
00270
00271
00272
00273 txt = edit->text().ascii();
00274 if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
00275 return;
00276 len = strlen(txt);
00277 if (len == 0)
00278 return;
00279 pos = txt;
00280 hex = true;
00281 while (*pos) {
00282 if (!((*pos >= '0' && *pos <= '9') || (*pos >= 'a' && *pos <= 'f') ||
00283 (*pos >= 'A' && *pos <= 'F'))) {
00284 hex = false;
00285 break;
00286 }
00287 pos++;
00288 }
00289 if (hex && len != 10 && len != 26 && len != 32)
00290 hex = false;
00291 snprintf(buf, sizeof(buf), "wep_key%d", id);
00292 setNetworkParam(network_id, buf, txt, !hex);
00293 }
00294
00295
00296 static int key_value_isset(const char *reply, size_t reply_len)
00297 {
00298 return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
00299 }
00300
00301
00302 void NetworkConfig::paramsFromConfig( int network_id )
00303 {
00304 int i, res;
00305
00306 edit_network_id = network_id;
00307 getEapCapa();
00308
00309 char reply[1024], cmd[256], *pos;
00310 size_t reply_len;
00311
00312 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
00313 reply_len = sizeof(reply) - 1;
00314 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
00315 reply[0] == '"') {
00316 reply[reply_len] = '\0';
00317 pos = strchr(reply + 1, '"');
00318 if (pos)
00319 *pos = '\0';
00320 ssidEdit->setText(reply + 1);
00321 }
00322
00323 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
00324 reply_len = sizeof(reply) - 1;
00325 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
00326 reply[0] == '"') {
00327 reply[reply_len] = '\0';
00328 pos = strchr(reply + 1, '"');
00329 if (pos)
00330 *pos = '\0';
00331 idstrEdit->setText(reply + 1);
00332 }
00333
00334 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
00335 reply_len = sizeof(reply) - 1;
00336 int wpa = 0;
00337 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
00338 reply[reply_len] = '\0';
00339 if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
00340 wpa = 2;
00341 else if (strstr(reply, "WPA"))
00342 wpa = 1;
00343 }
00344
00345 int auth = AUTH_NONE, encr = 0;
00346 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
00347 reply_len = sizeof(reply) - 1;
00348 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
00349 reply[reply_len] = '\0';
00350 if (strstr(reply, "WPA-EAP"))
00351 auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
00352 else if (strstr(reply, "WPA-PSK"))
00353 auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
00354 else if (strstr(reply, "IEEE8021X")) {
00355 auth = AUTH_IEEE8021X;
00356 encr = 1;
00357 }
00358 }
00359
00360 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
00361 reply_len = sizeof(reply) - 1;
00362 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
00363 reply[reply_len] = '\0';
00364 if (strstr(reply, "CCMP") && auth != AUTH_NONE)
00365 encr = 1;
00366 else if (strstr(reply, "TKIP"))
00367 encr = 0;
00368 else if (strstr(reply, "WEP"))
00369 encr = 1;
00370 else
00371 encr = 0;
00372 }
00373
00374 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
00375 reply_len = sizeof(reply) - 1;
00376 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
00377 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
00378 reply[reply_len] = '\0';
00379 pos = strchr(reply + 1, '"');
00380 if (pos)
00381 *pos = '\0';
00382 pskEdit->setText(reply + 1);
00383 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
00384 pskEdit->setText(WPA_GUI_KEY_DATA);
00385 }
00386
00387 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
00388 reply_len = sizeof(reply) - 1;
00389 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
00390 reply[0] == '"') {
00391 reply[reply_len] = '\0';
00392 pos = strchr(reply + 1, '"');
00393 if (pos)
00394 *pos = '\0';
00395 identityEdit->setText(reply + 1);
00396 }
00397
00398 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
00399 reply_len = sizeof(reply) - 1;
00400 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
00401 if (res >= 0 && reply_len >= 2 &&
00402 reply[0] == '"') {
00403 reply[reply_len] = '\0';
00404 pos = strchr(reply + 1, '"');
00405 if (pos)
00406 *pos = '\0';
00407 passwordEdit->setText(reply + 1);
00408 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
00409 passwordEdit->setText(WPA_GUI_KEY_DATA);
00410 }
00411
00412 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
00413 reply_len = sizeof(reply) - 1;
00414 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
00415 reply[0] == '"') {
00416 reply[reply_len] = '\0';
00417 pos = strchr(reply + 1, '"');
00418 if (pos)
00419 *pos = '\0';
00420 cacertEdit->setText(reply + 1);
00421 }
00422
00423 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
00424 reply_len = sizeof(reply) - 1;
00425 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
00426 reply[reply_len] = '\0';
00427 for (i = 0; i < eapSelect->count(); i++) {
00428 if (eapSelect->text(i).compare(reply) == 0) {
00429 eapSelect->setCurrentItem(i);
00430 break;
00431 }
00432 }
00433 }
00434
00435 for (i = 0; i < 4; i++) {
00436 QLineEdit *wepEdit;
00437 switch (i) {
00438 default:
00439 case 0:
00440 wepEdit = wep0Edit;
00441 break;
00442 case 1:
00443 wepEdit = wep1Edit;
00444 break;
00445 case 2:
00446 wepEdit = wep2Edit;
00447 break;
00448 case 3:
00449 wepEdit = wep3Edit;
00450 break;
00451 }
00452 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d", network_id, i);
00453 reply_len = sizeof(reply) - 1;
00454 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
00455 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
00456 reply[reply_len] = '\0';
00457 pos = strchr(reply + 1, '"');
00458 if (pos)
00459 *pos = '\0';
00460 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
00461 encr = 1;
00462
00463 wepEdit->setText(reply + 1);
00464 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
00465 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
00466 encr = 1;
00467 wepEdit->setText(WPA_GUI_KEY_DATA);
00468 }
00469 }
00470
00471 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
00472 reply_len = sizeof(reply) - 1;
00473 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
00474 reply[reply_len] = '\0';
00475 switch (atoi(reply)) {
00476 case 0:
00477 wep0Radio->setChecked(true);
00478 break;
00479 case 1:
00480 wep1Radio->setChecked(true);
00481 break;
00482 case 2:
00483 wep2Radio->setChecked(true);
00484 break;
00485 case 3:
00486 wep3Radio->setChecked(true);
00487 break;
00488 }
00489 }
00490
00491 authSelect->setCurrentItem(auth);
00492 authChanged(auth);
00493 encrSelect->setCurrentItem(encr);
00494 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
00495 wepEnabled(encr == 1);
00496
00497 removeButton->setEnabled(true);
00498 addButton->setText("Save");
00499 }
00500
00501
00502 void NetworkConfig::removeNetwork()
00503 {
00504 char reply[10], cmd[256];
00505 size_t reply_len;
00506
00507 if (QMessageBox::information(this, "wpa_gui",
00508 "This will permanently remove the network\n"
00509 "from the configuration. Do you really want\n"
00510 "to remove this network?", "Yes", "No") != 0)
00511 return;
00512
00513 snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
00514 reply_len = sizeof(reply);
00515 wpagui->ctrlRequest(cmd, reply, &reply_len);
00516 if (strncmp(reply, "OK", 2) != 0) {
00517 QMessageBox::warning(this, "wpa_gui",
00518 "Failed to remove network from wpa_supplicant\n"
00519 "configuration.");
00520 } else {
00521 wpagui->triggerUpdate();
00522 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
00523 }
00524
00525 close();
00526 }
00527
00528
00529 void NetworkConfig::newNetwork()
00530 {
00531 new_network = true;
00532 getEapCapa();
00533 }
00534
00535
00536 void NetworkConfig::getEapCapa()
00537 {
00538 char reply[256];
00539 size_t reply_len;
00540
00541 if (wpagui == NULL)
00542 return;
00543
00544 reply_len = sizeof(reply) - 1;
00545 if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
00546 return;
00547 reply[reply_len] = '\0';
00548
00549 QString res(reply);
00550 QStringList types = QStringList::split(QChar(' '), res);
00551 eapSelect->insertStringList(types);
00552 }