Home | History | Annotate | Download | only in wpa_gui
      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