Exemple #1
0
static int nai_realm_cred_username(struct nai_realm_eap *eap)
{
	if (eap_get_name(EAP_VENDOR_IETF, eap->method) == NULL)
		return 0; /* method not supported */

	if (eap->method != EAP_TYPE_TTLS && eap->method != EAP_TYPE_PEAP) {
		/* Only tunneled methods with username/password supported */
		return 0;
	}

	if (eap->method == EAP_TYPE_PEAP &&
	    eap_get_name(EAP_VENDOR_IETF, eap->inner_method) == NULL)
		return 0;

	if (eap->method == EAP_TYPE_TTLS) {
		if (eap->inner_method == 0 && eap->inner_non_eap == 0)
			return 0;
		if (eap->inner_method &&
		    eap_get_name(EAP_VENDOR_IETF, eap->inner_method) == NULL)
			return 0;
		if (eap->inner_non_eap &&
		    eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_PAP &&
		    eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_CHAP &&
		    eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_MSCHAP &&
		    eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_MSCHAPV2)
			return 0;
	}

	if (eap->inner_method &&
	    eap->inner_method != EAP_TYPE_GTC &&
	    eap->inner_method != EAP_TYPE_MSCHAPV2)
		return 0;

	return 1;
}
Exemple #2
0
static char * wpa_config_write_eap(const struct parse_data *data,
				   struct wpa_ssid *ssid)
{
	int i, ret;
	char *buf, *pos, *end;
	const struct eap_method_type *eap_methods = ssid->eap.eap_methods;
	const char *name;

	if (eap_methods == NULL)
		return NULL;

	pos = buf = os_zalloc(100);
	if (buf == NULL)
		return NULL;
	end = buf + 100;

