Esempio n. 1
0
/**
 * eap_sim_db_get_gsm_triplets - Get GSM triplets
 * @data: Private data pointer from eap_sim_db_init()
 * @username: Permanent username (prefix | IMSI)
 * @max_chal: Maximum number of triplets
 * @_rand: Buffer for RAND values
 * @kc: Buffer for Kc values
 * @sres: Buffer for SRES values
 * @cb_session_ctx: Session callback context for get_complete_cb()
 * Returns: Number of triplets received (has to be less than or equal to
 * max_chal), -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not found), or
 * -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this case, the
 * callback function registered with eap_sim_db_init() will be called once the
 * results become available.
 *
 * When using an external server for GSM triplets, this function can always
 * start a request and return EAP_SIM_DB_PENDING immediately if authentication
 * triplets are not available. Once the triplets are received, callback
 * function registered with eap_sim_db_init() is called to notify EAP state
 * machine to reprocess the message. This eap_sim_db_get_gsm_triplets()
 * function will then be called again and the newly received triplets will then
 * be given to the caller.
 */
int eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data,
				const char *username, int max_chal,
				u8 *_rand, u8 *kc, u8 *sres,
				void *cb_session_ctx)
{
	struct eap_sim_db_pending *entry;
	int len, ret;
	char msg[40];
	const char *imsi;
	size_t imsi_len;

	if (username == NULL || username[0] != EAP_SIM_PERMANENT_PREFIX ||
	    username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'",
			   username);
		return EAP_SIM_DB_FAILURE;
	}
	imsi = username + 1;
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get GSM triplets for IMSI '%s'",
		   imsi);

	entry = eap_sim_db_get_pending(data, imsi, 0);
	if (entry) {
		int num_chal;
		if (entry->state == FAILURE) {
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
				   "failure");
			eap_sim_db_free_pending(data, entry);
			return EAP_SIM_DB_FAILURE;
		}

		if (entry->state == PENDING) {
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
				   "still pending");
			eap_sim_db_add_pending(data, entry);
			return EAP_SIM_DB_PENDING;
		}

		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
			   "%d challenges", entry->u.sim.num_chal);
		num_chal = entry->u.sim.num_chal;
		if (num_chal > max_chal)
			num_chal = max_chal;
		os_memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN);
		os_memcpy(sres, entry->u.sim.sres,
			  num_chal * EAP_SIM_SRES_LEN);
		os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN);
		eap_sim_db_free_pending(data, entry);
		return num_chal;
	}

	if (data->sock < 0) {
		if (eap_sim_db_open_socket(data) < 0)
			return EAP_SIM_DB_FAILURE;
	}

	imsi_len = os_strlen(imsi);
	len = os_snprintf(msg, sizeof(msg), "SIM-REQ-AUTH ");
	if (os_snprintf_error(sizeof(msg), len) ||
	    len + imsi_len >= sizeof(msg))
		return EAP_SIM_DB_FAILURE;
	os_memcpy(msg + len, imsi, imsi_len);
	len += imsi_len;
	ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal);
	if (os_snprintf_error(sizeof(msg) - len, ret))
		return EAP_SIM_DB_FAILURE;
	len += ret;

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting SIM authentication "
		   "data for IMSI '%s'", imsi);
	if (eap_sim_db_send(data, msg, len) < 0)
		return EAP_SIM_DB_FAILURE;

	entry = os_zalloc(sizeof(*entry));
	if (entry == NULL)
		return EAP_SIM_DB_FAILURE;

	os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi));
	entry->cb_session_ctx = cb_session_ctx;
	entry->state = PENDING;
	eap_sim_db_add_pending(data, entry);
	eap_sim_db_expire_pending(data, entry);
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added query %p", entry);

	return EAP_SIM_DB_PENDING;
}
Esempio n. 2
0
static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
{
    u8 *eap;
    size_t len;
    struct eap_hdr *hdr;
    int eap_type = -1;
    char buf[64];
    struct radius_msg *msg;

    if (e->last_recv_radius == NULL)
        return;

    msg = e->last_recv_radius;

    eap = radius_msg_get_eap(msg, &len);
    if (eap == NULL) {
        /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3:
         * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
         * attribute */
        wpa_printf(MSG_DEBUG, "could not extract "
                   "EAP-Message from RADIUS message");
        os_free(e->last_eap_radius);
        e->last_eap_radius = NULL;
        e->last_eap_radius_len = 0;
        return;
    }

    if (len < sizeof(*hdr)) {
        wpa_printf(MSG_DEBUG, "too short EAP packet "
                   "received from authentication server");
        os_free(eap);
        return;
    }

    if (len > sizeof(*hdr))
        eap_type = eap[sizeof(*hdr)];

    hdr = (struct eap_hdr *) eap;
    switch (hdr->code) {
    case EAP_CODE_REQUEST:
        os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
                    eap_type >= 0 ? eap_type_text(eap_type) : "??",
                    eap_type);
        break;
    case EAP_CODE_RESPONSE:
        os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",
                    eap_type >= 0 ? eap_type_text(eap_type) : "??",
                    eap_type);
        break;
    case EAP_CODE_SUCCESS:
        os_strlcpy(buf, "EAP Success", sizeof(buf));
        /* LEAP uses EAP Success within an authentication, so must not
         * stop here with eloop_terminate(); */
        break;
    case EAP_CODE_FAILURE:
        os_strlcpy(buf, "EAP Failure", sizeof(buf));
        eloop_terminate();
        break;
    default:
        os_strlcpy(buf, "unknown EAP code", sizeof(buf));
        wpa_hexdump(MSG_DEBUG, "Decapsulated EAP packet", eap, len);
        break;
    }
    wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d "
               "id=%d len=%d) from RADIUS server: %s",
               hdr->code, hdr->identifier, ntohs(hdr->length), buf);

    /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */

    os_free(e->last_eap_radius);
    e->last_eap_radius = eap;
    e->last_eap_radius_len = len;

    {
        struct ieee802_1x_hdr *dot1x;
        dot1x = os_malloc(sizeof(*dot1x) + len);
        assert(dot1x != NULL);
        dot1x->version = EAPOL_VERSION;
        dot1x->type = IEEE802_1X_TYPE_EAP_PACKET;
        dot1x->length = htons(len);
        os_memcpy((u8 *) (dot1x + 1), eap, len);
        eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid,
                          (u8 *) dot1x, sizeof(*dot1x) + len);
        os_free(dot1x);
    }
}
static void *
madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params)
{
	struct madwifi_driver_data *drv;
	struct ifreq ifr;
	struct iwreq iwr;
	char brname[IFNAMSIZ];

	drv = os_zalloc(sizeof(struct madwifi_driver_data));
	if (drv == NULL) {
		printf("Could not allocate memory for madwifi driver data\n");
		return NULL;
	}

	drv->hapd = hapd;
	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->ioctl_sock < 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		goto bad;
	}
	memcpy(drv->iface, params->ifname, sizeof(drv->iface));

	memset(&ifr, 0, sizeof(ifr));
	os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
	if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
		perror("ioctl(SIOCGIFINDEX)");
		goto bad;
	}
	drv->ifindex = ifr.ifr_ifindex;

	drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
					handle_read, drv, 1);
	if (drv->sock_xmit == NULL)
		goto bad;
	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
		goto bad;
	if (params->bridge[0]) {
		wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
			   params->bridge[0]);
		drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
						ETH_P_EAPOL, handle_read, drv,
						1);
		if (drv->sock_recv == NULL)
			goto bad;
	} else if (linux_br_get(brname, drv->iface) == 0) {
		wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
			   "EAPOL receive", brname);
		drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
						handle_read, drv, 1);
		if (drv->sock_recv == NULL)
			goto bad;
	} else
		drv->sock_recv = drv->sock_xmit;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);

	iwr.u.mode = IW_MODE_MASTER;

	if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
		perror("ioctl[SIOCSIWMODE]");
		printf("Could not set interface to master mode!\n");
		goto bad;
	}

	/* mark down during setup */
	linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
	madwifi_set_privacy(drv, 0); /* default to no privacy */

	madwifi_receive_probe_req(drv);

	if (madwifi_wireless_event_init(drv))
		goto bad;

	return drv;
bad:
	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
	if (drv->ioctl_sock >= 0)
		close(drv->ioctl_sock);
	if (drv != NULL)
		free(drv);
	return NULL;
}
Esempio n. 4
0
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
{
	struct wpa_ctrl *ctrl;
	static int counter = 0;
	int ret;
	size_t res;
	int tries = 0;

	ctrl = os_malloc(sizeof(*ctrl));
	if (ctrl == NULL)
		return NULL;
	os_memset(ctrl, 0, sizeof(*ctrl));

	ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (ctrl->s < 0) {
		os_free(ctrl);
		return NULL;
	}

	ctrl->local.sun_family = AF_UNIX;
	counter++;
try_again:
	ret = os_snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
			  CONFIG_CTRL_IFACE_CLIENT_DIR "/"
			  CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d",
			  (int) getpid(), counter);
	if (ret < 0 || (size_t) ret >= sizeof(ctrl->local.sun_path)) {
		close(ctrl->s);
		os_free(ctrl);
		return NULL;
	}
	tries++;
	if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
		    sizeof(ctrl->local)) < 0) {
		if (errno == EADDRINUSE && tries < 2) {
			/*
			 * getpid() returns unique identifier for this instance
			 * of wpa_ctrl, so the existing socket file must have
			 * been left by unclean termination of an earlier run.
			 * Remove the file and try again.
			 */
			unlink(ctrl->local.sun_path);
			goto try_again;
		}
		close(ctrl->s);
		os_free(ctrl);
		return NULL;
	}

#ifdef ANDROID
	chmod(ctrl->local.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
	chown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI);
	/*
	 * If the ctrl_path isn't an absolute pathname, assume that
	 * it's the name of a socket in the Android reserved namespace.
	 * Otherwise, it's a normal UNIX domain socket appearing in the
	 * filesystem.
	 */
	if (ctrl_path != NULL && *ctrl_path != '/') {
		char buf[21];
		os_snprintf(buf, sizeof(buf), "wpa_%s", ctrl_path);
		if (socket_local_client_connect(
			    ctrl->s, buf,
			    ANDROID_SOCKET_NAMESPACE_RESERVED,
			    SOCK_DGRAM) < 0) {
			close(ctrl->s);
			unlink(ctrl->local.sun_path);
			os_free(ctrl);
			return NULL;
		}
		return ctrl;
	}
