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     const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
    136     switch (auth) {
    137     case AUTH_NONE:
    138 	key_mgmt = "NONE";
    139 	break;
    140     case AUTH_IEEE8021X:
    141 	key_mgmt = "IEEE8021X";
    142 	break;
    143     case AUTH_WPA_PSK:
    144 	key_mgmt = "WPA-PSK";
    145 	proto = "WPA";
    146 	break;
    147     case AUTH_WPA_EAP:
    148 	key_mgmt = "WPA-EAP";
    149 	proto = "WPA";
    150 	break;
    151     case AUTH_WPA2_PSK:
    152 	key_mgmt = "WPA-PSK";
    153 	proto = "WPA2";
    154 	break;
    155     case AUTH_WPA2_EAP:
    156 	key_mgmt = "WPA-EAP";
    157 	proto = "WPA2";
    158 	break;
    159     }
    160 
    161     if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
    162 	auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
    163 	int encr = encrSelect->currentItem();
    164 	if (encr == 0)
    165 	    pairwise = "TKIP";
    166 	else
    167 	    pairwise = "CCMP";
    168     }
    169 
    170     if (proto)
    171 	setNetworkParam(id, "proto", proto, false);
    172     if (key_mgmt)
    173 	setNetworkParam(id, "key_mgmt", key_mgmt, false);
    174     if (pairwise) {
    175 	setNetworkParam(id, "pairwise", pairwise, false);
    176 	setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
    177     }
    178     if (pskEdit->isEnabled() &&
    179 	strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
    180 	setNetworkParam(id, "psk", pskEdit->text().ascii(), psklen != 64);
    181     if (eapSelect->isEnabled())
    182 	setNetworkParam(id, "eap", eapSelect->currentText().ascii(), false);
    183     if (identityEdit->isEnabled())
    184 	setNetworkParam(id, "identity", identityEdit->text().ascii(), true);
    185     if (passwordEdit->isEnabled() &&
    186 	strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
    187 	setNetworkParam(id, "password", passwordEdit->text().ascii(), true);
    188     if (cacertEdit->isEnabled())
    189 	setNetworkParam(id, "ca_cert", cacertEdit->text().ascii(), true);
    190     writeWepKey(id, wep0Edit, 0);
    191     writeWepKey(id, wep1Edit, 1);
    192     writeWepKey(id, wep2Edit, 2);
    193     writeWepKey(id, wep3Edit, 3);
    194 
    195     if (wep0Radio->isEnabled() && wep0Radio->isChecked())
    196 	setNetworkParam(id, "wep_tx_keyidx", "0", false);
    197     else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
    198 	setNetworkParam(id, "wep_tx_keyidx", "1", false);
    199     else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
    200 	setNetworkParam(id, "wep_tx_keyidx", "2", false);
    201     else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
    202 	setNetworkParam(id, "wep_tx_keyidx", "3", false);
    203 
    204     snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
    205     reply_len = sizeof(reply);
    206     wpagui->ctrlRequest(cmd, reply, &reply_len);
    207     if (strncmp(reply, "OK", 2) != 0) {
    208 	QMessageBox::warning(this, "wpa_gui", "Failed to enable network in wpa_supplicant\n"
    209 			     "configuration.");
    210 	/* Network was added, so continue anyway */
    211     }
    212     wpagui->triggerUpdate();
    213     wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
    214 
    215     close();
    216 }
    217 
    218 
    219 void NetworkConfig::setWpaGui( WpaGui *_wpagui )
    220 {
    221     wpagui = _wpagui;
    222 }
    223 
    224 
    225 int NetworkConfig::setNetworkParam(int id, const char *field, const char *value, bool quote)
    226 {
    227     char reply[10], cmd[256];
    228     size_t reply_len;
    229     snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
    230 	     id, field, quote ? "\"" : "", value, quote ? "\"" : "");
    231     reply_len = sizeof(reply);
    232     wpagui->ctrlRequest(cmd, reply, &reply_len);
    233     return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
    234 }
    235 
    236 
    237 void NetworkConfig::encrChanged( const QString &sel )
    238 {
    239     wepEnabled(sel.find("WEP") == 0);
    240 }
    241 
    242 
    243 void NetworkConfig::wepEnabled( bool enabled )
    244 {
    245     wep0Edit->setEnabled(enabled);
    246     wep1Edit->setEnabled(enabled);
    247     wep2Edit->setEnabled(enabled);
    248     wep3Edit->setEnabled(enabled);
    249     wep0Radio->setEnabled(enabled);
    250     wep1Radio->setEnabled(enabled);
    251     wep2Radio->setEnabled(enabled);
    252     wep3Radio->setEnabled(enabled);
    253 }
    254 
    255 
    256 void NetworkConfig::writeWepKey( int network_id, QLineEdit *edit, int id )
    257 {
    258     char buf[10];
    259     bool hex;
    260     const char *txt, *pos;
    261     size_t len;
    262 
    263     if (!edit->isEnabled() || edit->text().isEmpty())
    264 	return;
    265 
    266     /*
    267         * Assume hex key if only hex characters are present and length matches
    268        * with 40, 104, or 128-bit key
    269        */
    270     txt = edit->text().ascii();
    271     if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
    272 	return;
    273     len = strlen(txt);
    274     if (len == 0)
    275 	return;
    276     pos = txt;
    277     hex = true;
    278     while (*pos) {
    279 	if (!((*pos >= '0' && *pos <= '9') || (*pos >= 'a' && *pos <= 'f') ||
    280 	      (*pos >= 'A' && *pos <= 'F'))) {
    281 	    hex = false;
    282 	    break;
    283 	}
    284 	pos++;
    285     }
    286     if (hex && len != 10 && len != 26 && len != 32)
    287 	hex = false;
    288     snprintf(buf, sizeof(buf), "wep_key%d", id);
    289     setNetworkParam(network_id, buf, txt, !hex);
    290 }
    291 
    292 
    293 static int key_value_isset(const char *reply, size_t reply_len)
    294 {
    295     return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
    296 }
    297 
    298 
    299 void NetworkConfig::paramsFromConfig( int network_id )
    300 {
    301     int i, res;
    302 
    303     edit_network_id = network_id;
    304     getEapCapa();
    305 
    306     char reply[1024], cmd[256], *pos;
    307     size_t reply_len;
    308 
    309     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
    310     reply_len = sizeof(reply) - 1;
    311     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
    312 	reply[0] == '"') {
    313 	reply[reply_len] = '\0';
    314 	pos = strchr(reply + 1, '"');
    315 	if (pos)
    316 	    *pos = '\0';
    317 	ssidEdit->setText(reply + 1);
    318     }
    319 
    320     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
    321     reply_len = sizeof(reply) - 1;
    322     int wpa = 0;
    323     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
    324 	reply[reply_len] = '\0';
    325 	if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
    326 	    wpa = 2;
    327 	else if (strstr(reply, "WPA"))
    328 	    wpa = 1;
    329     }
    330 
    331     int auth = AUTH_NONE, encr = 0;
    332     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
    333     reply_len = sizeof(reply) - 1;
    334     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
    335 	reply[reply_len] = '\0';
    336 	if (strstr(reply, "WPA-EAP"))
    337 	    auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
    338 	else if (strstr(reply, "WPA-PSK"))
    339 	    auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
    340 	else if (strstr(reply, "IEEE8021X")) {
    341 	    auth = AUTH_IEEE8021X;
    342 	    encr = 1;
    343 	}
    344     }
    345 
    346     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", 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, "CCMP"))
    351 	    encr = 1;
    352 	else if (strstr(reply, "TKIP"))
    353 	    encr = 0;
    354 	else if (strstr(reply, "WEP"))
    355 	    encr = 1;
    356 	else
    357 	    encr = 0;
    358     }
    359 
    360     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
    361     reply_len = sizeof(reply) - 1;
    362     res = wpagui->ctrlRequest(cmd, reply, &reply_len);
    363     if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
    364 	reply[reply_len] = '\0';
    365 	pos = strchr(reply + 1, '"');
    366 	if (pos)
    367 	    *pos = '\0';
    368 	pskEdit->setText(reply + 1);
    369     } else if (res >= 0 && key_value_isset(reply, reply_len)) {
    370 	pskEdit->setText(WPA_GUI_KEY_DATA);
    371     }
    372 
    373     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
    374     reply_len = sizeof(reply) - 1;
    375     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
    376 	reply[0] == '"') {
    377 	reply[reply_len] = '\0';
    378 	pos = strchr(reply + 1, '"');
    379 	if (pos)
    380 	    *pos = '\0';
    381 	identityEdit->setText(reply + 1);
    382     }
    383 
    384     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
    385     reply_len = sizeof(reply) - 1;
    386     res = wpagui->ctrlRequest(cmd, reply, &reply_len);
    387     if (res >= 0 && reply_len >= 2 &&
    388 	reply[0] == '"') {
    389 	reply[reply_len] = '\0';
    390 	pos = strchr(reply + 1, '"');
    391 	if (pos)
    392 	    *pos = '\0';
    393 	passwordEdit->setText(reply + 1);
    394     } else if (res >= 0 && key_value_isset(reply, reply_len)) {
    395 	passwordEdit->setText(WPA_GUI_KEY_DATA);
    396     }
    397 
    398     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
    399     reply_len = sizeof(reply) - 1;
    400     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
    401 	reply[0] == '"') {
    402 	reply[reply_len] = '\0';
    403 	pos = strchr(reply + 1, '"');
    404 	if (pos)
    405 	    *pos = '\0';
    406 	cacertEdit->setText(reply + 1);
    407     }
    408 
    409     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
    410     reply_len = sizeof(reply) - 1;
    411     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
    412 	reply[reply_len] = '\0';
    413 	for (i = 0; i < eapSelect->count(); i++) {
    414 	    if (eapSelect->text(i).compare(reply) == 0) {
    415 		eapSelect->setCurrentItem(i);
    416 		break;
    417 	    }
    418 	}
    419     }
    420 
    421     for (i = 0; i < 4; i++) {
    422 	QLineEdit *wepEdit;
    423 	switch (i) {
    424 	default:
    425 	case 0:
    426 	    wepEdit = wep0Edit;
    427 	    break;
    428 	case 1:
    429 	    wepEdit = wep1Edit;
    430 	    break;
    431 	case 2:
    432 	    wepEdit = wep2Edit;
    433 	    break;
    434 	case 3:
    435 	    wepEdit = wep3Edit;
    436 	    break;
    437 	}
    438 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d", network_id, i);
    439 	reply_len = sizeof(reply) - 1;
    440 	res = wpagui->ctrlRequest(cmd, reply, &reply_len);
    441 	if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
    442 	    reply[reply_len] = '\0';
    443 	    pos = strchr(reply + 1, '"');
    444 	    if (pos)
    445 		*pos = '\0';
    446 	    if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
    447 		encr = 1;
    448 
    449 	    wepEdit->setText(reply + 1);
    450 	} else if (res >= 0 && key_value_isset(reply, reply_len)) {
    451 	    if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
    452 		encr = 1;
    453 	    wepEdit->setText(WPA_GUI_KEY_DATA);
    454 	}
    455     }
    456 
    457     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
    458     reply_len = sizeof(reply) - 1;
    459     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
    460 	reply[reply_len] = '\0';
    461 	switch (atoi(reply)) {
    462 	case 0:
    463 	    wep0Radio->setChecked(true);
    464 	    break;
    465 	case 1:
    466 	    wep1Radio->setChecked(true);
    467 	    break;
    468 	case 2:
    469 	    wep2Radio->setChecked(true);
    470 	    break;
    471 	case 3:
    472 	    wep3Radio->setChecked(true);
    473 	    break;
    474 	}
    475     }
    476 
    477     authSelect->setCurrentItem(auth);
    478     authChanged(auth);
    479     encrSelect->setCurrentItem(encr);
    480     if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
    481 	wepEnabled(encr == 1);
    482 
    483     removeButton->setEnabled(true);
    484     addButton->setText("Save");
    485 }
    486 
    487 
    488 void NetworkConfig::removeNetwork()
    489 {
    490     char reply[10], cmd[256];
    491     size_t reply_len;
    492 
    493     if (QMessageBox::information(this, "wpa_gui",
    494 				 "This will permanently remove the network\n"
    495 				 "from the configuration. Do you really want\n"
    496 				 "to remove this network?", "Yes", "No") != 0)
    497 	return;
    498 
    499     snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
    500     reply_len = sizeof(reply);
    501     wpagui->ctrlRequest(cmd, reply, &reply_len);
    502     if (strncmp(reply, "OK", 2) != 0) {
    503 	QMessageBox::warning(this, "wpa_gui",
    504 			     "Failed to remove network from wpa_supplicant\n"
    505 			     "configuration.");
    506     } else {
    507 	wpagui->triggerUpdate();
    508 	wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
    509     }
    510 
    511     close();
    512 }
    513 
    514 
    515 void NetworkConfig::newNetwork()
    516 {
    517     new_network = true;
    518     getEapCapa();
    519 }
    520 
    521 
    522 void NetworkConfig::getEapCapa()
    523 {
    524     char reply[256];
    525     size_t reply_len;
    526 
    527     if (wpagui == NULL)
    528 	return;
    529 
    530     reply_len = sizeof(reply) - 1;
    531     if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
    532 	return;
    533     reply[reply_len] = '\0';
    534 
    535     QString res(reply);
    536     QStringList types = QStringList::split(QChar(' '), res);
    537     eapSelect->insertStringList(types);
    538 }
    539