コード例 #1
0
ファイル: ampe.c プロジェクト: cozybit/authsae
static uint32_t do_estab_peer_link(struct candidate *cand) {
  uint32_t changed;
  derive_mtk(cand);
  cb->estab_peer_link(
      cand->peer_mac,
      cand->mtk,
      sizeof(cand->mtk),
      cand->mgtk,
      sizeof(cand->mgtk),
      cand->mgtk_expiration,
      (cand->has_igtk) ? cand->igtk : NULL,
      (cand->has_igtk) ? sizeof(cand->igtk) : 0,
      cand->igtk_keyid,
      cand->sup_rates,
      cand->sup_rates_len,
      cand->cookie);
  set_link_state(cand, PLINK_ESTAB);
  changed = mesh_set_ht_op_mode(cand->conf->mesh);

  sae_debug(
      AMPE_DEBUG_FSM,
      "Mesh plink with " MACSTR " ESTABLISHED\n",
      MAC2STR(cand->peer_mac));
  rekey_verify_peer(cand);
  return changed;
}
コード例 #2
0
ファイル: ampe.c プロジェクト: cozybit/authsae
static void peer_ampe_init(
    struct ampe_config *aconf,
    struct candidate *cand,
    void *cookie) {
  le16 llid;

  assert(cand);

  RAND_bytes((unsigned char *)&llid, sizeof(llid));
  RAND_bytes(cand->my_nonce, sizeof(cand->my_nonce));
  memset(cand->peer_nonce, 0, sizeof(cand->peer_nonce));
  cand->cookie = cookie;
  cand->my_lid = llid;
  cand->peer_lid = 0;
  set_link_state(cand, PLINK_LISTEN);
  cand->timeout = aconf->retry_timeout_ms;
  cand->conf = aconf;

  memset(cand->mtk, 0, sizeof(cand->mtk));
  memset(cand->mgtk, 0, sizeof(cand->mgtk));
  memset(cand->igtk, 0, sizeof(cand->igtk));
  cand->has_igtk = false;

  if (aconf->mesh->conf->is_secure) {
    derive_aek(cand);
    siv_init(&cand->sivctx, cand->aek, SIV_256);
  }
}
コード例 #3
0
ファイル: ampe.c プロジェクト: cozybit/authsae
/**
 * ampe_open_peer_link - attempt to establish a peer link
 * @peer:      MAC address of the candidate peer
 * @cookie:    Opaque cookie that will be returned to the caller along with
 *             frames to be transmitted.
 *
 * Returns 0 or a negative error.
 */
int ampe_open_peer_link(unsigned char *peer_mac, void *cookie) {
  struct candidate *cand;

  assert(peer_mac);

  if ((cand = find_peer(peer_mac, 0)) == NULL) {
    sae_debug(
        AMPE_DEBUG_FSM,
        "Mesh plink: Attempt to peer with "
        " non-authed peer\n");
    return -EPERM;
  }

  peer_ampe_init(&ampe_conf, cand, cookie);
  set_link_state(cand, PLINK_OPN_SNT);
  cb->evl->rem_timeout(cand->t2);
  cand->t2 = cb->evl->add_timeout(SRV_MSEC(cand->timeout), plink_timer, cand);

  sae_debug(
      AMPE_DEBUG_FSM,
      "Mesh plink: starting establishment "
      "with " MACSTR "\n",
      MAC2STR(peer_mac));

  return plink_frame_tx(cand, PLINK_OPEN, 0);
}
コード例 #4
0
ファイル: ampe.c プロジェクト: cococorp/authsae
static void peer_ampe_init(struct ampe_config *aconf,
                           struct candidate *cand, unsigned char *me, void *cookie)
{
	le16 llid;

    assert(cand && me);