#endif /* ANDROID */

	ctrl->dest.sun_family = AF_UNIX;
	res = os_strlcpy(ctrl->dest.sun_path, ctrl_path,
			 sizeof(ctrl->dest.sun_path));
	if (res >= sizeof(ctrl->dest.sun_path)) {
		close(ctrl->s);
		os_free(ctrl);
		return NULL;
	}
	if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
		    sizeof(ctrl->dest)) < 0) {
		close(ctrl->s);
		unlink(ctrl->local.sun_path);
		os_free(ctrl);
		return NULL;
	}

	return ctrl;
}
Esempio n. 5
0
static struct wpa_priv_interface *
wpa_priv_interface_init(const char *dir, const char *params)
{
	struct wpa_priv_interface *iface;
	char *pos;
	size_t len;
	struct sockaddr_un addr;
	int i;

	pos = os_strchr(params, ':');
	if (pos == NULL)
		return NULL;

	iface = os_zalloc(sizeof(*iface));
	if (iface == NULL)
		return NULL;
	iface->fd = -1;

	len = pos - params;
	iface->driver_name = os_malloc(len + 1);
	if (iface->driver_name == NULL) {
		wpa_priv_interface_deinit(iface);
		return NULL;
	}
	os_memcpy(iface->driver_name, params, len);
	iface->driver_name[len] = '\0';

	for (i = 0; wpa_drivers[i]; i++) {
		if (os_strcmp(iface->driver_name,
			      wpa_drivers[i]->name) == 0) {
			iface->driver = wpa_drivers[i];
			break;
		}
	}
	if (iface->driver == NULL) {
		wpa_printf(MSG_ERROR, "Unsupported driver '%s'",
			   iface->driver_name);
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	pos++;
	iface->ifname = os_strdup(pos);
	if (iface->ifname == NULL) {
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	len = os_strlen(dir) + 1 + os_strlen(iface->ifname);
	iface->sock_name = os_malloc(len + 1);
	if (iface->sock_name == NULL) {
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	os_snprintf(iface->sock_name, len + 1, "%s/%s", dir, iface->ifname);
	if (os_strlen(iface->sock_name) >= sizeof(addr.sun_path)) {
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	iface->fd = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (iface->fd < 0) {
		perror("socket(PF_UNIX)");
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_strlcpy(addr.sun_path, iface->sock_name, sizeof(addr.sun_path));

	if (bind(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		wpa_printf(MSG_DEBUG, "bind(PF_UNIX) failed: %s",
			   strerror(errno));
		if (connect(iface->fd, (struct sockaddr *) &addr,
			    sizeof(addr)) < 0) {
			wpa_printf(MSG_DEBUG, "Socket exists, but does not "
				   "allow connections - assuming it was "
				   "leftover from forced program termination");
			if (unlink(iface->sock_name) < 0) {
				perror("unlink[ctrl_iface]");
				wpa_printf(MSG_ERROR, "Could not unlink "
					   "existing ctrl_iface socket '%s'",
					   iface->sock_name);
				goto fail;
			}
			if (bind(iface->fd, (struct sockaddr *) &addr,
				 sizeof(addr)) < 0) {
				perror("bind(PF_UNIX)");
				goto fail;
			}
			wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
				   "socket '%s'", iface->sock_name);
		} else {
			wpa_printf(MSG_INFO, "Socket exists and seems to be "
				   "in use - cannot override it");
			wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
				   "not used anymore", iface->sock_name);
			goto fail;
		}
	}

	if (chmod(iface->sock_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
		perror("chmod");
		goto fail;
	}

	eloop_register_read_sock(iface->fd, wpa_priv_receive, iface, NULL);

	return iface;

fail:
	wpa_priv_interface_deinit(iface);
	return NULL;
}
struct wps_er *
wps_er_init(struct wps_context *wps, const char *ifname, const char *filter)
{
	struct wps_er *er;
	struct in_addr addr;

	er = os_zalloc(sizeof(*er));
	if (er == NULL)
		return NULL;
	dl_list_init(&er->ap);
	dl_list_init(&er->ap_unsubscribing);
	dl_list_init(&er->ap_settings);

	er->multicast_sd = -1;
	er->ssdp_sd = -1;

	os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
	er->wps = wps;
	if (os_get_random((unsigned char *) &er->event_id,
			  sizeof(er->event_id)) < 0) {
		wps_er_deinit(er, NULL, NULL);
		return NULL;
	}
	/* Limit event_id to < 32 bits to avoid issues with atoi() */
	er->event_id &= 0x0fffffff;

	if (filter && os_strncmp(filter, "ifname=", 7) == 0) {
		const char *pos, *end;
		pos = filter + 7;
		end = os_strchr(pos, ' ');
		if (end) {
			size_t len = end - pos;
			os_strlcpy(er->ifname, pos, len < sizeof(er->ifname) ?
				   len + 1 : sizeof(er->ifname));
			filter = end + 1;
		} else {
			os_strlcpy(er->ifname, pos, sizeof(er->ifname));
			filter = NULL;
		}
		er->forced_ifname = 1;
	}

	if (filter) {
		if (inet_aton(filter, &er->filter_addr) == 0) {
			wpa_printf(MSG_INFO, "WPS UPnP: Invalid filter "
				   "address %s", filter);
			wps_er_deinit(er, NULL, NULL);
			return NULL;
		}
		wpa_printf(MSG_DEBUG, "WPS UPnP: Only accepting connections "
			   "with %s", filter);
	}
	if (get_netif_info(er->ifname, &er->ip_addr, &er->ip_addr_text,
			   er->mac_addr)) {
		wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
			   "for %s. Does it have IP address?", er->ifname);
		wps_er_deinit(er, NULL, NULL);
		return NULL;
	}

	if (wps_er_ssdp_init(er) < 0) {
		wpa_printf(MSG_INFO, "WPS UPnP: SSDP initialization failed");
		wps_er_deinit(er, NULL, NULL);
		return NULL;
	}

	addr.s_addr = er->ip_addr;
	er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er);
	if (er->http_srv == NULL) {
		wpa_printf(MSG_INFO, "WPS UPnP: HTTP initialization failed");
		wps_er_deinit(er, NULL, NULL);
		return NULL;
	}
	er->http_port = http_server_get_port(er->http_srv);

	wpa_printf(MSG_DEBUG, "WPS ER: Start (ifname=%s ip_addr=%s)",
		   er->ifname, er->ip_addr_text);

	return er;
}
Esempio n. 7
0
static void radius_server_receive_auth(int sock, void *eloop_ctx,
				       void *sock_ctx)
{
	struct radius_server_data *data = eloop_ctx;
	u8 *buf = NULL;
	union {
		struct sockaddr_storage ss;
		struct sockaddr_in sin;
#ifdef CONFIG_IPV6
		struct sockaddr_in6 sin6;
#endif /* CONFIG_IPV6 */
	} from;
	socklen_t fromlen;
	int len;
	struct radius_client *client = NULL;
	struct radius_msg *msg = NULL;
	char abuf[50];
	int from_port = 0;

	buf = os_malloc(RADIUS_MAX_MSG_LEN);
	if (buf == NULL) {
		goto fail;
	}

	fromlen = sizeof(from);
	len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
		       (struct sockaddr *) &from.ss, &fromlen);
	if (len < 0) {
		wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
			   strerror(errno));
		goto fail;
	}

#ifdef CONFIG_IPV6
	if (data->ipv6) {
		if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
			      sizeof(abuf)) == NULL)
			abuf[0] = '\0';
		from_port = ntohs(from.sin6.sin6_port);
		RADIUS_DEBUG("Received %d bytes from %s:%d",
			     len, abuf, from_port);

		client = radius_server_get_client(data,
						  (struct in_addr *)
						  &from.sin6.sin6_addr, 1);
	}
#endif /* CONFIG_IPV6 */

	if (!data->ipv6) {
		os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
		from_port = ntohs(from.sin.sin_port);
		RADIUS_DEBUG("Received %d bytes from %s:%d",
			     len, abuf, from_port);

		client = radius_server_get_client(data, &from.sin.sin_addr, 0);
	}

	RADIUS_DUMP("Received data", buf, len);

	if (client == NULL) {
		RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
		data->counters.invalid_requests++;
		goto fail;
	}

	msg = radius_msg_parse(buf, len);
	if (msg == NULL) {
		RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
		data->counters.malformed_access_requests++;
		client->counters.malformed_access_requests++;
		goto fail;
	}

	os_free(buf);
	buf = NULL;

	if (wpa_debug_level <= MSG_MSGDUMP) {
		radius_msg_dump(msg);
	}

	if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) {
		RADIUS_DEBUG("Unexpected RADIUS code %d",
			     radius_msg_get_hdr(msg)->code);
		data->counters.unknown_types++;
		client->counters.unknown_types++;
		goto fail;
	}

	data->counters.access_requests++;
	client->counters.access_requests++;

	if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret,
				       client->shared_secret_len, NULL)) {
		RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf);
		data->counters.bad_authenticators++;
		client->counters.bad_authenticators++;
		goto fail;
	}

	if (radius_server_request(data, msg, (struct sockaddr *) &from,
				  fromlen, client, abuf, from_port, NULL) ==
	    -2)
		return; /* msg was stored with the session */

fail:
	radius_msg_free(msg);
	os_free(buf);
}
static int wpa_driver_prism54_set_key(void *priv, wpa_alg alg,
                                      const u8 *addr, int key_idx, int set_tx,
                                      const u8 *seq, size_t seq_len,
                                      const u8 *key, size_t key_len)
{
        struct wpa_driver_prism54_data *drv = priv;
        struct prism2_hostapd_param *param;
        u8 *buf;
        size_t blen;
        int ret = 0;
        char *alg_name;

        switch (alg) {
        case WPA_ALG_NONE:
                alg_name = "none";
                return -1;
                break;
        case WPA_ALG_WEP:
                alg_name = "WEP";
                return -1;
                break;
        case WPA_ALG_TKIP:
                alg_name = "TKIP";
                break;
        case WPA_ALG_CCMP:
                alg_name = "CCMP";
                return -1;
                break;
        default:
                return -1;
        }

        wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
                   "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
                   (unsigned long) seq_len, (unsigned long) key_len);

        if (seq_len > 8)
                return -2;

        blen = sizeof(*param) + key_len;
        buf = os_zalloc(blen);
        if (buf == NULL)
                return -1;

        param = (struct prism2_hostapd_param *) buf;
        param->cmd = PRISM2_SET_ENCRYPTION;
        /* TODO: In theory, STA in client mode can use five keys; four default
         * keys for receiving (with keyidx 0..3) and one individual key for
         * both transmitting and receiving (keyidx 0) _unicast_ packets. Now,
         * keyidx 0 is reserved for this unicast use and default keys can only
         * use keyidx 1..3 (i.e., default key with keyidx 0 is not supported).
         * This should be fine for more or less all cases, but for completeness
         * sake, the driver could be enhanced to support the missing key. */
#if 0
        if (addr == NULL)
                os_memset(param->sta_addr, 0xff, ETH_ALEN);
        else
                os_memcpy(param->sta_addr, addr, ETH_ALEN);
#else
        os_memset(param->sta_addr, 0xff, ETH_ALEN);
#endif
        os_strlcpy((char *) param->u.crypt.alg, alg_name,
                   HOSTAP_CRYPT_ALG_NAME_LEN);
        param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0;
        param->u.crypt.idx = key_idx;
        os_memcpy(param->u.crypt.seq, seq, seq_len);
        param->u.crypt.key_len = key_len;
        os_memcpy((u8 *) (param + 1), key, key_len);

        if (hostapd_ioctl_prism54(drv, param, blen, 1)) {
                wpa_printf(MSG_WARNING, "Failed to set encryption.");
                show_set_key_error(param);
                ret = -1;
        }
        os_free(buf);

        return ret;
}
Esempio n. 9
0
static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
				  struct wpa_ssid *ssid,
				  struct hostapd_config *conf)
{
	struct hostapd_bss_config *bss = &conf->bss[0];
	int pairwise;
#ifdef CONFIG_IEEE80211N
	struct hostapd_hw_modes *modes;
	u16 num_modes, flags;
#endif /* CONFIG_IEEE80211N */

	conf->driver = wpa_s->driver;

	os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));

	if (ssid->frequency == 0) {
		/* default channel 11 */
		conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
		conf->channel = 11;
	} else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) {
		conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
		conf->channel = (ssid->frequency - 2407) / 5;
	} else if ((ssid->frequency >= 5180 && ssid->frequency <= 5240) ||
		   (ssid->frequency >= 5745 && ssid->frequency <= 5825)) {
		conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
		conf->channel = (ssid->frequency - 5000) / 5;
	} else {
		wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
			   ssid->frequency);
		return -1;
	}

	/* TODO: enable HT40 if driver supports it;
	 * drop to 11b if driver does not support 11g */

#ifdef CONFIG_IEEE80211N
	/*
	 * Enable HT20 if the driver supports it, by setting conf->ieee80211n.
	 * Using default config settings for: conf->ht_op_mode_fixed,
	 * conf->ht_capab, conf->secondary_channel, conf->require_ht
	 */
	modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
	if (modes) {
		struct hostapd_hw_modes *mode = NULL;
		int i;
		for (i = 0; i < num_modes; i++) {
			if (modes[i].mode == conf->hw_mode) {
				mode = &modes[i];
				break;
			}
		}
		if (mode && mode->ht_capab)
			conf->ieee80211n = 1;
		ieee80211_sta_free_hw_features(modes, num_modes);
		modes = NULL;
	}
#endif /* CONFIG_IEEE80211N */

#ifdef CONFIG_P2P
	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
		if (!wpa_s->fgHotspot/* P2P only, no tethering */) {
			/* Remove 802.11b rates from supported and basic rate sets */
			int *list = os_malloc(4 * sizeof(int));
			if (list) {
				list[0] = 60;
				list[1] = 120;
				list[2] = 240;
				list[3] = -1;
			}
			conf->basic_rates = list;

			list = os_malloc(9 * sizeof(int));
			if (list) {
				list[0] = 60;
				list[1] = 90;
				list[2] = 120;
				list[3] = 180;
				list[4] = 240;
				list[5] = 360;
				list[6] = 480;
				list[7] = 540;
				list[8] = -1;
			}
			conf->supported_rates = list;
		}
		else		
		{
		    int *list = os_malloc(5 * sizeof(int));
			if (list) {
					list[0] = 10;
					list[1] = 20;
					list[2] = 55;
					list[3] = 110;
					list[4] = -1;
			}
			conf->basic_rates = list;
		
			list = os_malloc(13 * sizeof(int));
			if (list) {
					list[0] = 10;
					list[1] = 20;
					list[2] = 55;
					list[3] = 110;
					list[4] = 60;
					list[5] = 90;
					list[6] = 120;
					list[7] = 180;
					list[8] = 240;
					list[9] = 360;
					list[10] = 480;
					list[11] = 540;
					list[12] = -1;
			}
			conf->supported_rates = list;
	    }
    }
