Ejemplo n.º 1
0
/*
 * this code sends the success message.
 *
 * the only work to be done is the add the appropriate SEND/RECV
 * radius attributes derived from the MSK.
 *
 */
static int eap_sim_sendsuccess(EAP_HANDLER *handler)
{
        unsigned char *p;
	struct eap_sim_server_state *ess;
	VALUE_PAIR **outvps;
	VALUE_PAIR *newvp;

	/* outvps is the data to the client. */
	outvps= &handler->request->reply->vps;
	ess = (struct eap_sim_server_state *)handler->opaque;

	/* set the EAP_ID - new value */
	newvp = paircreate(ATTRIBUTE_EAP_ID, 0, PW_TYPE_INTEGER);
	newvp->vp_integer = ess->sim_id++;
	pairreplace(outvps, newvp);

	p = ess->keys.msk;
	add_reply(outvps, "MS-MPPE-Recv-Key", p, EAPTLS_MPPE_KEY_LEN);
	p += EAPTLS_MPPE_KEY_LEN;
	add_reply(outvps, "MS-MPPE-Send-Key", p, EAPTLS_MPPE_KEY_LEN);
	return 1;
}
Ejemplo n.º 2
0
int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
		     uint64_t *tagptr, struct flist_head *list)
{
	struct fio_net_cmd *cmd = NULL;
	size_t this_len, cur_len = 0;
	uint64_t tag;
	int ret;

	if (list) {
		assert(tagptr);
		tag = *tagptr = alloc_reply(*tagptr, opcode);
	} else
		tag = tagptr ? *tagptr : 0;

	do {
		this_len = size;
		if (this_len > FIO_SERVER_MAX_FRAGMENT_PDU)
			this_len = FIO_SERVER_MAX_FRAGMENT_PDU;

		if (!cmd || cur_len < sizeof(*cmd) + this_len) {
			if (cmd)
				free(cmd);

			cur_len = sizeof(*cmd) + this_len;
			cmd = malloc(cur_len);
		}

		fio_init_net_cmd(cmd, opcode, buf, this_len, tag);

		if (this_len < size)
			cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);

		fio_net_cmd_crc(cmd);

		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
		size -= this_len;
		buf += this_len;
	} while (!ret && size);

	if (list) {
		if (ret)
			free_reply(tag);
		else
			add_reply(tag, list);
	}

	if (cmd)
		free(cmd);

	return ret;
}
Ejemplo n.º 3
0
/*
 *	Generate keys according to RFC 2716 and add to reply
 */
void eaptls_gen_mppe_keys(VALUE_PAIR **reply_vps, SSL *s,
			  const char *prf_label)
{
	unsigned char out[4*EAPTLS_MPPE_KEY_LEN], buf[4*EAPTLS_MPPE_KEY_LEN];
	unsigned char seed[64 + 2*SSL3_RANDOM_SIZE];
	unsigned char *p = seed;
	size_t prf_size;

	if (!s->s3) {
		radlog(L_ERR, "ERROR: OpenSSL build / link incompatibility detected");
		return;
	}

	prf_size = strlen(prf_label);

	memcpy(p, prf_label, prf_size);
	p += prf_size;

	memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
	p += SSL3_RANDOM_SIZE;
	prf_size += SSL3_RANDOM_SIZE;

	memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
	prf_size += SSL3_RANDOM_SIZE;

	PRF(s->session->master_key, s->session->master_key_length,
	    seed, prf_size, out, buf, sizeof(out));

	p = out;
	add_reply(reply_vps, "MS-MPPE-Recv-Key", p, EAPTLS_MPPE_KEY_LEN);
	p += EAPTLS_MPPE_KEY_LEN;
	add_reply(reply_vps, "MS-MPPE-Send-Key", p, EAPTLS_MPPE_KEY_LEN);

	add_reply(reply_vps, "EAP-MSK", out, 64);
	add_reply(reply_vps, "EAP-EMSK", out + 64, 64);
}
Ejemplo n.º 4
0
static int		build_ressources_reply(t_conf *conf, void *buffer, 
					       int  max_len)
{
  struct dns_hdr	*hdr;
  t_list		*list;
  void			*where;
  char			buffer2[MAX_REQ_LEN];

  hdr = buffer;
  hdr->ra = 1;
  hdr->qr = 1;

  if (!(where = jump_end_query(buffer, GET_16(&hdr->qdcount), max_len)))
    return (-1);
  for (list = conf->ressources; list; list = list->next)
    {
      base64_encode(list->data, buffer2, (strchr(list->data, ':') - list->data));
      where = add_reply(hdr, where, TYPE_KEY, buffer2);
    }
  return (where - buffer);
}
Ejemplo n.º 5
0
/*
 * If 'list' is non-NULL, then allocate and store the sent command for
 * later verification.
 */
int fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
			    struct flist_head *list)
{
	int ret;

	if (list)
		tag = alloc_reply(tag, opcode);

	ret = fio_net_send_simple_stack_cmd(sk, opcode, tag);
	if (ret) {
		if (list)
			free_reply(tag);

		return ret;
	}

	if (list)
		add_reply(tag, list);

	return 0;
}
Ejemplo n.º 6
0
int			build_error_reply(t_conf *conf, void *req, int max_len, char *error)
{

  struct dns_hdr	*hdr;
  void			*where;
  t_packet		*packet;
  char			buffer[BASE64_SIZE(MAX_ERROR_SIZE) + PACKET_LEN];
  char			buffer2[BASE64_SIZE(MAX_ERROR_SIZE) + PACKET_LEN];
  int			len;

  hdr = req;
  hdr->ra = 1;
  hdr->qr = 1;
 if (!(where = jump_end_query(req, GET_16(&hdr->qdcount), max_len)))
      return (-1);
  packet = (t_packet *) memset(buffer, 0, PACKET_LEN);
  packet->type = ERR;
  len = strlen(error);
  memcpy(buffer+PACKET_LEN, error, len+1);
  base64_encode(buffer, buffer2, PACKET_LEN + len);
  where = add_reply(hdr, where, TYPE_KEY, buffer2);
  return (where - req);
}
Ejemplo n.º 7
0
static int
eap_pwd_authenticate (void *arg, EAP_HANDLER *handler)
{
    pwd_session_t *pwd_session;
    pwd_hdr *hdr;
    pwd_id_packet *id;
    EAP_PACKET *response;
    REQUEST *request, *fake;
    VALUE_PAIR *pw, **outvps, *vp;
    EAP_DS *eap_ds;
    int len, ret = 0;
    eap_pwd_t *inst = (eap_pwd_t *)arg;
    uint16_t offset;
    uint8_t exch, *buf, *ptr, msk[MSK_EMSK_LEN], emsk[MSK_EMSK_LEN];
    uint8_t peer_confirm[SHA256_DIGEST_LENGTH];
    BIGNUM *x = NULL, *y = NULL;

    if ((handler == NULL) ||
            ((eap_ds = handler->eap_ds) == NULL) ||
            (inst == NULL)) {
        return 0;
    }
    pwd_session = (pwd_session_t *)handler->opaque;
    request = handler->request;
    response = handler->eap_ds->response;
    hdr = (pwd_hdr *)response->type.data;

    buf = hdr->data;
    len = response->type.length - sizeof(pwd_hdr);

    /*
     * see if we're fragmenting, if so continue until we're done
     */
    if (pwd_session->out_buf_pos) {
        if (len) {
            RDEBUG2("pwd got something more than an ACK for a fragment");
        }
        return send_pwd_request(pwd_session, eap_ds);
    }

    /*
     * the first fragment will have a total length, make a
     * buffer to hold all the fragments
     */
    if (EAP_PWD_GET_LENGTH_BIT(hdr)) {
        if (pwd_session->in_buf) {
            RDEBUG2("pwd already alloced buffer for fragments");
            return 0;
        }
        pwd_session->in_buf_len = ntohs(buf[0] * 256 | buf[1]);
        if ((pwd_session->in_buf = malloc(pwd_session->in_buf_len)) == NULL) {
            RDEBUG2("pwd cannot malloc %d buffer to hold fragments",
                    pwd_session->in_buf_len);
            return 0;
        }
        memset(pwd_session->in_buf, 0, pwd_session->in_buf_len);
        pwd_session->in_buf_pos = 0;
        buf += sizeof(uint16_t);
        len -= sizeof(uint16_t);
    }

    /*
     * all fragments, including the 1st will have the M(ore) bit set,
     * buffer those fragments!
     */
    if (EAP_PWD_GET_MORE_BIT(hdr)) {
        rad_assert(pwd_session->in_buf != NULL);
        if ((pwd_session->in_buf_pos + len) > pwd_session->in_buf_len) {
            RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent.");
            return 0;
        }
        memcpy(pwd_session->in_buf + pwd_session->in_buf_pos, buf, len);
        pwd_session->in_buf_pos += len;

        /*
         * send back an ACK for this fragment
         */
        exch = EAP_PWD_GET_EXCHANGE(hdr);
        eap_ds->request->code = PW_EAP_REQUEST;
        eap_ds->request->type.type = PW_EAP_PWD;
        eap_ds->request->type.length = sizeof(pwd_hdr);
        if ((eap_ds->request->type.data = malloc(sizeof(pwd_hdr))) == NULL) {
            radlog(L_ERR, "rlm_eap_pwd: fragment ACK, out of memory");
            return 0;
        }
        hdr = (pwd_hdr *)eap_ds->request->type.data;
        EAP_PWD_SET_EXCHANGE(hdr, exch);
        return 1;

    }

    if (pwd_session->in_buf) {
        /*
         * the last fragment...
         */
        if ((pwd_session->in_buf_pos + len) > pwd_session->in_buf_len) {
            RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent.");
            return 0;
        }
        memcpy(pwd_session->in_buf + pwd_session->in_buf_pos, buf, len);
        buf = pwd_session->in_buf;
        len = pwd_session->in_buf_len;
    }

    switch (pwd_session->state) {
    case PWD_STATE_ID_REQ:
        if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_ID) {
            RDEBUG2("pwd exchange is incorrect: not ID");
            return 0;
        }
        id = (pwd_id_packet *)buf;
        if ((id->prf != EAP_PWD_DEF_PRF) ||
                (id->random_function != EAP_PWD_DEF_RAND_FUN) ||
                (id->prep != EAP_PWD_PREP_NONE) ||
                (memcmp(id->token, (char *)&pwd_session->token, 4)) ||
                (id->group_num != ntohs(pwd_session->group_num))) {
            RDEBUG2("pwd id response is invalid");
            return 0;
        }
        /*
         * we've agreed on the ciphersuite, record it...
         */
        ptr = (uint8_t *)&pwd_session->ciphersuite;
        memcpy(ptr, (char *)&id->group_num, sizeof(uint16_t));
        ptr += sizeof(uint16_t);
        *ptr = EAP_PWD_DEF_RAND_FUN;
        ptr += sizeof(uint8_t);
        *ptr = EAP_PWD_DEF_PRF;

        pwd_session->peer_id_len = len - sizeof(pwd_id_packet);
        if (pwd_session->peer_id_len >= sizeof(pwd_session->peer_id)) {
            RDEBUG2("pwd id response is malformed");
            return 0;
        }
        memcpy(pwd_session->peer_id, id->identity,
               pwd_session->peer_id_len);
        pwd_session->peer_id[pwd_session->peer_id_len] = '\0';

        /*
         * make fake request to get the password for the usable ID
         */
        if ((fake = request_alloc_fake(handler->request)) == NULL) {
            RDEBUG("pwd unable to create fake request!");
            return 0;
        }
        if ((fake->username = pairmake("User-Name", "", T_OP_EQ)) == NULL) {
            RDEBUG("pwd unanable to create value pair for username!");
            request_free(&fake);
            return 0;
        }
        memcpy(fake->username->vp_strvalue, pwd_session->peer_id,
               pwd_session->peer_id_len);
        fake->username->length = pwd_session->peer_id_len;
        fake->username->vp_strvalue[fake->username->length] = 0;

        if ((vp = pairfind(request->config_items, PW_VIRTUAL_SERVER, 0, TAG_ANY)) != NULL) {
            fake->server = vp->vp_strvalue;

        } else if (inst->conf->virtual_server) {
            fake->server = inst->conf->virtual_server;

        } /* else fake->server == request->server */

        if ((debug_flag > 0) && fr_log_fp) {
            RDEBUG("Sending tunneled request");

            debug_pair_list(fake->packet->vps);

            fprintf(fr_log_fp, "server %s {\n",
                    (fake->server == NULL) ? "" : fake->server);
        }

        /*
         *	Call authorization recursively, which will
         *	get the password.
         */
        module_authorize(0, fake);

        /*
         *	Note that we don't do *anything* with the reply
         *	attributes.
         */
        if ((debug_flag > 0) && fr_log_fp) {
            fprintf(fr_log_fp, "} # server %s\n",
                    (fake->server == NULL) ? "" : fake->server);

            RDEBUG("Got tunneled reply code %d", fake->reply->code);

            debug_pair_list(fake->reply->vps);
        }

        if ((pw = pairfind(fake->config_items, PW_CLEARTEXT_PASSWORD, 0, TAG_ANY)) == NULL) {
            DEBUG2("failed to find password for %s to do pwd authentication",
                   pwd_session->peer_id);
            request_free(&fake);
            return 0;
        }

        if (compute_password_element(pwd_session, pwd_session->group_num,
                                     pw->data.strvalue, strlen(pw->data.strvalue),
                                     inst->conf->server_id, strlen(inst->conf->server_id),
                                     pwd_session->peer_id, strlen(pwd_session->peer_id),
                                     &pwd_session->token)) {
            DEBUG2("failed to obtain password element :-(");
            request_free(&fake);
            return 0;
        }
        request_free(&fake);

        /*
         * compute our scalar and element
         */
        if (compute_scalar_element(pwd_session, inst->bnctx)) {
            DEBUG2("failed to compute server's scalar and element");
            return 0;
        }
        if (((x = BN_new()) == NULL) ||
                ((y = BN_new()) == NULL)) {
            DEBUG2("server point allocation failed");
            return 0;
        }
        /*
         * element is a point, get both coordinates: x and y
         */
        if (!EC_POINT_get_affine_coordinates_GFp(pwd_session->group,
                pwd_session->my_element, x, y,
                inst->bnctx)) {
            DEBUG2("server point assignment failed");
            BN_free(x);
            BN_free(y);
            return 0;
        }
        /*
         * construct request
         */
        pwd_session->out_buf_len = BN_num_bytes(pwd_session->order) +
                                   (2 * BN_num_bytes(pwd_session->prime));
        if ((pwd_session->out_buf = malloc(pwd_session->out_buf_len)) == NULL) {
            radlog(L_ERR, "rlm_eap_pwd: out of memory to send commit");
            return 0;
        }
        memset(pwd_session->out_buf, 0, pwd_session->out_buf_len);

        ptr = pwd_session->out_buf;
        offset = BN_num_bytes(pwd_session->prime) - BN_num_bytes(x);
        BN_bn2bin(x, ptr + offset);

        ptr += BN_num_bytes(pwd_session->prime);
        offset = BN_num_bytes(pwd_session->prime) - BN_num_bytes(y);
        BN_bn2bin(y, ptr + offset);

        ptr += BN_num_bytes(pwd_session->prime);
        offset = BN_num_bytes(pwd_session->order) - BN_num_bytes(pwd_session->my_scalar);
        BN_bn2bin(pwd_session->my_scalar, ptr + offset);

        pwd_session->state = PWD_STATE_COMMIT;
        ret = send_pwd_request(pwd_session, eap_ds);
        break;
    case PWD_STATE_COMMIT:
        if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_COMMIT) {
            RDEBUG2("pwd exchange is incorrect: not commit!");
            return 0;
        }
        /*
         * process the peer's commit and generate the shared key, k
         */
        if (process_peer_commit(pwd_session, buf, inst->bnctx)) {
            RDEBUG2("failed to process peer's commit");
            return 0;
        }

        /*
         * compute our confirm blob
         */
        if (compute_server_confirm(pwd_session, pwd_session->my_confirm, inst->bnctx)) {
            radlog(L_ERR, "rlm_eap_pwd: failed to compute confirm!");
            return 0;
        }
        /*
         * construct a response...which is just our confirm blob
         */
        pwd_session->out_buf_len = SHA256_DIGEST_LENGTH;
        if ((pwd_session->out_buf = malloc(pwd_session->out_buf_len)) == NULL) {
            radlog(L_ERR, "rlm_eap_pwd: out of memory to send confirm");
            return 0;
        }
        memset(pwd_session->out_buf, 0, pwd_session->out_buf_len);
        memcpy(pwd_session->out_buf, pwd_session->my_confirm, SHA256_DIGEST_LENGTH);

        pwd_session->state = PWD_STATE_CONFIRM;
        ret = send_pwd_request(pwd_session, eap_ds);
        break;
    case PWD_STATE_CONFIRM:
        if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_CONFIRM) {
            RDEBUG2("pwd exchange is incorrect: not commit!");
            return 0;
        }
        if (compute_peer_confirm(pwd_session, peer_confirm, inst->bnctx)) {
            RDEBUG2("pwd exchange cannot compute peer's confirm");
            return 0;
        }
        if (memcmp(peer_confirm, buf, SHA256_DIGEST_LENGTH)) {
            RDEBUG2("pwd exchange fails: peer confirm is incorrect!");
            return 0;
        }
        if (compute_keys(pwd_session, peer_confirm, msk, emsk)) {
            RDEBUG2("pwd exchange cannot generate (E)MSK!");
            return 0;
        }
        eap_ds->request->code = PW_EAP_SUCCESS;
        /*
         * return the MSK (in halves)
         */
        outvps = &handler->request->reply->vps;
        add_reply(outvps, "MS-MPPE-Recv-Key", msk, MPPE_KEY_LEN);
        add_reply(outvps, "MS-MPPE-Send-Key", msk+MPPE_KEY_LEN, MPPE_KEY_LEN);
        ret = 1;
        break;
    default:
        RDEBUG2("unknown PWD state");
        return 0;
    }

    /*
     * we processed the buffered fragments, get rid of them
     */
    if (pwd_session->in_buf) {
        free(pwd_session->in_buf);
        pwd_session->in_buf = NULL;
    }

    return ret;
}
Ejemplo n.º 8
0
static void add_reply_bulklen(sub_client *c, sds cnt)
{
    size_t len = sdslen(cnt);
    sds lensds = sdscatprintf(sdsempty(), "$%lu\r\n", len);
    add_reply(c, lensds);
}
Ejemplo n.º 9
0
void add_reply_bulk(sub_client *c, sds cnt)
{
    add_reply_bulklen(c, cnt);
    add_reply(c, cnt);
    add_reply(c, shared.crlf);
}
Ejemplo n.º 10
0
static void ping_command(sub_client *c)
{
    add_reply(c, shared.pong);
}