    RAND_bytes((unsigned char *) &llid, 2);
    RAND_bytes(cand->my_nonce, sizeof(cand->my_nonce));
    cand->cookie = cookie;
	cand->my_lid = llid;
	cand->peer_lid = 0;
	set_link_state(cand, PLINK_LISTEN);
    cand->timeout = aconf->retry_timeout_ms;
    cand->conf = aconf;
    derive_aek(cand);
    siv_init(&cand->sivctx, cand->aek, SIV_256);
	return;
}
コード例 #5
0
ファイル: ampe.c プロジェクト: cococorp/authsae
static void fsm_step(struct candidate *cand, enum plink_event event)
{
    struct ampe_config *aconf = cand->conf;
    unsigned short reason = 0;
    uint32_t changed = 0;

	switch (cand->link_state) {
	case PLINK_LISTEN:
		switch (event) {
		case CLS_ACPT:
			fsm_restart(cand);
			break;
		case OPN_ACPT:
            cand->timeout = aconf->retry_timeout_ms;
            cand->t2 = srv_add_timeout(srvctx, SRV_MSEC(cand->timeout), plink_timer, cand);
			plink_frame_tx(cand, PLINK_OPEN, 0);
			plink_frame_tx(cand, PLINK_CONFIRM, 0);
			break;
		default:
			break;
		}
		break;

	case PLINK_OPN_SNT:
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
			reason = htole16(MESH_CAPABILITY_POLICY_VIOLATION);
		case CLS_ACPT:
			if (!reason)
				reason = htole16(MESH_CLOSE_RCVD);
			cand->reason = reason;
			set_link_state(cand, PLINK_HOLDING);
            cand->timeout = aconf->holding_timeout_ms;
            cand->t2 = srv_add_timeout(srvctx, SRV_MSEC(cand->timeout), plink_timer, cand);
			plink_frame_tx(cand, PLINK_CLOSE, reason);
			break;
		case OPN_ACPT:
			/* retry timer is left untouched */
			set_link_state(cand, PLINK_OPN_RCVD);
			plink_frame_tx(cand, PLINK_CONFIRM, 0);
			break;
		case CNF_ACPT:
			set_link_state(cand, PLINK_CNF_RCVD);
            cand->timeout = aconf->confirm_timeout_ms;
            cand->t2 = srv_add_timeout(srvctx, SRV_MSEC(cand->timeout), plink_timer, cand);
			break;
		default:
			break;
		}
		break;

	case PLINK_OPN_RCVD:
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
			reason = htole16(MESH_CAPABILITY_POLICY_VIOLATION);
		case CLS_ACPT:
			if (!reason)
				reason = htole16(MESH_CLOSE_RCVD);
			cand->reason = reason;
			set_link_state(cand, PLINK_HOLDING);
            cand->timeout = aconf->holding_timeout_ms;
            cand->t2 = srv_add_timeout(srvctx, SRV_MSEC(cand->timeout), plink_timer, cand);
			plink_frame_tx(cand, PLINK_CLOSE, reason);
			break;
		case OPN_ACPT:
			plink_frame_tx(cand, PLINK_CONFIRM, 0);
			break;
		case CNF_ACPT:
			//del_timer(&cand->plink_timer);
			set_link_state(cand, PLINK_ESTAB);
			//mesh_plink_inc_estab_count(sdata);
			//ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
            derive_mtk(cand);
            estab_peer_link(cand->peer_mac,
                    cand->mtk, sizeof(cand->mtk),
                    cand->mgtk, sizeof(cand->mgtk),
                    cand->mgtk_expiration,
                    cand->sup_rates,
                    cand->sup_rates_len,
                    cand->cookie);
            changed |= mesh_set_ht_op_mode(cand->conf->mesh);
            sae_debug(AMPE_DEBUG_FSM, "mesh plink with "
                    MACSTR " established\n", MAC2STR(cand->peer_mac));
			break;
		default:
			break;
		}
		break;

	case PLINK_CNF_RCVD:
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
			reason = htole16(MESH_CAPABILITY_POLICY_VIOLATION);
		case CLS_ACPT:
			if (!reason)
				reason = htole16(MESH_CLOSE_RCVD);
			cand->reason = reason;
			set_link_state(cand, PLINK_HOLDING);
            cand->timeout = aconf->holding_timeout_ms;
            cand->t2 = srv_add_timeout(srvctx, SRV_MSEC(cand->timeout), plink_timer, cand);
			plink_frame_tx(cand, PLINK_CLOSE, reason);
			break;
		case OPN_ACPT:
			set_link_state(cand, PLINK_ESTAB);
            estab_peer_link(cand->peer_mac,
                    cand->mtk, sizeof(cand->mtk),
                    cand->mgtk, sizeof(cand->mgtk),
                    cand->mgtk_expiration, cand->sup_rates,
                    cand->sup_rates_len,
                    cand->cookie);
            changed |= mesh_set_ht_op_mode(cand->conf->mesh);
            //TODO: update the number of available peer "slots" in mesh config
			//mesh_plink_inc_estab_count(sdata);
			//ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
			sae_debug(AMPE_DEBUG_FSM, "Mesh plink with "
                    MACSTR " ESTABLISHED\n", MAC2STR(cand->peer_mac));
			plink_frame_tx(cand, PLINK_CONFIRM, 0);
			break;
		default:
			break;
		}
		break;

	case PLINK_ESTAB:
		switch (event) {
		case CLS_ACPT:
			reason = htole16(MESH_CLOSE_RCVD);
			cand->reason = reason;
			set_link_state(cand, PLINK_HOLDING);
            cand->timeout = aconf->holding_timeout_ms;
            cand->t2 = srv_add_timeout(srvctx, SRV_MSEC(cand->timeout), plink_timer, cand);
            changed |= mesh_set_ht_op_mode(cand->conf->mesh);
            //TODO: update the number of available peer "slots" in mesh config
			//if (deactivated)
		    //	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
			plink_frame_tx(cand, PLINK_CLOSE, reason);
			break;
		case OPN_ACPT:
			plink_frame_tx(cand, PLINK_CONFIRM, 0);
			break;
		default:
			break;
		}
		break;
	case PLINK_HOLDING:
		switch (event) {
		case CLS_ACPT:
			//if (del_timer(&cand->plink_timer))
			//	cand->ignore_plink_timer = 1;
			fsm_restart(cand);
			break;
		case OPN_ACPT:
		case CNF_ACPT:
		case OPN_RJCT:
		case CNF_RJCT:
			reason = cand->reason;
			plink_frame_tx(cand, PLINK_CLOSE, reason);
			break;
		default:
            break;
		}
		break;
	default:
        sae_debug(AMPE_DEBUG_FSM, "Unsupported event transition %d", event);
		break;
	}

    if (changed)
        meshd_set_mesh_conf(cand->conf->mesh, changed);
}
コード例 #6
0
ファイル: ampe.c プロジェクト: cococorp/authsae
static void plink_timer(timerid id, void *data)
{
	__le16 reason;
    struct candidate *cand;

	cand = (struct candidate *)data;

    assert(cand);

    sae_debug(AMPE_DEBUG_FSM, "Mesh plink timer for " MACSTR
            " fired on state %s\n", MAC2STR(cand->peer_mac),
		    mplstates[(cand->link_state > PLINK_BLOCKED) ? PLINK_UNDEFINED : cand->link_state]);

	reason = 0;

	switch (cand->link_state) {
	case PLINK_OPN_RCVD:
	case PLINK_OPN_SNT:
		/* retry timer */
        sae_debug(AMPE_DEBUG_FSM, "Mesh plink:retries %d of %d\n", cand->retries,
                  cand->conf->max_retries);
		if (cand->retries < cand->conf->max_retries) {
			unsigned int rand;
            sae_debug(AMPE_DEBUG_FSM, "Mesh plink for " MACSTR
                    " (retry, timeout): %d %d\n", MAC2STR(cand->peer_mac),
                    cand->retries, cand->timeout);
			RAND_bytes((unsigned char *) &rand, sizeof(rand));
            if (!cand->timeout) {
                cand->timeout = cand->conf->retry_timeout_ms;
                sae_debug(AMPE_DEBUG_ERR, "WARN: cand " MACSTR
                    " had a timeout of 0ms.  Reset to %d\n",
                    MAC2STR(cand->peer_mac),cand->timeout);
            }
            cand->timeout += rand % cand->timeout;
			++cand->retries;
            cand->t2 = srv_add_timeout(srvctx,
                    SRV_MSEC(cand->timeout), plink_timer,
                    cand);
			plink_frame_tx(cand, PLINK_OPEN, 0);
			break;
		}
		reason = htole16(MESH_MAX_RETRIES);
		/* fall through on else */
	case PLINK_CNF_RCVD:
		/* confirm timer */
		if (!reason)
			reason = htole16(MESH_CONFIRM_TIMEOUT);
		set_link_state(cand, PLINK_HOLDING);
        cand->t2 = srv_add_timeout(srvctx,
                    SRV_MSEC(cand->conf->holding_timeout_ms), plink_timer,
                    cand);
		plink_frame_tx(cand, PLINK_CLOSE, reason);
		break;
	case PLINK_HOLDING:
		/* holding timer */
		fsm_restart(cand);
		break;
	case PLINK_ESTAB:
		/* nothing to do */
		break;
	default:
        sae_debug(AMPE_DEBUG_FSM, "Timeout for peer " MACSTR
                " in state %d\n", MAC2STR(cand->peer_mac),
                cand->link_state);
		break;
	}
}
コード例 #7
0
ファイル: ampe.c プロジェクト: cococorp/authsae
/**
 * fsm_restart - restart a mesh peer link finite state machine
 *
 * @cand: mesh peer link to restart
 *
 * */