#endif /* CONFIG_P2P */

	if (ssid->ssid_len == 0) {
		wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
		return -1;
	}
	os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
	bss->ssid.ssid[ssid->ssid_len] = '\0';
	bss->ssid.ssid_len = ssid->ssid_len;
	bss->ssid.ssid_set = 1;

	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
		bss->wpa = ssid->proto;
	bss->wpa_key_mgmt = ssid->key_mgmt;
	bss->wpa_pairwise = ssid->pairwise_cipher;
	if (ssid->passphrase) {
		bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
	} else if (ssid->psk_set) {
		os_free(bss->ssid.wpa_psk);
		bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
		if (bss->ssid.wpa_psk == NULL)
			return -1;
		os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
		bss->ssid.wpa_psk->group = 1;
	}

	/* Select group cipher based on the enabled pairwise cipher suites */
	pairwise = 0;
	if (bss->wpa & 1)
		pairwise |= bss->wpa_pairwise;
	if (bss->wpa & 2) {
		if (bss->rsn_pairwise == 0)
			bss->rsn_pairwise = bss->wpa_pairwise;
		pairwise |= bss->rsn_pairwise;
	}
	if (pairwise & WPA_CIPHER_TKIP)
		bss->wpa_group = WPA_CIPHER_TKIP;
	else
		bss->wpa_group = WPA_CIPHER_CCMP;

	if (bss->wpa && bss->ieee802_1x)
		bss->ssid.security_policy = SECURITY_WPA;
	else if (bss->wpa)
		bss->ssid.security_policy = SECURITY_WPA_PSK;
	else if (bss->ieee802_1x) {
		bss->ssid.security_policy = SECURITY_IEEE_802_1X;
		bss->ssid.wep.default_len = bss->default_wep_key_len;
	} else if (bss->ssid.wep.keys_set)
		bss->ssid.security_policy = SECURITY_STATIC_WEP;
	else
		bss->ssid.security_policy = SECURITY_PLAINTEXT;
		
	if(bss->wpa_group == WPA_CIPHER_TKIP && wpa_s->fgHotspot)
		conf->ieee80211n = 0;
    else
        conf->ieee80211n = 1;

#ifdef CONFIG_WPS
	/*
	 * Enable WPS by default, but require user interaction to actually use
	 * it. Only the internal Registrar is supported.
	 */
	bss->eap_server = 1;
	bss->wps_state = 2;
	bss->ap_setup_locked = 2;
	if (wpa_s->conf->config_methods)
		bss->config_methods = os_strdup(wpa_s->conf->config_methods);
	os_memcpy(bss->device_type, wpa_s->conf->device_type,
		  WPS_DEV_TYPE_LEN);
	if (wpa_s->conf->device_name) {
		bss->device_name = os_strdup(wpa_s->conf->device_name);
		bss->friendly_name = os_strdup(wpa_s->conf->device_name);
	}
	if (wpa_s->conf->manufacturer)
		bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
	if (wpa_s->conf->model_name)
		bss->model_name = os_strdup(wpa_s->conf->model_name);
	if (wpa_s->conf->model_number)
		bss->model_number = os_strdup(wpa_s->conf->model_number);
	if (wpa_s->conf->serial_number)
		bss->serial_number = os_strdup(wpa_s->conf->serial_number);
	if (is_nil_uuid(wpa_s->conf->uuid))
		os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
	else
		os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
	os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
#endif /* CONFIG_WPS */

	if (wpa_s->max_stations &&
	    wpa_s->max_stations < wpa_s->conf->max_num_sta)
		bss->max_num_sta = wpa_s->max_stations;
	else
		bss->max_num_sta = wpa_s->conf->max_num_sta;

	bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;

	return 0;
}
Esempio n. 10
0
static void *rtl871x_driver_init_ops(struct hostapd_data *hapd, struct wpa_init_params *params)
{
	struct rtl871x_driver_data *drv;
	struct ifreq ifr;
	char	ifrn_name[IFNAMSIZ + 1]; // for mgnt_l2_sock/mgnt_sock
	char brname[IFNAMSIZ];

	drv = os_zalloc(sizeof(struct rtl871x_driver_data));
	if (drv == NULL) {
		printf("Could not allocate memory for rtl871x driver data\n");
		return NULL;
	}

	drv->hapd = hapd;
	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->ioctl_sock < 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		goto bad;
	}
	os_memcpy(drv->iface, params->ifname, sizeof(drv->iface));

	linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); // set interface up

	os_memset(&ifr, 0, sizeof(ifr));
	os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
	if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
		perror("ioctl(SIOCGIFINDEX)");
		goto bad;
	}
	drv->ifindex = ifr.ifr_ifindex;
	printf("drv->ifindex=%d\n", drv->ifindex);

	drv->l2_sock = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
					rtl871x_handle_read, drv, 1);

	if (drv->l2_sock == NULL)
		goto bad;

	if (l2_packet_get_own_addr(drv->l2_sock, params->own_addr))
		goto bad;

	if (params->bridge[0]) {
		wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
			   params->bridge[0]);
		drv->l2_sock_recv = l2_packet_init(params->bridge[0], NULL,
						ETH_P_EAPOL, rtl871x_handle_read, drv,
						1);
		if (drv->l2_sock_recv == NULL) {
			drv->l2_sock_recv = drv->l2_sock;
			printf("no br0 interface , let l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock);	
		}
		
	} else if (linux_br_get(brname, drv->iface) == 0) {
		wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
			   "EAPOL receive", brname);
		drv->l2_sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
						rtl871x_handle_read, drv, 1);
		if (drv->l2_sock_recv == NULL)
			goto bad;
	} else {
		drv->l2_sock_recv = drv->l2_sock;
		printf("l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock);	
	}


	os_memset(ifrn_name, 0, sizeof(ifrn_name));
	snprintf(ifrn_name, sizeof(ifrn_name), "mgnt.%s", "wlan0");

#ifdef CONFIG_MGNT_L2SOCK	
	drv->mgnt_l2_sock = NULL;
	drv->mgnt_l2_sock = l2_packet_init(ifrn_name, NULL, ETH_P_80211_RAW,
				       rtl871x_recvive_mgmt_frame, drv, 1);
	if (drv->mgnt_l2_sock == NULL)
		goto bad;
#else
#ifdef CONFIG_MLME_OFFLOAD
	drv->mgnt_sock = -1;
#else
	drv->mgnt_sock = rtl871x_mgnt_sock_init(drv, ifrn_name);
	if (drv->mgnt_sock < 0) {		
		goto bad;
	}
#endif

#endif
	if (rtl871x_set_mode(drv, IW_MODE_MASTER)<0) {
		printf("Could not set interface to master mode!\n");
		goto bad;
	}

#ifndef CONFIG_MLME_OFFLOAD
	rtl871x_set_iface_flags(drv, 1); // set mgnt interface up
#endif

	if (rtl871x_wireless_event_init(drv))
		goto bad;

	os_memcpy(drv->hw_mac, params->own_addr, ETH_ALEN);

	return drv;
	
bad:

	if (drv->l2_sock_recv != NULL && drv->l2_sock_recv != drv->l2_sock)
		l2_packet_deinit(drv->l2_sock_recv);
	
	if (drv->l2_sock != NULL)
		l2_packet_deinit(drv->l2_sock);
	
	if (drv->ioctl_sock >= 0)
		close(drv->ioctl_sock);

#ifdef CONFIG_MGNT_L2SOCK
	if ( drv->mgnt_l2_sock != NULL)
		l2_packet_deinit(drv->mgnt_l2_sock);
#else
	if (drv->mgnt_sock >= 0)
		close(drv->mgnt_sock);
#endif
	
	if (drv != NULL)
		free(drv);
	
	return NULL;
}
int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
{
	struct sockaddr_un addr;
	int s = -1;
	char *fname = NULL;

	hapd->ctrl_sock = -1;

	if (hapd->conf->ctrl_interface == NULL)
		return 0;

#ifdef ANDROID
    os_snprintf(addr.sun_path, sizeof(addr.sun_path), "hostapd_%s",
            hapd->conf->ctrl_interface);
    s = android_get_control_socket(addr.sun_path);
    if (s >= 0)
        goto havesock;
#endif

	if (mkdir(hapd->conf->ctrl_interface, S_IRWXU | S_IRWXG) < 0) {
		if (errno == EEXIST) {
			wpa_printf(MSG_DEBUG, "Using existing control "
				   "interface directory.");
#ifdef ANDROID
            fname = hostapd_ctrl_iface_path(hapd);
            if (fname)
                unlink(fname);
            free(fname);
            rmdir(hapd->conf->ctrl_interface);
            mkdir(hapd->conf->ctrl_interface, S_IRWXU | S_IRWXG);
#endif /* ANDROID */

		} else {
			perror("mkdir[ctrl_interface]");
			goto fail;
		}
	}

#ifdef ANDROID
    if (chown(hapd->conf->ctrl_interface, AID_SYSTEM, AID_WIFI) < 0) {
		perror("chown[ctrl_interface]");
	}
#endif /* ANDROID */

	if (hapd->conf->ctrl_interface_gid_set &&
	    chown(hapd->conf->ctrl_interface, 0,
		  hapd->conf->ctrl_interface_gid) < 0) {
		perror("chown[ctrl_interface]");
		return -1;
	}

	if (os_strlen(hapd->conf->ctrl_interface) + 1 +
	    os_strlen(hapd->conf->iface) >= sizeof(addr.sun_path))
		goto fail;

	s = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (s < 0) {
		perror("socket(PF_UNIX)");
		goto fail;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	fname = hostapd_ctrl_iface_path(hapd);
	if (fname == NULL)
		goto fail;
	os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("bind(PF_UNIX)");
		goto fail;
	}

	if (hapd->conf->ctrl_interface_gid_set &&
	    chown(fname, 0, hapd->conf->ctrl_interface_gid) < 0) {
		perror("chown[ctrl_interface/ifname]");
		goto fail;
	}

	if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
		perror("chmod[ctrl_interface/ifname]");
		goto fail;
	}
	os_free(fname);

#ifdef ANDROID
havesock:
#endif
	hapd->ctrl_sock = s;
	eloop_register_read_sock(s, hostapd_ctrl_iface_receive, hapd,
				 NULL);
	wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);

	return 0;

fail:
	if (s >= 0)
		close(s);
	if (fname) {
		unlink(fname);
		os_free(fname);
	}
	return -1;
}
Esempio n. 12
0
static int rtl871x_set_key_ops(const char *ifname, void *priv, enum wpa_alg alg,
		const u8 *addr, int idx, int txkey, const u8 *seq,
		size_t seq_len, const u8 *key, size_t key_len)
{
	ieee_param *param;	
	u8 *buf;
	char *alg_str;
	size_t blen;
	int ret = 0;
	struct rtl871x_driver_data *drv = priv;

	printf("%s\n", __func__);

	blen = sizeof(*param) + key_len;
	buf = os_zalloc(blen);
	if (buf == NULL)
		return -1;

	param = (ieee_param *)buf;
	param->cmd = RTL871X_SET_ENCRYPTION;
	if (addr == NULL)
		memset(param->sta_addr, 0xff, ETH_ALEN);
	else
		memcpy(param->sta_addr, addr, ETH_ALEN);

	switch (alg) {
	case WPA_ALG_NONE:
		alg_str = "none";
		break;
	case WPA_ALG_WEP:
		alg_str = "WEP";
		break;
	case WPA_ALG_TKIP:
		alg_str = "TKIP";
		break;
	case WPA_ALG_CCMP:
		alg_str = "CCMP";
		break;
	default:
		printf("%s: unknown/unsupported algorithm %d\n",
			__func__, alg);
		return -1;
	}	
	
	os_strlcpy((char *) param->u.crypt.alg, alg_str,
		   IEEE_CRYPT_ALG_NAME_LEN);
	
	param->u.crypt.set_tx = txkey ? 1 : 0;
	param->u.crypt.idx = idx;
	param->u.crypt.key_len = key_len;
	memcpy(param->u.crypt.key, key, key_len);

	if (rtl871x_hostapd_ioctl(drv, param, blen)) {
		printf("Failed to set encryption.\n");
		ret = -1;
	}
	
	os_free(buf);

	return ret;

}
Esempio n. 13
0
/**
 * tlsv1_client_get_cipher - Get current cipher name
 * @conn: TLSv1 client connection data from tlsv1_client_init()
 * @buf: Buffer for the cipher name
 * @buflen: buf size
 * Returns: 0 on success, -1 on failure
 *
 * Get the name of the currently used cipher.
 */
int tlsv1_client_get_cipher(struct tlsv1_client *conn, char *buf,
			    size_t buflen)
{
	char *cipher;

	switch (conn->rl.cipher_suite) {
	case TLS_RSA_WITH_RC4_128_MD5:
		cipher = "RC4-MD5";
		break;
	case TLS_RSA_WITH_RC4_128_SHA:
		cipher = "RC4-SHA";
		break;
	case TLS_RSA_WITH_DES_CBC_SHA:
		cipher = "DES-CBC-SHA";
		break;
	case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
		cipher = "DES-CBC3-SHA";
		break;
	case TLS_DHE_RSA_WITH_DES_CBC_SHA:
		cipher = "DHE-RSA-DES-CBC-SHA";
		break;
	case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
		cipher = "DHE-RSA-DES-CBC3-SHA";
		break;
	case TLS_DH_anon_WITH_RC4_128_MD5:
		cipher = "ADH-RC4-MD5";
		break;
	case TLS_DH_anon_WITH_DES_CBC_SHA:
		cipher = "ADH-DES-SHA";
		break;
	case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
		cipher = "ADH-DES-CBC3-SHA";
		break;
	case TLS_RSA_WITH_AES_128_CBC_SHA:
		cipher = "AES-128-SHA";
		break;
	case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
		cipher = "DHE-RSA-AES-128-SHA";
		break;
	case TLS_DH_anon_WITH_AES_128_CBC_SHA:
		cipher = "ADH-AES-128-SHA";
		break;
	case TLS_RSA_WITH_AES_256_CBC_SHA:
		cipher = "AES-256-SHA";
		break;
	case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
		cipher = "DHE-RSA-AES-256-SHA";
		break;
	case TLS_DH_anon_WITH_AES_256_CBC_SHA:
		cipher = "ADH-AES-256-SHA";
		break;
	case TLS_RSA_WITH_AES_128_CBC_SHA256:
		cipher = "AES-128-SHA256";
		break;
	case TLS_RSA_WITH_AES_256_CBC_SHA256:
		cipher = "AES-256-SHA256";
		break;
	case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
		cipher = "DHE-RSA-AES-128-SHA256";
		break;
	case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
		cipher = "DHE-RSA-AES-256-SHA256";
		break;
	case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
		cipher = "ADH-AES-128-SHA256";
		break;
	case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
		cipher = "ADH-AES-256-SHA256";
		break;
	default:
		return -1;
	}

	if (os_strlcpy(buf, cipher, buflen) >= buflen)
		return -1;
	return 0;
}
Esempio n. 14
0
/*
 * Function to initialize the adapter settings.
 */