	for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF ||
		     eap_methods[i].method != EAP_TYPE_NONE; i++) {
		name = eap_get_name(eap_methods[i].vendor,
				    eap_methods[i].method);
		if (name) {
			ret = os_snprintf(pos, end - pos, "%s%s",
					  pos == buf ? "" : " ", name);
			if (ret < 0 || ret >= end - pos)
				break;
			pos += ret;
		}
	}

	end[-1] = '\0';

	return buf;
}
Exemple #3
0
static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
{
	size_t i;

	if (cred->priority)
		fprintf(f, "\tpriority=%d\n", cred->priority);
	if (cred->pcsc)
		fprintf(f, "\tpcsc=%d\n", cred->pcsc);
	if (cred->realm)
		fprintf(f, "\trealm=\"%s\"\n", cred->realm);
	if (cred->username)
		fprintf(f, "\tusername=\"%s\"\n", cred->username);
	if (cred->password && cred->ext_password)
		fprintf(f, "\tpassword=ext:%s\n", cred->password);
	else if (cred->password)
		fprintf(f, "\tpassword=\"%s\"\n", cred->password);
	if (cred->ca_cert)
		fprintf(f, "\tca_cert=\"%s\"\n", cred->ca_cert);
	if (cred->client_cert)
		fprintf(f, "\tclient_cert=\"%s\"\n", cred->client_cert);
	if (cred->private_key)
		fprintf(f, "\tprivate_key=\"%s\"\n", cred->private_key);
	if (cred->private_key_passwd)
		fprintf(f, "\tprivate_key_passwd=\"%s\"\n",
			cred->private_key_passwd);
	if (cred->imsi)
		fprintf(f, "\timsi=\"%s\"\n", cred->imsi);
	if (cred->milenage)
		fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage);
	for (i = 0; i < cred->num_domain; i++)
		fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]);
	if (cred->roaming_consortium_len) {
		fprintf(f, "\troaming_consortium=");
		for (i = 0; i < cred->roaming_consortium_len; i++)
			fprintf(f, "%02x", cred->roaming_consortium[i]);
		fprintf(f, "\n");
	}
	if (cred->eap_method) {
		const char *name;
		name = eap_get_name(cred->eap_method[0].vendor,
				    cred->eap_method[0].method);
		fprintf(f, "\teap=%s\n", name);
	}
	if (cred->phase1)
		fprintf(f, "\tphase1=\"%s\"\n", cred->phase1);
	if (cred->phase2)
		fprintf(f, "\tphase2=\"%s\"\n", cred->phase2);
	if (cred->excluded_ssid) {
		size_t j;
		for (i = 0; i < cred->num_excluded_ssid; i++) {
			struct excluded_ssid *e = &cred->excluded_ssid[i];
			fprintf(f, "\texcluded_ssid=");
			for (j = 0; j < e->ssid_len; j++)
				fprintf(f, "%02x", e->ssid[j]);
			fprintf(f, "\n");
		}
	}
}
Exemple #4
0
static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
{
	size_t i;

	if (cred->priority)
		fprintf(f, "\tpriority=%d\n", cred->priority);
	if (cred->pcsc)
		fprintf(f, "\tpcsc=%d\n", cred->pcsc);
	if (cred->realm)
		fprintf(f, "\trealm=\"%s\"\n", cred->realm);
	if (cred->username)
		fprintf(f, "\tusername=\"%s\"\n", cred->username);
	if (cred->password && cred->ext_password)
		fprintf(f, "\tpassword=ext:%s\n", cred->password);
	else if (cred->password)
		fprintf(f, "\tpassword=\"%s\"\n", cred->password);
	if (cred->ca_cert)
		fprintf(f, "\tca_cert=\"%s\"\n", cred->ca_cert);
	if (cred->client_cert)
		fprintf(f, "\tclient_cert=\"%s\"\n", cred->client_cert);
	if (cred->private_key)
		fprintf(f, "\tprivate_key=\"%s\"\n", cred->private_key);
	if (cred->private_key_passwd)
		fprintf(f, "\tprivate_key_passwd=\"%s\"\n",
			cred->private_key_passwd);
	if (cred->imsi)
		fprintf(f, "\timsi=\"%s\"\n", cred->imsi);
	if (cred->milenage)
		fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage);
	for (i = 0; i < cred->num_domain; i++)
		fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]);
	if (cred->domain_suffix_match)
		fprintf(f, "\tdomain_suffix_match=\"%s\"\n",
			cred->domain_suffix_match);
	if (cred->roaming_consortium_len) {
		fprintf(f, "\troaming_consortium=");
		for (i = 0; i < cred->roaming_consortium_len; i++)
			fprintf(f, "%02x", cred->roaming_consortium[i]);
		fprintf(f, "\n");
	}
	if (cred->eap_method) {
		const char *name;
		name = eap_get_name(cred->eap_method[0].vendor,
				    cred->eap_method[0].method);
		if (name)
			fprintf(f, "\teap=%s\n", name);
	}
	if (cred->phase1)
		fprintf(f, "\tphase1=\"%s\"\n", cred->phase1);
	if (cred->phase2)
		fprintf(f, "\tphase2=\"%s\"\n", cred->phase2);
	if (cred->excluded_ssid) {
		size_t j;
		for (i = 0; i < cred->num_excluded_ssid; i++) {
			struct excluded_ssid *e = &cred->excluded_ssid[i];
			fprintf(f, "\texcluded_ssid=");
			for (j = 0; j < e->ssid_len; j++)
				fprintf(f, "%02x", e->ssid[j]);
			fprintf(f, "\n");
		}
	}
	if (cred->roaming_partner) {
		for (i = 0; i < cred->num_roaming_partner; i++) {
			struct roaming_partner *p = &cred->roaming_partner[i];
			fprintf(f, "\troaming_partner=\"%s,%d,%u,%s\"\n",
				p->fqdn, p->exact_match, p->priority,
				p->country);
		}
	}
	if (cred->update_identifier)
		fprintf(f, "\tupdate_identifier=%d\n", cred->update_identifier);

	if (cred->provisioning_sp)
		fprintf(f, "\tprovisioning_sp=\"%s\"\n", cred->provisioning_sp);
	if (cred->sp_priority)
		fprintf(f, "\tsp_priority=%d\n", cred->sp_priority);

	if (cred->min_dl_bandwidth_home)
		fprintf(f, "\tmin_dl_bandwidth_home=%u\n",
			cred->min_dl_bandwidth_home);
	if (cred->min_ul_bandwidth_home)
		fprintf(f, "\tmin_ul_bandwidth_home=%u\n",
			cred->min_ul_bandwidth_home);
	if (cred->min_dl_bandwidth_roaming)
		fprintf(f, "\tmin_dl_bandwidth_roaming=%u\n",
			cred->min_dl_bandwidth_roaming);
	if (cred->min_ul_bandwidth_roaming)
		fprintf(f, "\tmin_ul_bandwidth_roaming=%u\n",
			cred->min_ul_bandwidth_roaming);

	if (cred->max_bss_load)
		fprintf(f, "\tmax_bss_load=%u\n",
			cred->max_bss_load);

	if (cred->ocsp)
		fprintf(f, "\tocsp=%d\n", cred->ocsp);

	if (cred->num_req_conn_capab) {
		for (i = 0; i < cred->num_req_conn_capab; i++) {
			int *ports;

			fprintf(f, "\treq_conn_capab=%u",
				cred->req_conn_capab_proto[i]);
			ports = cred->req_conn_capab_port[i];
			if (ports) {
				int j;
				for (j = 0; ports[j] != -1; j++) {
					fprintf(f, "%s%d", j > 0 ? "," : ":",
						ports[j]);
				}
			}
			fprintf(f, "\n");
		}
	}

	if (cred->required_roaming_consortium_len) {
		fprintf(f, "\trequired_roaming_consortium=");
		for (i = 0; i < cred->required_roaming_consortium_len; i++)
			fprintf(f, "%02x",
				cred->required_roaming_consortium[i]);
		fprintf(f, "\n");
	}

	if (cred->sim_num != DEFAULT_USER_SELECTED_SIM)
		fprintf(f, "\tsim_num=%d\n", cred->sim_num);
}
Exemple #5
0
int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
{
	struct wpa_ssid *ssid;
	struct nai_realm *realm;
	struct nai_realm_eap *eap = NULL;
	u16 count, i;
	char buf[100];
	const u8 *ie;

	if (bss == NULL)
		return -1;
	ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
	if (ie == NULL || ie[1] == 0) {
		wpa_printf(MSG_DEBUG, "Interworking: No SSID known for "
			   MACSTR, MAC2STR(bss->bssid));
		return -1;
	}

	realm = nai_realm_parse(bss->anqp_nai_realm, &count);
	if (realm == NULL) {
		wpa_printf(MSG_DEBUG, "Interworking: Could not parse NAI "
			   "Realm list from " MACSTR, MAC2STR(bss->bssid));
		count = 0;
	}

	for (i = 0; i < count; i++) {
		if (!nai_realm_match(&realm[i], wpa_s->conf->home_realm))
			continue;
		eap = nai_realm_find_eap(wpa_s, &realm[i]);
		if (eap)
			break;
	}

	if (!eap) {
		if (interworking_connect_3gpp(wpa_s, bss) == 0) {
			if (realm)
				nai_realm_free(realm, count);
			return 0;
		}

		wpa_printf(MSG_DEBUG, "Interworking: No matching credentials "
			   "and EAP method found for " MACSTR,
			   MAC2STR(bss->bssid));
		nai_realm_free(realm, count);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR,
		   MAC2STR(bss->bssid));

	ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL) {
		nai_realm_free(realm, count);
		return -1;
	}
	wpas_notify_network_added(wpa_s, ssid);
	wpa_config_set_network_defaults(ssid);
	ssid->temporary = 1;
	ssid->ssid = os_zalloc(ie[1] + 1);
	if (ssid->ssid == NULL)
		goto fail;
	os_memcpy(ssid->ssid, ie + 2, ie[1]);
	ssid->ssid_len = ie[1];

	if (wpa_config_set(ssid, "eap", eap_get_name(EAP_VENDOR_IETF,
						     eap->method), 0) < 0)
		goto fail;

	if (wpa_s->conf->home_username && wpa_s->conf->home_username[0] &&
	    wpa_config_set_quoted(ssid, "identity",
				  wpa_s->conf->home_username) < 0)
		goto fail;

	if (wpa_s->conf->home_password && wpa_s->conf->home_password[0] &&
	    wpa_config_set_quoted(ssid, "password", wpa_s->conf->home_password)
	    < 0)
		goto fail;

	switch (eap->method) {
	case EAP_TYPE_TTLS:
		if (eap->inner_method) {
			os_snprintf(buf, sizeof(buf), "\"autheap=%s\"",
				    eap_get_name(EAP_VENDOR_IETF,
						 eap->inner_method));
			if (wpa_config_set(ssid, "phase2", buf, 0) < 0)
				goto fail;
			break;
		}
		switch (eap->inner_non_eap) {
		case NAI_REALM_INNER_NON_EAP_PAP:
			if (wpa_config_set(ssid, "phase2", "\"auth=PAP\"", 0) <
			    0)
				goto fail;
			break;
		case NAI_REALM_INNER_NON_EAP_CHAP:
			if (wpa_config_set(ssid, "phase2", "\"auth=CHAP\"", 0)
			    < 0)
				goto fail;
			break;
		case NAI_REALM_INNER_NON_EAP_MSCHAP:
			if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAP\"",
					   0) < 0)
				goto fail;
			break;
		case NAI_REALM_INNER_NON_EAP_MSCHAPV2:
			if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAPV2\"",
					   0) < 0)
				goto fail;
			break;
		}
		break;
	case EAP_TYPE_PEAP:
		os_snprintf(buf, sizeof(buf), "\"auth=%s\"",
			    eap_get_name(EAP_VENDOR_IETF, eap->inner_method));
		if (wpa_config_set(ssid, "phase2", buf, 0) < 0)
			goto fail;
		break;
	}

	if (wpa_s->conf->home_ca_cert && wpa_s->conf->home_ca_cert[0] &&
	    wpa_config_set_quoted(ssid, "ca_cert", wpa_s->conf->home_ca_cert) <
	    0)
		goto fail;

	nai_realm_free(realm, count);

	wpa_supplicant_select_network(wpa_s, ssid);

	return 0;

fail:
	wpas_notify_network_removed(wpa_s, ssid);
	wpa_config_remove_network(wpa_s->conf, ssid->id);
	nai_realm_free(realm, count);
	return -1;
}