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