int pqisrc_init(pqisrc_softstate_t *softs)
{
	int ret = 0;
	int i = 0, j = 0;

	DBG_FUNC("IN\n");
    
	check_struct_sizes();
    
	/* Init the Sync interface */
	ret = pqisrc_sis_init(softs);
	if (ret) {
		DBG_ERR("SIS Init failed with error %d\n", ret);
		goto err_out;
	}

	/* Init the PQI interface */
	ret = pqisrc_pqi_init(softs);
	if (ret) {
		DBG_ERR("PQI Init failed with error %d\n", ret);
		goto err_pqi;
	}

	/* Setup interrupt */
	ret = os_setup_intr(softs);
	if (ret) {
		DBG_ERR("Interrupt setup failed with error %d\n", ret);
		goto err_intr;
	}

	/* Report event configuration */
        ret = pqisrc_report_event_config(softs);
        if(ret){
                DBG_ERR(" Failed to configure Report events\n");
		goto err_event;
	}
	 
	/* Set event configuration*/
        ret = pqisrc_set_event_config(softs);
        if(ret){
                DBG_ERR(" Failed to configure Set events\n");
                goto err_event;
        }

	/* Check for For PQI spanning */
	ret = pqisrc_get_ctrl_fw_version(softs);
        if(ret){
                DBG_ERR(" Failed to get ctrl fw version\n");
		goto err_fw_version;
        }

	/* update driver version in to FW */
	ret = pqisrc_write_driver_version_to_host_wellness(softs);
	if (ret) {
		DBG_ERR(" Failed to update driver version in to FW");
		goto err_host_wellness;
	}

    
	os_strlcpy(softs->devlist_lock_name, "devlist_lock", LOCKNAME_SIZE);
	ret = os_init_spinlock(softs, &softs->devlist_lock, softs->devlist_lock_name);
	if(ret){
		DBG_ERR(" Failed to initialize devlist_lock\n");
		softs->devlist_lockcreated=false;
		goto err_lock;
	}
	softs->devlist_lockcreated = true;
	
	ret = os_create_semaphore("scan_lock", 1, &softs->scan_lock);
	if(ret != PQI_STATUS_SUCCESS){
		DBG_ERR(" Failed to initialize scan lock\n");
		goto err_scan_lock;
	}
		
	OS_ATOMIC64_SET(softs, num_intrs, 0);
	softs->prev_num_intrs = softs->num_intrs;


	/* Get the PQI configuration table to read heart-beat counter*/
	if (PQI_NEW_HEARTBEAT_MECHANISM(softs)) {
		ret = pqisrc_process_config_table(softs);
		if (ret) {
			DBG_ERR("Failed to process PQI configuration table %d\n", ret);
			goto err_config_tab;
		}
	}

	if (PQI_NEW_HEARTBEAT_MECHANISM(softs))
		softs->prev_heartbeat_count = CTRLR_HEARTBEAT_CNT(softs) - OS_FW_HEARTBEAT_TIMER_INTERVAL;
	
	/* Init device list */
	for(i = 0; i < PQI_MAX_DEVICES; i++)
		for(j = 0; j < PQI_MAX_MULTILUN; j++)
			softs->device_list[i][j] = NULL;

	DBG_FUNC("OUT\n");
	return ret;

err_config_tab:
	os_destroy_semaphore(&softs->scan_lock);
err_scan_lock:
	if(softs->devlist_lockcreated==true){    
		os_uninit_spinlock(&softs->devlist_lock);
		softs->devlist_lockcreated = false;
	}	
err_lock:
err_fw_version:
err_event:
err_host_wellness:
	os_destroy_intr(softs);
err_intr:
	pqisrc_pqi_uninit(softs);
err_pqi:
	pqisrc_sis_uninit(softs);
err_out:
	DBG_FUNC("OUT failed\n");
	return ret;
}
Esempio n. 15
0
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) {
    struct wpa_ctrl *ctrl;
    static int counter = 0;
    int ret;
    size_t res;
    int tries = 0;

    ctrl = os_malloc(sizeof (*ctrl));
    if (ctrl == NULL)
        return NULL;
    os_memset(ctrl, 0, sizeof (*ctrl));

    ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
    if (ctrl->s < 0) {
        os_free(ctrl);
        return NULL;
    }

    ctrl->local.sun_family = AF_UNIX;
    counter++;
try_again:
    ret = os_snprintf(ctrl->local.sun_path, sizeof (ctrl->local.sun_path),
            "/tmp/wpa_ctrl_%d-%d", getpid(), counter);
    if (ret < 0 || (size_t) ret >= sizeof (ctrl->local.sun_path)) {
        close(ctrl->s);
        os_free(ctrl);
        return NULL;
    }
    tries++;
    if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
            sizeof (ctrl->local)) < 0) {
        if (errno == EADDRINUSE && tries < 2) {
            /*
             * getpid() returns unique identifier for this instance
             * of wpa_ctrl, so the existing socket file must have
             * been left by unclean termination of an earlier run.
             * Remove the file and try again.
             */
            unlink(ctrl->local.sun_path);
            goto try_again;
        }
        close(ctrl->s);
        os_free(ctrl);
        return NULL;
    }

    ctrl->dest.sun_family = AF_UNIX;
    res = os_strlcpy(ctrl->dest.sun_path, ctrl_path,
            sizeof (ctrl->dest.sun_path));
    if (res >= sizeof (ctrl->dest.sun_path)) {
        close(ctrl->s);
        os_free(ctrl);
        return NULL;
    }
    if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
            sizeof (ctrl->dest)) < 0) {
        close(ctrl->s);
        unlink(ctrl->local.sun_path);
        os_free(ctrl);
        return NULL;
    }

    return ctrl;
}
Esempio n. 16
0
static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
				  struct wpa_ssid *ssid,
				  struct hostapd_config *conf)
{
	struct hostapd_bss_config *bss = &conf->bss[0];
	int pairwise;

	conf->driver = wpa_s->driver;

	os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));

	if (ssid->frequency == 0) {
		/* default channel 11 */
		conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
		conf->channel = 11;
	} else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) {
		conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
		conf->channel = (ssid->frequency - 2407) / 5;
	} else if ((ssid->frequency >= 5180 && ssid->frequency <= 5240) ||
		   (ssid->frequency >= 5745 && ssid->frequency <= 5825)) {
		conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
		conf->channel = (ssid->frequency - 5000) / 5;
	} else {
		wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
			   ssid->frequency);
		return -1;
	}

	/* TODO: enable HT40 if driver supports it;
	 * drop to 11b if driver does not support 11g */

#ifdef CONFIG_IEEE80211N
	/*
	 * Enable HT20 if the driver supports it, by setting conf->ieee80211n
	 * and a mask of allowed capabilities within conf->ht_capab.
	 * Using default config settings for: conf->ht_op_mode_fixed,
	 * conf->secondary_channel, conf->require_ht
	 */
	if (wpa_s->hw.modes) {
		struct hostapd_hw_modes *mode = NULL;
		int i;
		for (i = 0; i < wpa_s->hw.num_modes; i++) {
			if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
				mode = &wpa_s->hw.modes[i];
				break;
			}
		}
		if (mode && mode->ht_capab) {
			conf->ieee80211n = 1;

			/*
			 * white-list capabilities that won't cause issues
			 * to connecting stations, while leaving the current
			 * capabilities intact (currently disabled SMPS).
			 */
			conf->ht_capab |= mode->ht_capab &
				(HT_CAP_INFO_GREEN_FIELD |
				 HT_CAP_INFO_SHORT_GI20MHZ |
				 HT_CAP_INFO_SHORT_GI40MHZ |
				 HT_CAP_INFO_RX_STBC_MASK |
				 HT_CAP_INFO_MAX_AMSDU_SIZE);
		}
	}
#endif /* CONFIG_IEEE80211N */

#ifdef CONFIG_P2P
	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
		/* Remove 802.11b rates from supported and basic rate sets */
		int *list = os_malloc(4 * sizeof(int));
		if (list) {
			list[0] = 60;
			list[1] = 120;
			list[2] = 240;
			list[3] = -1;
		}
		conf->basic_rates = list;

		list = os_malloc(9 * sizeof(int));
		if (list) {
			list[0] = 60;
			list[1] = 90;
			list[2] = 120;
			list[3] = 180;
			list[4] = 240;
			list[5] = 360;
			list[6] = 480;
			list[7] = 540;
			list[8] = -1;
		}
		conf->supported_rates = list;
	}

	bss->isolate = !wpa_s->conf->p2p_intra_bss;
#endif /* CONFIG_P2P */

	if (ssid->ssid_len == 0) {
		wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
		return -1;
	}
	os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
	bss->ssid.ssid[ssid->ssid_len] = '\0';
	bss->ssid.ssid_len = ssid->ssid_len;
	bss->ssid.ssid_set = 1;

	if (ssid->auth_alg)
		bss->auth_algs = ssid->auth_alg;

	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
		bss->wpa = ssid->proto;
	bss->wpa_key_mgmt = ssid->key_mgmt;
	bss->wpa_pairwise = ssid->pairwise_cipher;
	if (ssid->passphrase) {
		bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
	} else if (ssid->psk_set) {
		os_free(bss->ssid.wpa_psk);
		bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
		if (bss->ssid.wpa_psk == NULL)
			return -1;
		os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
		bss->ssid.wpa_psk->group = 1;
	} else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
		   ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
		struct hostapd_wep_keys *wep = &bss->ssid.wep;
		int i;
		for (i = 0; i < NUM_WEP_KEYS; i++) {
			if (ssid->wep_key_len[i] == 0)
				continue;
			wep->key[i] = os_malloc(ssid->wep_key_len[i]);
			if (wep->key[i] == NULL)
				return -1;
			os_memcpy(wep->key[i], ssid->wep_key[i],
				  ssid->wep_key_len[i]);
			wep->len[i] = ssid->wep_key_len[i];
		}
		wep->idx = ssid->wep_tx_keyidx;
		wep->keys_set = 1;
	}

	/* Select group cipher based on the enabled pairwise cipher suites */
	pairwise = 0;
	if (bss->wpa & 1)
		pairwise |= bss->wpa_pairwise;
	if (bss->wpa & 2) {
		if (bss->rsn_pairwise == 0)
			bss->rsn_pairwise = bss->wpa_pairwise;
		pairwise |= bss->rsn_pairwise;
	}
	if (pairwise & WPA_CIPHER_TKIP)
		bss->wpa_group = WPA_CIPHER_TKIP;
	else
		bss->wpa_group = WPA_CIPHER_CCMP;

	if (bss->wpa && bss->ieee802_1x)
		bss->ssid.security_policy = SECURITY_WPA;
	else if (bss->wpa)
		bss->ssid.security_policy = SECURITY_WPA_PSK;
	else if (bss->ieee802_1x) {
		int cipher = WPA_CIPHER_NONE;
		bss->ssid.security_policy = SECURITY_IEEE_802_1X;
		bss->ssid.wep.default_len = bss->default_wep_key_len;
		if (bss->default_wep_key_len)
			cipher = bss->default_wep_key_len >= 13 ?
				WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
		bss->wpa_group = cipher;
		bss->wpa_pairwise = cipher;
		bss->rsn_pairwise = cipher;
	} else if (bss->ssid.wep.keys_set) {
		int cipher = WPA_CIPHER_WEP40;
		if (bss->ssid.wep.len[0] >= 13)
			cipher = WPA_CIPHER_WEP104;
		bss->ssid.security_policy = SECURITY_STATIC_WEP;
		bss->wpa_group = cipher;
		bss->wpa_pairwise = cipher;
		bss->rsn_pairwise = cipher;
	} else {
		bss->ssid.security_policy = SECURITY_PLAINTEXT;
		bss->wpa_group = WPA_CIPHER_NONE;
		bss->wpa_pairwise = WPA_CIPHER_NONE;
		bss->rsn_pairwise = WPA_CIPHER_NONE;
	}