static inline void fsm_restart(struct candidate *cand)
{
    set_link_state(cand, PLINK_LISTEN);
    cand->my_lid = cand->peer_lid = cand->reason = 0;
    cand->retries = 0;
}
コード例 #8
0
ファイル: ampe.c プロジェクト: cozybit/authsae
static void fsm_step(struct candidate *cand, enum plink_event event) {
  struct ampe_config *aconf = cand->conf;
  unsigned short reason = 0;
  uint32_t changed = 0;

  switch (cand->link_state) {
    case PLINK_LISTEN:
      switch (event) {
        case CLS_ACPT:
          fsm_restart(cand);
          break;
        case OPN_ACPT:
          cand->timeout = aconf->retry_timeout_ms;
          cb->evl->rem_timeout(cand->t2);
          cand->t2 =
              cb->evl->add_timeout(SRV_MSEC(cand->timeout), plink_timer, cand);
          set_link_state(cand, PLINK_OPN_RCVD);
          plink_frame_tx(cand, PLINK_OPEN, 0);
          plink_frame_tx(cand, PLINK_CONFIRM, 0);
          break;
        default:
          break;
      }
      break;

    case PLINK_OPN_SNT:
      switch (event) {
        case OPN_RJCT:
        case CNF_RJCT:
        case REQ_RJCT:
          reason = MESH_CAPABILITY_POLICY_VIOLATION;
        /* no break */
        case CLS_ACPT:
          if (!reason)
            reason = MESH_CLOSE_RCVD;
          set_link_state(cand, PLINK_HOLDING);
          cand->timeout = aconf->holding_timeout_ms;
          cb->evl->rem_timeout(cand->t2);
          cand->t2 =
              cb->evl->add_timeout(SRV_MSEC(cand->timeout), plink_timer, cand);
          plink_frame_tx(cand, PLINK_CLOSE, reason);
          break;
        case OPN_ACPT:
          /* retry timer is left untouched */
          set_link_state(cand, PLINK_OPN_RCVD);
          plink_frame_tx(cand, PLINK_CONFIRM, 0);
          break;
        case CNF_ACPT:
          set_link_state(cand, PLINK_CNF_RCVD);
          cand->timeout = aconf->confirm_timeout_ms;
          cb->evl->rem_timeout(cand->t2);
          cand->t2 =
              cb->evl->add_timeout(SRV_MSEC(cand->timeout), plink_timer, cand);
          break;
        default:
          break;
      }
      break;

    case PLINK_OPN_RCVD:
      switch (event) {
        case OPN_RJCT:
        case CNF_RJCT:
        case REQ_RJCT:
          reason = MESH_CAPABILITY_POLICY_VIOLATION;
        /* no break */
        case CLS_ACPT:
          if (!reason)
            reason = MESH_CLOSE_RCVD;
          set_link_state(cand, PLINK_HOLDING);
          cand->timeout = aconf->holding_timeout_ms;
          cb->evl->rem_timeout(cand->t2);
          cand->t2 =
              cb->evl->add_timeout(SRV_MSEC(cand->timeout), plink_timer, cand);
          plink_frame_tx(cand, PLINK_CLOSE, reason);
          break;
        case OPN_ACPT:
          plink_frame_tx(cand, PLINK_CONFIRM, 0);
          break;
        case CNF_ACPT:
          changed |= do_estab_peer_link(cand);
          break;
        default:
          break;
      }
      break;

    case PLINK_CNF_RCVD:
      switch (event) {
        case OPN_RJCT:
        case CNF_RJCT:
        case REQ_RJCT:
          reason = MESH_CAPABILITY_POLICY_VIOLATION;
        /* no break */
        case CLS_ACPT:
          if (!reason)
            reason = MESH_CLOSE_RCVD;
          set_link_state(cand, PLINK_HOLDING);
          cand->timeout = aconf->holding_timeout_ms;
          cb->evl->rem_timeout(cand->t2);
          cand->t2 =
              cb->evl->add_timeout(SRV_MSEC(cand->timeout), plink_timer, cand);
          plink_frame_tx(cand, PLINK_CLOSE, reason);
          break;
        case OPN_ACPT:
          changed |= do_estab_peer_link(cand);
          plink_frame_tx(cand, PLINK_CONFIRM, 0);
          break;
        default:
          break;
      }
      break;

    case PLINK_ESTAB:
      switch (event) {
        case OPN_RJCT:
        case CNF_RJCT:
        case REQ_RJCT:
          reason = MESH_CAPABILITY_POLICY_VIOLATION;
        case CLS_ACPT:
          if (!reason)
            reason = MESH_CLOSE_RCVD;
          set_link_state(cand, PLINK_HOLDING);
          cand->timeout = aconf->holding_timeout_ms;
          cb->evl->rem_timeout(cand->t2);
          cand->t2 =
              cb->evl->add_timeout(SRV_MSEC(cand->timeout), plink_timer, cand);
          changed |= mesh_set_ht_op_mode(cand->conf->mesh);
          plink_frame_tx(cand, PLINK_CLOSE, reason);
          break;
        case OPN_ACPT:
          plink_frame_tx(cand, PLINK_CONFIRM, 0);
          break;
        default:
          break;
      }
      break;
    case PLINK_HOLDING:
      switch (event) {
        case CLS_ACPT:
          fsm_restart(cand);
          break;
        case OPN_ACPT:
        case CNF_ACPT:
        case OPN_RJCT:
        case CNF_RJCT:
        case REQ_RJCT:
          plink_frame_tx(cand, PLINK_CLOSE, reason);
          break;
        default:
          break;
      }
      break;
    default:
      sae_debug(AMPE_DEBUG_FSM, "Unsupported event transition %d", event);
      break;
  }

  if (changed)
    cb->meshd_set_mesh_conf(cand->conf->mesh, changed);
}
コード例 #9
0
ファイル: ampe.c プロジェクト: cozybit/authsae
static void plink_timer(void *data) {
  le16 reason;
  struct candidate *cand;

  cand = (struct candidate *)data;

  assert(cand);

  sae_debug(
      AMPE_DEBUG_FSM,
      "Mesh plink timer for " MACSTR " fired on state %s\n",
      MAC2STR(cand->peer_mac),
      mpl_states[(cand->link_state > PLINK_BLOCKED) ? PLINK_UNDEFINED
                                                    : cand->link_state]);

  reason = 0;

  switch (cand->link_state) {
    case PLINK_OPN_RCVD:
    case PLINK_OPN_SNT:
      /* retry timer */
      sae_debug(
          AMPE_DEBUG_FSM,
          "Mesh plink:retries %d of %d\n",
          cand->retries,
          cand->conf->max_retries);
      if (cand->retries < cand->conf->max_retries) {
        cand->timeout = cand->conf->retry_timeout_ms;
        sae_debug(
            AMPE_DEBUG_FSM,
            "Mesh plink for " MACSTR " (retry, timeout): %d %d\n",
            MAC2STR(cand->peer_mac),
            cand->retries,
            cand->timeout);
        ++cand->retries;
        cb->evl->rem_timeout(cand->t2);
        cand->t2 =
            cb->evl->add_timeout(SRV_MSEC(cand->timeout), plink_timer, cand);
        plink_frame_tx(cand, PLINK_OPEN, 0);
        break;
      }
      reason = MESH_MAX_RETRIES;
    /* no break / fall through on else */
    case PLINK_CNF_RCVD:
      /* confirm timer */
      if (!reason)
        reason = MESH_CONFIRM_TIMEOUT;
      set_link_state(cand, PLINK_HOLDING);
      cb->evl->rem_timeout(cand->t2);
      cand->t2 = cb->evl->add_timeout(
          SRV_MSEC(cand->conf->holding_timeout_ms), plink_timer, cand);
      plink_frame_tx(cand, PLINK_CLOSE, reason);
      break;
    case PLINK_HOLDING:
      /* holding timer */
      fsm_restart(cand);
      break;
    case PLINK_ESTAB:
      /* nothing to do */
      break;
    default:
      sae_debug(
          AMPE_DEBUG_FSM,
          "Timeout for peer " MACSTR " in state %d\n",
          MAC2STR(cand->peer_mac),
          cand->link_state);
      break;
  }
}