#ifdef CONFIG_WPS
	/*
	 * Enable WPS by default for open and WPA/WPA2-Personal network, but
	 * require user interaction to actually use it. Only the internal
	 * Registrar is supported.
	 */
	if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
	    bss->ssid.security_policy != SECURITY_PLAINTEXT)
		goto no_wps;
	bss->eap_server = 1;
	bss->wps_state = 2;
	bss->ap_setup_locked = 2;
	if (wpa_s->conf->config_methods)
		bss->config_methods = os_strdup(wpa_s->conf->config_methods);
	os_memcpy(bss->device_type, wpa_s->conf->device_type,
		  WPS_DEV_TYPE_LEN);
	if (wpa_s->conf->device_name) {
		bss->device_name = os_strdup(wpa_s->conf->device_name);
		bss->friendly_name = os_strdup(wpa_s->conf->device_name);
	}
	if (wpa_s->conf->manufacturer)
		bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
	if (wpa_s->conf->model_name)
		bss->model_name = os_strdup(wpa_s->conf->model_name);
	if (wpa_s->conf->model_number)
		bss->model_number = os_strdup(wpa_s->conf->model_number);
	if (wpa_s->conf->serial_number)
		bss->serial_number = os_strdup(wpa_s->conf->serial_number);
	if (is_nil_uuid(wpa_s->conf->uuid))
		os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
	else
		os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
	os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
no_wps:
#endif /* CONFIG_WPS */

	if (wpa_s->max_stations &&
	    wpa_s->max_stations < wpa_s->conf->max_num_sta)
		bss->max_num_sta = wpa_s->max_stations;
	else
		bss->max_num_sta = wpa_s->conf->max_num_sta;

	bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;

	return 0;
}
Esempio n. 17
0
struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface)
{
	struct ifreq ifr;
	struct sockaddr_ll addr;
	int ifindex;
	struct sockaddr_in *paddr, uaddr;
	struct iapp_data *iapp;
	struct ip_mreqn mreq;

	iapp = os_zalloc(sizeof(*iapp));
	if (iapp == NULL)
		return NULL;
	iapp->hapd = hapd;
	iapp->udp_sock = iapp->packet_sock = -1;

	/* TODO:
	 * open socket for sending and receiving IAPP frames over TCP
	 */

	iapp->udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (iapp->udp_sock < 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		iapp_deinit(iapp);
		return NULL;
	}

	os_memset(&ifr, 0, sizeof(ifr));
	os_strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
	if (ioctl(iapp->udp_sock, SIOCGIFINDEX, &ifr) != 0) {
		perror("ioctl(SIOCGIFINDEX)");
		iapp_deinit(iapp);
		return NULL;
	}
	ifindex = ifr.ifr_ifindex;

	if (ioctl(iapp->udp_sock, SIOCGIFADDR, &ifr) != 0) {
		perror("ioctl(SIOCGIFADDR)");
		iapp_deinit(iapp);
		return NULL;
	}
	paddr = (struct sockaddr_in *) &ifr.ifr_addr;
	if (paddr->sin_family != AF_INET) {
		printf("Invalid address family %i (SIOCGIFADDR)\n",
		       paddr->sin_family);
		iapp_deinit(iapp);
		return NULL;
	}
	iapp->own.s_addr = paddr->sin_addr.s_addr;

	if (ioctl(iapp->udp_sock, SIOCGIFBRDADDR, &ifr) != 0) {
		perror("ioctl(SIOCGIFBRDADDR)");
		iapp_deinit(iapp);
		return NULL;
	}
	paddr = (struct sockaddr_in *) &ifr.ifr_addr;
	if (paddr->sin_family != AF_INET) {
		printf("Invalid address family %i (SIOCGIFBRDADDR)\n",
		       paddr->sin_family);
		iapp_deinit(iapp);
		return NULL;
	}
	inet_aton(IAPP_MULTICAST, &iapp->multicast);

	os_memset(&uaddr, 0, sizeof(uaddr));
	uaddr.sin_family = AF_INET;
	uaddr.sin_port = htons(IAPP_UDP_PORT);
	if (bind(iapp->udp_sock, (struct sockaddr *) &uaddr,
		 sizeof(uaddr)) < 0) {
		perror("bind[UDP]");
		iapp_deinit(iapp);
		return NULL;
	}

	os_memset(&mreq, 0, sizeof(mreq));
	mreq.imr_multiaddr = iapp->multicast;
	mreq.imr_address.s_addr = INADDR_ANY;
	mreq.imr_ifindex = 0;
	if (setsockopt(iapp->udp_sock, SOL_IP, IP_ADD_MEMBERSHIP, &mreq,
		       sizeof(mreq)) < 0) {
		perror("setsockopt[UDP,IP_ADD_MEMBERSHIP]");
		iapp_deinit(iapp);
		return NULL;
	}

	iapp->packet_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	if (iapp->packet_sock < 0) {
		perror("socket[PF_PACKET,SOCK_RAW]");
		iapp_deinit(iapp);
		return NULL;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sll_family = AF_PACKET;
	addr.sll_ifindex = ifindex;
	if (bind(iapp->packet_sock, (struct sockaddr *) &addr,
		 sizeof(addr)) < 0) {
		perror("bind[PACKET]");
		iapp_deinit(iapp);
		return NULL;
	}

	if (eloop_register_read_sock(iapp->udp_sock, iapp_receive_udp,
				     iapp, NULL)) {
		printf("Could not register read socket for IAPP.\n");
		iapp_deinit(iapp);
		return NULL;
	}

	printf("IEEE 802.11F (IAPP) using interface %s\n", iface);

	/* TODO: For levels 2 and 3: send RADIUS Initiate-Request, receive
	 * RADIUS Initiate-Accept or Initiate-Reject. IAPP port should actually
	 * be openned only after receiving Initiate-Accept. If Initiate-Reject
	 * is received, IAPP is not started. */

	return iapp;
}
Esempio n. 18
0
static void * wpa_driver_roboswitch_init(void *ctx, const char *ifname)
{
	struct wpa_driver_roboswitch_data *drv;
	char *sep;
	u16 vlan = 0, _read[2];

	drv = os_zalloc(sizeof(*drv));
	if (drv == NULL) return NULL;
	drv->ctx = ctx;
	drv->own_addr[0] = '\0';

	/* copy ifname and take a pointer to the second to last character */
	sep = drv->ifname +
	      os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)) - 2;
	/* find the '.' seperating <interface> and <vlan> */
	while (sep > drv->ifname && *sep != '.') sep--;
	if (sep <= drv->ifname) {
		wpa_printf(MSG_INFO, "%s: No <interface>.<vlan> pair in "
			   "interface name %s", __func__, drv->ifname);
		os_free(drv);
		return NULL;
	}
	*sep = '\0';
	while (*++sep) {
		if (*sep < '0' || *sep > '9') {
			wpa_printf(MSG_INFO, "%s: Invalid vlan specification "
				   "in interface name %s", __func__, ifname);
			os_free(drv);
			return NULL;
		}
		vlan *= 10;
		vlan += *sep - '0';
		if (vlan > ROBO_VLAN_MAX) {
			wpa_printf(MSG_INFO, "%s: VLAN out of range in "
				   "interface name %s", __func__, ifname);
			os_free(drv);
			return NULL;
		}
	}

	drv->fd = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->fd < 0) {
		wpa_printf(MSG_INFO, "%s: Unable to create socket", __func__);
		os_free(drv);
		return NULL;
	}

	os_memset(&drv->ifr, 0, sizeof(drv->ifr));
	os_strlcpy(drv->ifr.ifr_name, drv->ifname, IFNAMSIZ);
	if (ioctl(drv->fd, SIOCGMIIPHY, &drv->ifr) < 0) {
		perror("ioctl[SIOCGMIIPHY]");
		os_free(drv);
		return NULL;
	}
	if (if_mii(&drv->ifr)->phy_id != ROBO_PHY_ADDR) {
		wpa_printf(MSG_INFO, "%s: Invalid phy address (not a "
			   "RoboSwitch?)", __func__);
		os_free(drv);
		return NULL;
	}

	/* set and read back to see if the register can be used */
	_read[0] = ROBO_VLAN_MAX;
	wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350,
				    _read, 1);
	wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350,
				   _read + 1, 1);
	drv->is_5350 = _read[0] == _read[1];

	/* set the read bit */
	vlan |= 1 << 13;
	wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE,
				    drv->is_5350 ? ROBO_VLAN_ACCESS_5350
						 : ROBO_VLAN_ACCESS,
				    &vlan, 1);
	wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_READ, _read,
				   drv->is_5350 ? 2 : 1);
	if (!(drv->is_5350 ? _read[1] & (1 << 4) : _read[0] & (1 << 14))) {
		wpa_printf(MSG_INFO, "%s: Could not get port information for "
				     "VLAN %d", __func__, vlan & ~(1 << 13));
		os_free(drv);
		return NULL;
	}
	drv->ports = _read[0] & 0x001F;
	/* add the MII port */
	drv->ports |= 1 << 8;
	if (wpa_driver_roboswitch_join(drv, drv->ports, pae_group_addr) < 0) {
		wpa_printf(MSG_INFO, "%s: Unable to join PAE group", __func__);
		os_free(drv);
		return NULL;
	} else {
		wpa_printf(MSG_DEBUG, "%s: Added PAE group address to "
			   "RoboSwitch ARL", __func__);
	}

	return drv;
}
Esempio n. 19
0
/**
 * radius_server_get_mib - Get RADIUS server MIB information
 * @data: RADIUS server context from radius_server_init()
 * @buf: Buffer for returning the MIB data in text format
 * @buflen: buf length in octets
 * Returns: Number of octets written into buf
 */
int radius_server_get_mib(struct radius_server_data *data, char *buf,
			  size_t buflen)
{
	int ret, uptime;
	unsigned int idx;
	char *end, *pos;
	struct os_reltime now;
	struct radius_client *cli;

	/* RFC 2619 - RADIUS Authentication Server MIB */

	if (data == NULL || buflen == 0)
		return 0;

	pos = buf;
	end = buf + buflen;

	os_get_reltime(&now);
	uptime = (now.sec - data->start_time.sec) * 100 +
		((now.usec - data->start_time.usec) / 10000) % 100;
	ret = os_snprintf(pos, end - pos,
			  "RADIUS-AUTH-SERVER-MIB\n"
			  "radiusAuthServIdent=hostapd\n"
			  "radiusAuthServUpTime=%d\n"
			  "radiusAuthServResetTime=0\n"
			  "radiusAuthServConfigReset=4\n",
			  uptime);
	if (ret < 0 || ret >= end - pos) {
		*pos = '\0';
		return pos - buf;
	}
	pos += ret;

	ret = os_snprintf(pos, end - pos,
			  "radiusAuthServTotalAccessRequests=%u\n"
			  "radiusAuthServTotalInvalidRequests=%u\n"
			  "radiusAuthServTotalDupAccessRequests=%u\n"
			  "radiusAuthServTotalAccessAccepts=%u\n"
			  "radiusAuthServTotalAccessRejects=%u\n"
			  "radiusAuthServTotalAccessChallenges=%u\n"
			  "radiusAuthServTotalMalformedAccessRequests=%u\n"
			  "radiusAuthServTotalBadAuthenticators=%u\n"
			  "radiusAuthServTotalPacketsDropped=%u\n"
			  "radiusAuthServTotalUnknownTypes=%u\n",
			  data->counters.access_requests,
			  data->counters.invalid_requests,
			  data->counters.dup_access_requests,
			  data->counters.access_accepts,
			  data->counters.access_rejects,
			  data->counters.access_challenges,
			  data->counters.malformed_access_requests,
			  data->counters.bad_authenticators,
			  data->counters.packets_dropped,
			  data->counters.unknown_types);
	if (ret < 0 || ret >= end - pos) {
		*pos = '\0';
		return pos - buf;
	}
	pos += ret;

	for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) {
		char abuf[50], mbuf[50];
#ifdef CONFIG_IPV6
		if (data->ipv6) {
			if (inet_ntop(AF_INET6, &cli->addr6, abuf,
				      sizeof(abuf)) == NULL)
				abuf[0] = '\0';
			if (inet_ntop(AF_INET6, &cli->mask6, abuf,
				      sizeof(mbuf)) == NULL)
				mbuf[0] = '\0';
		}
#endif /* CONFIG_IPV6 */
		if (!data->ipv6) {
			os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf));
			os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf));
		}

		ret = os_snprintf(pos, end - pos,
				  "radiusAuthClientIndex=%u\n"
				  "radiusAuthClientAddress=%s/%s\n"
				  "radiusAuthServAccessRequests=%u\n"
				  "radiusAuthServDupAccessRequests=%u\n"
				  "radiusAuthServAccessAccepts=%u\n"
				  "radiusAuthServAccessRejects=%u\n"
				  "radiusAuthServAccessChallenges=%u\n"
				  "radiusAuthServMalformedAccessRequests=%u\n"
				  "radiusAuthServBadAuthenticators=%u\n"
				  "radiusAuthServPacketsDropped=%u\n"
				  "radiusAuthServUnknownTypes=%u\n",
				  idx,
				  abuf, mbuf,
				  cli->counters.access_requests,
				  cli->counters.dup_access_requests,
				  cli->counters.access_accepts,
				  cli->counters.access_rejects,
				  cli->counters.access_challenges,
				  cli->counters.malformed_access_requests,
				  cli->counters.bad_authenticators,
				  cli->counters.packets_dropped,
				  cli->counters.unknown_types);
		if (ret < 0 || ret >= end - pos) {
			*pos = '\0';
			return pos - buf;
		}
		pos += ret;
	}

	return pos - buf;
}
Esempio n. 20
0
static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx)
{
	struct radius_das_data *das = eloop_ctx;
	u8 buf[1500];
	union {
		struct sockaddr_storage ss;
		struct sockaddr_in sin;
#ifdef CONFIG_IPV6
		struct sockaddr_in6 sin6;
#endif /* CONFIG_IPV6 */
	} from;
	char abuf[50];
	int from_port = 0;
	socklen_t fromlen;
	int len;
	struct radius_msg *msg, *reply = NULL;
	struct radius_hdr *hdr;
	struct wpabuf *rbuf;
	u32 val;
	int res;
	struct os_time now;

	fromlen = sizeof(from);
	len = recvfrom(sock, buf, sizeof(buf), 0,
		       (struct sockaddr *) &from.ss, &fromlen);
	if (len < 0) {
		wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno));
		return;
	}

	os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
	from_port = ntohs(from.sin.sin_port);

	wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d",
		   len, abuf, from_port);
	if (das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) {
		wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client");
		return;
	}

	msg = radius_msg_parse(buf, len);
	if (msg == NULL) {
		wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet "
			   "from %s:%d failed", abuf, from_port);
		return;
	}

	if (wpa_debug_level <= MSG_MSGDUMP)
		radius_msg_dump(msg);

	if (radius_msg_verify_das_req(msg, das->shared_secret,
				       das->shared_secret_len)) {
		wpa_printf(MSG_DEBUG, "DAS: Invalid authenticator in packet "
			   "from %s:%d - drop", abuf, from_port);
		goto fail;
	}

	os_get_time(&now);
	res = radius_msg_get_attr(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
				  (u8 *) &val, 4);
	if (res == 4) {
		u32 timestamp = ntohl(val);
		if (abs(now.sec - timestamp) > das->time_window) {
			wpa_printf(MSG_DEBUG, "DAS: Unacceptable "
				   "Event-Timestamp (%u; local time %u) in "
				   "packet from %s:%d - drop",
				   timestamp, (unsigned int) now.sec,
				   abuf, from_port);
			goto fail;
		}
	} else if (das->require_event_timestamp) {
		wpa_printf(MSG_DEBUG, "DAS: Missing Event-Timestamp in packet "
			   "from %s:%d - drop", abuf, from_port);
		goto fail;
	}

	hdr = radius_msg_get_hdr(msg);

	switch (hdr->code) {
	case RADIUS_CODE_DISCONNECT_REQUEST:
		reply = radius_das_disconnect(das, msg, abuf, from_port);
		break;
	case RADIUS_CODE_COA_REQUEST:
		/* TODO */
		reply = radius_msg_new(RADIUS_CODE_COA_NAK,
				       hdr->identifier);
		if (reply == NULL)
			break;

		/* Unsupported Service */
		radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, 405);
		break;
	default:
		wpa_printf(MSG_DEBUG, "DAS: Unexpected RADIUS code %u in "
			   "packet from %s:%d",
			   hdr->code, abuf, from_port);
	}

	if (reply) {
		wpa_printf(MSG_DEBUG, "DAS: Reply to %s:%d", abuf, from_port);

		if (!radius_msg_add_attr_int32(reply,
					       RADIUS_ATTR_EVENT_TIMESTAMP,
					       now.sec)) {
			wpa_printf(MSG_DEBUG, "DAS: Failed to add "
				   "Event-Timestamp attribute");
		}

		if (radius_msg_finish_das_resp(reply, das->shared_secret,
					       das->shared_secret_len, hdr) <
		    0) {
			wpa_printf(MSG_DEBUG, "DAS: Failed to add "
				   "Message-Authenticator attribute");
		}

		if (wpa_debug_level <= MSG_MSGDUMP)
			radius_msg_dump(reply);

		rbuf = radius_msg_get_buf(reply);
		res = sendto(das->sock, wpabuf_head(rbuf),
			     wpabuf_len(rbuf), 0,
			     (struct sockaddr *) &from.ss, fromlen);
		if (res < 0) {
			wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s",
				   abuf, from_port, strerror(errno));
		}
	}

fail:
	radius_msg_free(msg);
	radius_msg_free(reply);
}
Esempio n. 21
0
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
		     char *reply, size_t *reply_len,
		     void (*msg_cb)(char *msg, size_t len))
{
	struct timeval tv;
	int res;
	fd_set rfds;
	const char *_cmd;
	char *cmd_buf = NULL;
	size_t _cmd_len;

#ifdef CONFIG_CTRL_IFACE_UDP
	if (ctrl->cookie) {
		char *pos;
		_cmd_len = os_strlen(ctrl->cookie) + 1 + cmd_len;
		cmd_buf = os_malloc(_cmd_len);
		if (cmd_buf == NULL)
			return -1;
		_cmd = cmd_buf;
		pos = cmd_buf;
		os_strlcpy(pos, ctrl->cookie, _cmd_len);
		pos += os_strlen(ctrl->cookie);
		*pos++ = ' ';
		os_memcpy(pos, cmd, cmd_len);
	} else
#endif /* CONFIG_CTRL_IFACE_UDP */
	{
		_cmd = cmd;
		_cmd_len = cmd_len;
	}

	if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
		os_free(cmd_buf);
		return -1;
	}
	os_free(cmd_buf);

	for (;;) {
		tv.tv_sec = 10;
		tv.tv_usec = 0;
		FD_ZERO(&rfds);
		FD_SET(ctrl->s, &rfds);
		res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
		if (res < 0)
			return res;
		if (FD_ISSET(ctrl->s, &rfds)) {
			res = recv(ctrl->s, reply, *reply_len, 0);
			if (res < 0)
				return res;
			if (res > 0 && reply[0] == '<') {
				/* This is an unsolicited message from
				 * wpa_supplicant, not the reply to the
				 * request. Use msg_cb to report this to the
				 * caller. */
				if (msg_cb) {
					/* Make sure the message is nul
					 * terminated. */
					if ((size_t) res == *reply_len)
						res = (*reply_len) - 1;
					reply[res] = '\0';
					msg_cb(reply, res);
				}
				continue;
			}
			*reply_len = res;
			break;
		} else {
			return -2;
		}
	}
	return 0;
}
Esempio n. 22
0
static void
wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
{
	struct bsd_driver_data *drv = sock_ctx;
	char *buf;
	struct if_announcemsghdr *ifan;
	struct if_msghdr *ifm;
	struct rt_msghdr *rtm;
	union wpa_event_data event;
	struct ieee80211_michael_event *mic;
	struct ieee80211_leave_event *leave;
	struct ieee80211_join_event *join;
	int n, len;

	len = rtbuf_len();

	buf = os_malloc(len);
	if (buf == NULL) {
		wpa_printf(MSG_ERROR, "%s os_malloc() failed\n", __func__);
		return;
	}

	n = read(sock, buf, len);
	if (n < 0) {
		if (errno != EINTR && errno != EAGAIN)
			wpa_printf(MSG_ERROR, "%s read() failed: %s\n",
				   __func__, strerror(errno));
		os_free(buf);
		return;
	}

	rtm = (struct rt_msghdr *) buf;
	if (rtm->rtm_version != RTM_VERSION) {
		wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
			   rtm->rtm_version);
		os_free(buf);
		return;
	}
	os_memset(&event, 0, sizeof(event));
	switch (rtm->rtm_type) {
	case RTM_IFANNOUNCE:
		ifan = (struct if_announcemsghdr *) rtm;
		if (ifan->ifan_index != drv->ifindex)
			break;
		os_strlcpy(event.interface_status.ifname, drv->ifname,
			   sizeof(event.interface_status.ifname));
		switch (ifan->ifan_what) {
		case IFAN_DEPARTURE:
			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
		default:
			os_free(buf);
			return;
		}
		wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
			   event.interface_status.ifname,
			   ifan->ifan_what == IFAN_DEPARTURE ?
				"removed" : "added");
		wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
		break;
	case RTM_IEEE80211:
		ifan = (struct if_announcemsghdr *) rtm;
		if (ifan->ifan_index != drv->ifindex)
			break;
		switch (ifan->ifan_what) {
		case RTM_IEEE80211_ASSOC:
		case RTM_IEEE80211_REASSOC:
			if (drv->is_ap)
				break;
			wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
			break;
		case RTM_IEEE80211_DISASSOC:
			if (drv->is_ap)
				break;
			wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
			break;
		case RTM_IEEE80211_SCAN:
			if (drv->is_ap)
				break;
			wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
			break;
		case RTM_IEEE80211_LEAVE:
			leave = (struct ieee80211_leave_event *) &ifan[1];
			drv_event_disassoc(ctx, leave->iev_addr);
			break;
		case RTM_IEEE80211_JOIN:
#ifdef RTM_IEEE80211_REJOIN
		case RTM_IEEE80211_REJOIN:
#endif
			join = (struct ieee80211_join_event *) &ifan[1];
			bsd_new_sta(drv, ctx, join->iev_addr);
			break;
		case RTM_IEEE80211_REPLAY:
			/* ignore */
			break;
		case RTM_IEEE80211_MICHAEL:
			mic = (struct ieee80211_michael_event *) &ifan[1];
			wpa_printf(MSG_DEBUG,
				"Michael MIC failure wireless event: "
				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
				MAC2STR(mic->iev_src));

			os_memset(&event, 0, sizeof(event));
			event.michael_mic_failure.unicast =
				!IEEE80211_IS_MULTICAST(mic->iev_dst);
			wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,
				&event);
			break;
		}
		break;
	case RTM_IFINFO:
		ifm = (struct if_msghdr *) rtm;
		if (ifm->ifm_index != drv->ifindex)
			break;
		if ((rtm->rtm_flags & RTF_UP) == 0) {
			os_strlcpy(event.interface_status.ifname, drv->ifname,
				   sizeof(event.interface_status.ifname));
			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
				   event.interface_status.ifname);
			wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
		}
		break;
	}
	os_free(buf);
}
static void eap_sim_process_start(struct eap_sm *sm,
				  struct eap_sim_data *data,
				  struct wpabuf *respData,
				  struct eap_sim_attrs *attr)
{
	size_t identity_len;
	u8 ver_list[2];
	u8 *new_identity;
	char *username;

	wpa_printf(MSG_DEBUG, "EAP-SIM: Receive start response");

	if (data->start_round == 0) {
		/*
		 * Special case for AT_COUNTER_TOO_SMALL recovery - no identity
		 * was requested since we already know it.
		 */
		goto skip_id_update;
	}

	/*
	 * We always request identity in SIM/Start, so the peer is required to
	 * have replied with one.
	 */
	if (!attr->identity || attr->identity_len == 0) {
		wpa_printf(MSG_DEBUG, "EAP-SIM: Peer did not provide any "
			   "identity");
		goto failed;
	}

	new_identity = os_malloc(attr->identity_len);
	if (new_identity == NULL)
		goto failed;
	os_free(sm->identity);
	sm->identity = new_identity;
	os_memcpy(sm->identity, attr->identity, attr->identity_len);
	sm->identity_len = attr->identity_len;

	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity",
			  sm->identity, sm->identity_len);
	username = sim_get_username(sm->identity, sm->identity_len);
	if (username == NULL)
		goto failed;

	if (username[0] == EAP_SIM_REAUTH_ID_PREFIX) {
		wpa_printf(MSG_DEBUG, "EAP-SIM: Reauth username '%s'",
			   username);
		data->reauth = eap_sim_db_get_reauth_entry(
			sm->eap_sim_db_priv, username);
		os_free(username);
		if (data->reauth == NULL) {
			wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown reauth "
				   "identity - request full auth identity");
			/* Remain in START state for another round */
			return;
		}
		wpa_printf(MSG_DEBUG, "EAP-SIM: Using fast re-authentication");
		os_strlcpy(data->permanent, data->reauth->permanent,
			   sizeof(data->permanent));
		data->counter = data->reauth->counter;
		os_memcpy(data->mk, data->reauth->mk, EAP_SIM_MK_LEN);
		eap_sim_state(data, REAUTH);
		return;
	}

	if (username[0] == EAP_SIM_PSEUDONYM_PREFIX) {
		const char *permanent;
		wpa_printf(MSG_DEBUG, "EAP-SIM: Pseudonym username '%s'",
			   username);
		permanent = eap_sim_db_get_permanent(
			sm->eap_sim_db_priv, username);
		os_free(username);
		if (permanent == NULL) {
			wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown pseudonym "
				   "identity - request permanent identity");
			/* Remain in START state for another round */
			return;
		}
		os_strlcpy(data->permanent, permanent,
			   sizeof(data->permanent));
	} else if (username[0] == EAP_SIM_PERMANENT_PREFIX) {
		wpa_printf(MSG_DEBUG, "EAP-SIM: Permanent username '%s'",
			   username);
		os_strlcpy(data->permanent, username, sizeof(data->permanent));
		os_free(username);
	} else {
		wpa_printf(MSG_DEBUG, "EAP-SIM: Unrecognized username '%s'",
			   username);
		os_free(username);
		goto failed;
	}

skip_id_update:
	/* Full authentication */

	if (attr->nonce_mt == NULL || attr->selected_version < 0) {
		wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "
			   "required attributes");
		goto failed;
	}

	if (!eap_sim_supported_ver(data, attr->selected_version)) {
		wpa_printf(MSG_DEBUG, "EAP-SIM: Peer selected unsupported "
			   "version %d", attr->selected_version);
		goto failed;
	}

	data->counter = 0; /* reset re-auth counter since this is full auth */
	data->reauth = NULL;

	data->num_chal = eap_sim_db_get_gsm_triplets(
		sm->eap_sim_db_priv, data->permanent, EAP_SIM_MAX_CHAL,
		(u8 *) data->rand, (u8 *) data->kc, (u8 *) data->sres, sm);
	if (data->num_chal == EAP_SIM_DB_PENDING) {
		wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication triplets "
			   "not yet available - pending request");
		sm->method_pending = METHOD_PENDING_WAIT;
		return;
	}
	if (data->num_chal < 2) {
		wpa_printf(MSG_INFO, "EAP-SIM: Failed to get GSM "
			   "authentication triplets for the peer");
		goto failed;
	}

	identity_len = sm->identity_len;
	while (identity_len > 0 && sm->identity[identity_len - 1] == '\0') {
		wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop last null "
			   "character from identity");
		identity_len--;
	}
	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity for MK derivation",
			  sm->identity, identity_len);

	os_memcpy(data->nonce_mt, attr->nonce_mt, EAP_SIM_NONCE_MT_LEN);
	WPA_PUT_BE16(ver_list, EAP_SIM_VERSION);
	eap_sim_derive_mk(sm->identity, identity_len, attr->nonce_mt,
			  attr->selected_version, ver_list, sizeof(ver_list),
			  data->num_chal, (const u8 *) data->kc, data->mk);
	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
			    data->emsk);

	eap_sim_state(data, CHALLENGE);
	return;

failed:
	data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
	eap_sim_state(data, NOTIFICATION);
}
Esempio n. 24
0
static void *
wpa_driver_bsd_init(void *ctx, const char *ifname)
{
#define	GETPARAM(drv, param, v) \
	(((v) = get80211param(drv, param)) != -1)
	struct bsd_driver_data *drv;

	drv = os_zalloc(sizeof(*drv));
	if (drv == NULL)
		return NULL;
	/*
	 * NB: We require the interface name be mappable to an index.
	 *     This implies we do not support having wpa_supplicant
	 *     wait for an interface to appear.  This seems ok; that
	 *     doesn't belong here; it's really the job of devd.
	 */
	drv->ifindex = if_nametoindex(ifname);
	if (drv->ifindex == 0) {
		wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
			   __func__, ifname);
		goto fail1;
	}
	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->sock < 0)
		goto fail1;
	drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
	if (drv->route < 0)
		goto fail;
	eloop_register_read_sock(drv->route,
		wpa_driver_bsd_event_receive, ctx, drv);

	drv->ctx = ctx;
	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));

	/* Down interface during setup. */
	if (bsd_ctrl_iface(drv, 0) < 0)
		goto fail;

	if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
		wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
			__func__, strerror(errno));
		goto fail;
	}
	if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) {
		wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s",
			__func__, strerror(errno));
		goto fail;
	}
	if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) {
		wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s",
			__func__, strerror(errno));
		goto fail;
	}

	if (wpa_driver_bsd_capa(drv))
		goto fail;

	return drv;
fail:
	close(drv->sock);
fail1:
	os_free(drv);
	return NULL;
#undef GETPARAM
}
static void *
ar6000_init(struct hostapd_data *hapd, struct wpa_init_params *params)
{
    struct ar6000_driver_data *drv;
    struct ifreq ifr;
    struct iwreq iwr;
	char brname[IFNAMSIZ];

    drv = os_zalloc(sizeof(struct ar6000_driver_data));
    if (drv == NULL) {
        printf("Could not allocate memory for ar6000 driver data\n");
        return NULL;
    }

    drv->hapd = hapd;
    drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (drv->ioctl_sock < 0) {
        perror("socket[PF_INET,SOCK_DGRAM]");
		wpa_printf(MSG_ERROR, "%s: Failed socket[PF_INET,SOCK_DGRAM]",__func__);			
        goto bad;
    }
    os_strlcpy(drv->iface, params->ifname, sizeof(drv->iface));

    memset(&ifr, 0, sizeof(ifr));
    os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
    if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
        perror("ioctl(SIOCGIFINDEX)");
		wpa_printf(MSG_ERROR, "%s: Failed ioctl(SIOCGIFINDEX): iface=%s",__func__, drv->iface);			
        goto bad;
    }
    drv->ifindex = ifr.ifr_ifindex;

    drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
                    handle_read, drv, 1);
    if (drv->sock_xmit == NULL)
        goto bad;
    if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
        goto bad;
    if (params->bridge[0]) {
        wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
            params->bridge[0]);
        drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
                        ETH_P_EAPOL, handle_read, drv,
                        1);
        if (drv->sock_recv == NULL)
            goto bad;
	} else if (linux_br_get(brname, drv->iface) == 0) {
		wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
			   "EAPOL receive", brname);
		drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
						handle_read, drv, 1);
		if (drv->sock_recv == NULL)
			goto bad;
    } else
        drv->sock_recv = drv->sock_xmit;

    memset(&iwr, 0, sizeof(iwr));
    os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);

    iwr.u.mode = IW_MODE_MASTER;

    if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
        perror("ioctl[SIOCSIWMODE]");
		wpa_printf(MSG_ERROR, "%s: Failed ioctl[SIOCSIWMODE]",__func__);			
        goto bad;
    }

	/* mark down during setup */
	linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
    ar6000_set_privacy(drv, 0); /* default to no privacy */
	
	/* Set the maximum number of allowed stations */
	ar6000_set_max_num_sta(drv,hapd->conf->max_num_sta);
	
	if (ar6000_wireless_event_init(drv))
		goto bad;

    return drv;
bad:
	if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
		l2_packet_deinit(drv->sock_recv);
	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
    if (drv->ioctl_sock >= 0)
        close(drv->ioctl_sock);
    if (drv != NULL)
        free(drv);
    return NULL;
}
Esempio n. 26
0
static int wpa_driver_privsep_set_param(void *priv, const char *param)
{
	struct wpa_driver_privsep_data *drv = priv;
	const char *pos;
	char *own_dir, *priv_dir;
	static unsigned int counter = 0;
	size_t len;
	struct sockaddr_un addr;

	wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
	if (param == NULL)
		pos = NULL;
	else
		pos = os_strstr(param, "own_dir=");
	if (pos) {
		char *end;
		own_dir = os_strdup(pos + 8);
		if (own_dir == NULL)
			return -1;
		end = os_strchr(own_dir, ' ');
		if (end)
			*end = '\0';
	} else {
		own_dir = os_strdup("/tmp");
		if (own_dir == NULL)
			return -1;
	}

	if (param == NULL)
		pos = NULL;
	else
		pos = os_strstr(param, "priv_dir=");
	if (pos) {
		char *end;
		priv_dir = os_strdup(pos + 9);
		if (priv_dir == NULL) {
			os_free(own_dir);
			return -1;
		}
		end = os_strchr(priv_dir, ' ');
		if (end)
			*end = '\0';
	} else {
		priv_dir = os_strdup("/var/run/wpa_priv");
		if (priv_dir == NULL) {
			os_free(own_dir);
			return -1;
		}
	}

	len = os_strlen(own_dir) + 50;
	drv->own_socket_path = os_malloc(len);
	if (drv->own_socket_path == NULL) {
		os_free(priv_dir);
		os_free(own_dir);
		return -1;
	}
	os_snprintf(drv->own_socket_path, len, "%s/wpa_privsep-%d-%d",
		    own_dir, getpid(), counter++);

	len = os_strlen(own_dir) + 50;
	drv->own_cmd_path = os_malloc(len);
	if (drv->own_cmd_path == NULL) {
		os_free(drv->own_socket_path);
		drv->own_socket_path = NULL;
		os_free(priv_dir);
		os_free(own_dir);
		return -1;
	}
	os_snprintf(drv->own_cmd_path, len, "%s/wpa_privsep-%d-%d",
		    own_dir, getpid(), counter++);

	os_free(own_dir);

	drv->priv_addr.sun_family = AF_UNIX;
	os_snprintf(drv->priv_addr.sun_path, sizeof(drv->priv_addr.sun_path),
		    "%s/%s", priv_dir, drv->ifname);
	os_free(priv_dir);

	drv->priv_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (drv->priv_socket < 0) {
		perror("socket(PF_UNIX)");
		os_free(drv->own_socket_path);
		drv->own_socket_path = NULL;
		return -1;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
	if (bind(drv->priv_socket, (struct sockaddr *) &addr, sizeof(addr)) <
	    0) {
		perror("privsep-set-params priv-sock: bind(PF_UNIX)");
		close(drv->priv_socket);
		drv->priv_socket = -1;
		unlink(drv->own_socket_path);
		os_free(drv->own_socket_path);
		drv->own_socket_path = NULL;
		return -1;
	}

	eloop_register_read_sock(drv->priv_socket, wpa_driver_privsep_receive,
				 drv, NULL);

	drv->cmd_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (drv->cmd_socket < 0) {
		perror("socket(PF_UNIX)");
		os_free(drv->own_cmd_path);
		drv->own_cmd_path = NULL;
		return -1;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_strlcpy(addr.sun_path, drv->own_cmd_path, sizeof(addr.sun_path));
	if (bind(drv->cmd_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0)
	{
		perror("privsep-set-params cmd-sock: bind(PF_UNIX)");
		close(drv->cmd_socket);
		drv->cmd_socket = -1;
		unlink(drv->own_cmd_path);
		os_free(drv->own_cmd_path);
		drv->own_cmd_path = NULL;
		return -1;
	}

	if (wpa_priv_reg_cmd(drv, PRIVSEP_CMD_REGISTER) < 0) {
		wpa_printf(MSG_ERROR, "Failed to register with wpa_priv");
		return -1;
	}

	return 0;
}
static int
set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len)
{
	struct iwreq iwr;
	int do_inline = len < IFNAMSIZ;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
#ifdef IEEE80211_IOCTL_FILTERFRAME
	/* FILTERFRAME must be NOT inline, regardless of size. */
	if (op == IEEE80211_IOCTL_FILTERFRAME)
		do_inline = 0;
#endif /* IEEE80211_IOCTL_FILTERFRAME */
	if (op == IEEE80211_IOCTL_SET_APPIEBUF)
		do_inline = 0;
	if (do_inline) {
		/*
		 * Argument data fits inline; put it there.
		 */
		memcpy(iwr.u.name, data, len);
	} else {
		/*
		 * Argument data too big for inline transfer; setup a
		 * parameter block instead; the kernel will transfer
		 * the data for the driver.
		 */
		iwr.u.data.pointer = data;
		iwr.u.data.length = len;
	}

	if (ioctl(drv->ioctl_sock, op, &iwr) < 0) {
#ifdef MADWIFI_NG
		int first = IEEE80211_IOCTL_SETPARAM;
		static const char *opnames[] = {
			"ioctl[IEEE80211_IOCTL_SETPARAM]",
			"ioctl[IEEE80211_IOCTL_GETPARAM]",
			"ioctl[IEEE80211_IOCTL_SETMODE]",
			"ioctl[IEEE80211_IOCTL_GETMODE]",
			"ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
			"ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
			"ioctl[IEEE80211_IOCTL_SETCHANLIST]",
			"ioctl[IEEE80211_IOCTL_GETCHANLIST]",
			"ioctl[IEEE80211_IOCTL_CHANSWITCH]",
			"ioctl[IEEE80211_IOCTL_GET_APPIEBUF]",
			"ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
			"ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
			"ioctl[IEEE80211_IOCTL_FILTERFRAME]",
			"ioctl[IEEE80211_IOCTL_GETCHANINFO]",
			"ioctl[IEEE80211_IOCTL_SETOPTIE]",
			"ioctl[IEEE80211_IOCTL_GETOPTIE]",
			"ioctl[IEEE80211_IOCTL_SETMLME]",
			NULL,
			"ioctl[IEEE80211_IOCTL_SETKEY]",
			NULL,
			"ioctl[IEEE80211_IOCTL_DELKEY]",
			NULL,
			"ioctl[IEEE80211_IOCTL_ADDMAC]",
			NULL,
			"ioctl[IEEE80211_IOCTL_DELMAC]",
			NULL,
			"ioctl[IEEE80211_IOCTL_WDSMAC]",
			NULL,
			"ioctl[IEEE80211_IOCTL_WDSDELMAC]",
			NULL,
			"ioctl[IEEE80211_IOCTL_KICKMAC]",
		};
#else /* MADWIFI_NG */
		int first = IEEE80211_IOCTL_SETPARAM;
		static const char *opnames[] = {
			"ioctl[IEEE80211_IOCTL_SETPARAM]",
			"ioctl[IEEE80211_IOCTL_GETPARAM]",
			"ioctl[IEEE80211_IOCTL_SETKEY]",
			"ioctl[SIOCIWFIRSTPRIV+3]",
			"ioctl[IEEE80211_IOCTL_DELKEY]",
			"ioctl[SIOCIWFIRSTPRIV+5]",
			"ioctl[IEEE80211_IOCTL_SETMLME]",
			"ioctl[SIOCIWFIRSTPRIV+7]",
			"ioctl[IEEE80211_IOCTL_SETOPTIE]",
			"ioctl[IEEE80211_IOCTL_GETOPTIE]",
			"ioctl[IEEE80211_IOCTL_ADDMAC]",
			"ioctl[SIOCIWFIRSTPRIV+11]",
			"ioctl[IEEE80211_IOCTL_DELMAC]",
			"ioctl[SIOCIWFIRSTPRIV+13]",
			"ioctl[IEEE80211_IOCTL_CHANLIST]",
			"ioctl[SIOCIWFIRSTPRIV+15]",
			"ioctl[IEEE80211_IOCTL_GETRSN]",
			"ioctl[SIOCIWFIRSTPRIV+17]",
			"ioctl[IEEE80211_IOCTL_GETKEY]",
		};
#endif /* MADWIFI_NG */
		int idx = op - first;
		if (first <= op &&
		    idx < (int) (sizeof(opnames) / sizeof(opnames[0])) &&
		    opnames[idx])
			perror(opnames[idx]);
		else
			perror("ioctl[unknown???]");
		return -1;
	}
	return 0;
}
Esempio n. 28
0
static int cavp_rsa_sig_ver(const char *fname)
{
    FILE *f;
    int ret = 0;
    char buf[15000], *pos, *pos2;
    u8 msg[200], n[512], s[512], em[512], e[512];
    size_t msg_len = 0, n_len = 0, s_len = 0, em_len, e_len = 0;
    size_t tmp_len;
    char sha_alg[20];
    int ok = 0;

    printf("CAVP RSA SigVer test vectors from %s\n", fname);

    f = fopen(fname, "r");
    if (f == NULL) {
        printf("%s does not exist - cannot validate CAVP RSA SigVer test vectors\n",
               fname);
        return 0;
    }

    while (fgets(buf, sizeof(buf), f)) {
        pos = os_strchr(buf, '=');
        if (pos == NULL)
            continue;
        pos2 = pos - 1;
        while (pos2 >= buf && *pos2 == ' ')
            *pos2-- = '\0';
        *pos++ = '\0';
        while (*pos == ' ')
            *pos++ = '\0';
        pos2 = os_strchr(pos, '\r');
        if (!pos2)
            pos2 = os_strchr(pos, '\n');
        if (pos2)
            *pos2 = '\0';
        else
            pos2 = pos + os_strlen(pos);

        if (os_strcmp(buf, "SHAAlg") == 0) {
            os_strlcpy(sha_alg, pos, sizeof(sha_alg));
        } else if (os_strcmp(buf, "Msg") == 0) {
            tmp_len = os_strlen(pos);
            if (tmp_len > sizeof(msg) * 2) {
                printf("Too long Msg\n");
                return -1;
            }
            msg_len = tmp_len / 2;
            if (hexstr2bin(pos, msg, msg_len) < 0) {
                printf("Invalid hex string '%s'\n", pos);
                ret++;
                break;
            }
        } else if (os_strcmp(buf, "n") == 0) {
            tmp_len = os_strlen(pos);
            if (tmp_len > sizeof(n) * 2) {
                printf("Too long n\n");
                return -1;
            }
            n_len = tmp_len / 2;
            if (hexstr2bin(pos, n, n_len) < 0) {
                printf("Invalid hex string '%s'\n", pos);
                ret++;
                break;
            }
        } else if (os_strcmp(buf, "e") == 0) {
            tmp_len = os_strlen(pos);
            if (tmp_len > sizeof(e) * 2) {
                printf("Too long e\n");
                return -1;
            }
            e_len = tmp_len / 2;
            if (hexstr2bin(pos, e, e_len) < 0) {
                printf("Invalid hex string '%s'\n", pos);
                ret++;
                break;
            }
        } else if (os_strcmp(buf, "S") == 0) {
            tmp_len = os_strlen(pos);
            if (tmp_len > sizeof(s) * 2) {
                printf("Too long S\n");
                return -1;
            }
            s_len = tmp_len / 2;
            if (hexstr2bin(pos, s, s_len) < 0) {
                printf("Invalid hex string '%s'\n", pos);
                ret++;
                break;
            }
        } else if (os_strncmp(buf, "EM", 2) == 0) {
            tmp_len = os_strlen(pos);
            if (tmp_len > sizeof(em) * 2)
                return -1;
            em_len = tmp_len / 2;
            if (hexstr2bin(pos, em, em_len) < 0) {
                printf("Invalid hex string '%s'\n", pos);
                ret++;
                break;
            }
        } else if (os_strcmp(buf, "Result") == 0) {
            const u8 *addr[1];
            size_t len[1];
            struct crypto_public_key *pk;
            int res;
            u8 hash[32];
            size_t hash_len;
            const struct asn1_oid *alg;

            addr[0] = msg;
            len[0] = msg_len;
            if (os_strcmp(sha_alg, "SHA1") == 0) {
                if (sha1_vector(1, addr, len, hash) < 0)
                    return -1;
                hash_len = 20;
                alg = &asn1_sha1_oid;
            } else if (os_strcmp(sha_alg, "SHA256") == 0) {
                if (sha256_vector(1, addr, len, hash) < 0)
                    return -1;
                hash_len = 32;
                alg = &asn1_sha256_oid;
            } else {
                continue;
            }

            printf("\nExpected result: %s\n", pos);
            wpa_hexdump(MSG_INFO, "Hash(Msg)", hash, hash_len);

            pk = crypto_public_key_import_parts(n, n_len,
                                                e, e_len);
            if (pk == NULL) {
                printf("Failed to import public key\n");
                ret++;
                continue;
            }

            res = pkcs1_v15_sig_ver(pk, s, s_len, alg,
                                    hash, hash_len);
            crypto_public_key_free(pk);
            if ((*pos == 'F' && !res) || (*pos != 'F' && res)) {
                printf("FAIL\n");
                ret++;
                continue;
            }

            printf("PASS\n");
            ok++;
        }
    }

    fclose(f);

    if (ret)
        printf("Test case failed\n");
    else
        printf("%d test vectors OK\n", ok);

    return ret;
}
static int
set80211priv(struct wpa_driver_madwifi_data *drv, int op, void *data, int len,
	     int show_err)
{
	struct iwreq iwr;

	os_memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
	if (len < IFNAMSIZ &&
	    op != IEEE80211_IOCTL_SET_APPIEBUF) {
		/*
		 * Argument data fits inline; put it there.
		 */
		os_memcpy(iwr.u.name, data, len);
	} else {
		/*
		 * Argument data too big for inline transfer; setup a
		 * parameter block instead; the kernel will transfer
		 * the data for the driver.
		 */
		iwr.u.data.pointer = data;
		iwr.u.data.length = len;
	}

	if (ioctl(drv->sock, op, &iwr) < 0) {
		if (show_err) {
#ifdef MADWIFI_NG
			int first = IEEE80211_IOCTL_SETPARAM;
			int last = IEEE80211_IOCTL_KICKMAC;
			static const char *opnames[] = {
				"ioctl[IEEE80211_IOCTL_SETPARAM]",
				"ioctl[IEEE80211_IOCTL_GETPARAM]",
				"ioctl[IEEE80211_IOCTL_SETMODE]",
				"ioctl[IEEE80211_IOCTL_GETMODE]",
				"ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
				"ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
				"ioctl[IEEE80211_IOCTL_SETCHANLIST]",
				"ioctl[IEEE80211_IOCTL_GETCHANLIST]",
				"ioctl[IEEE80211_IOCTL_CHANSWITCH]",
				NULL,
				"ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
				"ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
				NULL,
				"ioctl[IEEE80211_IOCTL_GETCHANINFO]",
				"ioctl[IEEE80211_IOCTL_SETOPTIE]",
				"ioctl[IEEE80211_IOCTL_GETOPTIE]",
				"ioctl[IEEE80211_IOCTL_SETMLME]",
				NULL,
				"ioctl[IEEE80211_IOCTL_SETKEY]",
				NULL,
				"ioctl[IEEE80211_IOCTL_DELKEY]",
				NULL,
				"ioctl[IEEE80211_IOCTL_ADDMAC]",
				NULL,
				"ioctl[IEEE80211_IOCTL_DELMAC]",
				NULL,
				"ioctl[IEEE80211_IOCTL_WDSMAC]",
				NULL,
				"ioctl[IEEE80211_IOCTL_WDSDELMAC]",
				NULL,
				"ioctl[IEEE80211_IOCTL_KICKMAC]",
			};
#else /* MADWIFI_NG */
			int first = IEEE80211_IOCTL_SETPARAM;
			int last = IEEE80211_IOCTL_CHANLIST;
			static const char *opnames[] = {
				"ioctl[IEEE80211_IOCTL_SETPARAM]",
				"ioctl[IEEE80211_IOCTL_GETPARAM]",
				"ioctl[IEEE80211_IOCTL_SETKEY]",
				"ioctl[IEEE80211_IOCTL_GETKEY]",
				"ioctl[IEEE80211_IOCTL_DELKEY]",
				NULL,
				"ioctl[IEEE80211_IOCTL_SETMLME]",
				NULL,
				"ioctl[IEEE80211_IOCTL_SETOPTIE]",
				"ioctl[IEEE80211_IOCTL_GETOPTIE]",
				"ioctl[IEEE80211_IOCTL_ADDMAC]",
				NULL,
				"ioctl[IEEE80211_IOCTL_DELMAC]",
				NULL,
				"ioctl[IEEE80211_IOCTL_CHANLIST]",
			};
#endif /* MADWIFI_NG */
			int idx = op - first;
			if (first <= op && op <= last &&
			    idx < (int) (sizeof(opnames) / sizeof(opnames[0]))
			    && opnames[idx])
				perror(opnames[idx]);
			else
				perror("ioctl[unknown???]");
		}
		return -1;
	}
	return 0;
}
Esempio n. 30
0
/**
 * eap_sim_db_get_aka_auth - Get AKA authentication values
 * @data: Private data pointer from eap_sim_db_init()
 * @username: Permanent username (prefix | IMSI)
 * @_rand: Buffer for RAND value
 * @autn: Buffer for AUTN value
 * @ik: Buffer for IK value
 * @ck: Buffer for CK value
 * @res: Buffer for RES value
 * @res_len: Buffer for RES length
 * @cb_session_ctx: Session callback context for get_complete_cb()
 * Returns: 0 on success, -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not
 * found), or -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this
 * case, the callback function registered with eap_sim_db_init() will be
 * called once the results become available.
 *
 * When using an external server for AKA authentication, this function can
 * always start a request and return EAP_SIM_DB_PENDING immediately if
 * authentication triplets are not available. Once the authentication data are
 * received, callback function registered with eap_sim_db_init() is called to
 * notify EAP state machine to reprocess the message. This
 * eap_sim_db_get_aka_auth() function will then be called again and the newly
 * received triplets will then be given to the caller.
 */
int eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username,
			    u8 *_rand, u8 *autn, u8 *ik, u8 *ck,
			    u8 *res, size_t *res_len, void *cb_session_ctx)
{
	struct eap_sim_db_pending *entry;
	int len;
	char msg[40];
	const char *imsi;
	size_t imsi_len;

	if (username == NULL ||
	    (username[0] != EAP_AKA_PERMANENT_PREFIX &&
	     username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) ||
	    username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'",
			   username);
		return EAP_SIM_DB_FAILURE;
	}
	imsi = username + 1;
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'",
		   imsi);

	entry = eap_sim_db_get_pending(data, imsi, 1);
	if (entry) {
		if (entry->state == FAILURE) {
			eap_sim_db_free_pending(data, entry);
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure");
			return EAP_SIM_DB_FAILURE;
		}

		if (entry->state == PENDING) {
			eap_sim_db_add_pending(data, entry);
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending");
			return EAP_SIM_DB_PENDING;
		}

		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Returning successfully "
			   "received authentication data");
		os_memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN);
		os_memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN);
		os_memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN);
		os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN);
		os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN);
		*res_len = entry->u.aka.res_len;
		eap_sim_db_free_pending(data, entry);
		return 0;
	}

	if (data->sock < 0) {
		if (eap_sim_db_open_socket(data) < 0)
			return EAP_SIM_DB_FAILURE;
	}

	imsi_len = os_strlen(imsi);
	len = os_snprintf(msg, sizeof(msg), "AKA-REQ-AUTH ");
	if (os_snprintf_error(sizeof(msg), len) ||
	    len + imsi_len >= sizeof(msg))
		return EAP_SIM_DB_FAILURE;
	os_memcpy(msg + len, imsi, imsi_len);
	len += imsi_len;

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting AKA authentication "
		    "data for IMSI '%s'", imsi);
	if (eap_sim_db_send(data, msg, len) < 0)
		return EAP_SIM_DB_FAILURE;

	entry = os_zalloc(sizeof(*entry));
	if (entry == NULL)
		return EAP_SIM_DB_FAILURE;

	entry->aka = 1;
	os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi));
	entry->cb_session_ctx = cb_session_ctx;
	entry->state = PENDING;
	eap_sim_db_add_pending(data, entry);
	eap_sim_db_expire_pending(data, entry);
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added query %p", entry);

	return EAP_SIM_DB_PENDING;
}