int Ctgdb::Process_console_command(tgdb_request_ptr request)
{
	struct ibuf *command;

	if (!request)
		return -1;

	if (!Can_issue_command())
		return -1;

	if (request->header != TGDB_REQUEST_CONSOLE_COMMAND)
		return -1;

	command = ibuf_init ();
	ibuf_add (command, request->choice.console_command.command);
	ibuf_addchar (command, '\n');

	if (Send(ibuf_get (command), TGDB_COMMAND_CONSOLE) == -1)
	{
		Logger_write_pos( __FILE__, __LINE__, "tgdb_send failed");
		return -1;
	}

	ibuf_free (command);
	command = NULL;

	return 0;
}
Example #2
0
struct ibuf *ibuf_dup(struct ibuf *s)
{
    struct ibuf *ns = ibuf_init();

    ibuf_add(ns, ibuf_get(s));
    return ns;
}
static int test_add(ibuf s) {

    /* Add the strings "hello" and " world" to the ibuf */
    ibuf_add(s, "hello");
    ibuf_add(s, " world");

    /* Make sure that's what got added */
    if (strcmp(ibuf_get(s), "hello world") != 0) {
        debug("test_add: Mismatch, expected \"hello world\", got: %s\n", 
                ibuf_get(s));
        return 1;
    }

    debug("test_add: Succeeded.\n");
    return 0;
}
Example #4
0
struct iked_message *
ikev2_msg_copy(struct iked *env, struct iked_message *msg)
{
	struct iked_message		*m = NULL;
	struct ibuf			*buf;
	size_t				 len;
	void				*ptr;

	if (ibuf_size(msg->msg_data) < msg->msg_offset)
		return (NULL);
	len = ibuf_size(msg->msg_data) - msg->msg_offset;

	if ((ptr = ibuf_seek(msg->msg_data, msg->msg_offset, len)) == NULL ||
	    (m = malloc(sizeof(*m))) == NULL ||
	    (buf = ikev2_msg_init(env, m, &msg->msg_peer, msg->msg_peerlen,
	     &msg->msg_local, msg->msg_locallen, msg->msg_response)) == NULL ||
	    ibuf_add(buf, ptr, len))
		return (NULL);

	m->msg_fd = msg->msg_fd;
	m->msg_msgid = msg->msg_msgid;
	m->msg_offset = msg->msg_offset;
	m->msg_sa = msg->msg_sa;

	return (m);
}
Example #5
0
int
imsg_add(struct ibuf *msg, const void *data, u_int16_t datalen)
{
	if (datalen)
		if (ibuf_add(msg, data, datalen) == -1) {
			ibuf_free(msg);
			return (-1);
		}
	return (datalen);
}
Example #6
0
int
eap_challenge_request(struct iked *env, struct iked_sa *sa,
    struct eap_header *hdr)
{
	struct eap_message		*eap;
	struct eap_mschap_challenge	*ms;
	const char			*name;
	int				 ret = -1;
	struct ibuf			*e;

	if ((e = ibuf_static()) == NULL)
		return (-1);

	if ((eap = ibuf_advance(e, sizeof(*eap))) == NULL)
		goto done;
	eap->eap_code = EAP_CODE_REQUEST;
	eap->eap_id = hdr->eap_id + 1;
	eap->eap_type = sa->sa_policy->pol_auth.auth_eap;

	switch (sa->sa_policy->pol_auth.auth_eap) {
	case EAP_TYPE_MSCHAP_V2:
		name = IKED_USER;	/* XXX should be user-configurable */
		eap->eap_length = htobe16(sizeof(*eap) +
		    sizeof(*ms) + strlen(name));

		if ((ms = ibuf_advance(e, sizeof(*ms))) == NULL)
			return (-1);
		ms->msc_opcode = EAP_MSOPCODE_CHALLENGE;
		ms->msc_id = eap->eap_id;
		ms->msc_length = htobe16(sizeof(*ms) + strlen(name));
		ms->msc_valuesize = sizeof(ms->msc_challenge);
		arc4random_buf(ms->msc_challenge, sizeof(ms->msc_challenge));
		if (ibuf_add(e, name, strlen(name)) == -1)
			goto done;

		/* Store the EAP challenge value */
		sa->sa_eap.id_type = eap->eap_type;
		if ((sa->sa_eap.id_buf = ibuf_new(ms->msc_challenge,
		    sizeof(ms->msc_challenge))) == NULL)
			goto done;
		break;
	default:
		log_debug("%s: unsupported EAP type %s", __func__,
		    print_map(eap->eap_type, eap_type_map));
		goto done;
	}

	ret = ikev2_send_ike_e(env, sa, e,
	    IKEV2_PAYLOAD_EAP, IKEV2_EXCHANGE_IKE_AUTH, 1);

 done:
	ibuf_release(e);

	return (ret);
}
static int test_trim(ibuf s) {

    /* Test #1: Empty string. */
    ibuf_clear(s);
    ibuf_trim(s);
    if (strcmp(ibuf_get(s), "") != 0) {
        debug("test_trim: 1: expected empty string, got: %s\n", ibuf_get(s));
        return 1;
    }

    /* Test #2: Single space. */
    ibuf_clear(s);
    ibuf_addchar(s, ' ');
    ibuf_trim(s);
    if (strcmp(ibuf_get(s), "") != 0) {
        debug("test_trim: 2: expected empty string, got: %s\n", ibuf_get(s));
        return 2;
    }

    /* Test #3: "hello world" (no leading or trailing spaces) */
    ibuf_clear(s);
    ibuf_add(s, "hello world");
    ibuf_trim(s);
    if (strcmp(ibuf_get(s), "hello world") != 0) {
        debug("test_trim: 3: expected \"hello world\", got: %s\n",
                ibuf_get(s));
        return 3;
    }

    /* Test #4: "  hello world  \t" (leading and trailing spaces) */
    ibuf_clear(s);
    ibuf_add(s, "  hello world  \t");
    ibuf_trim(s);
    if (strcmp(ibuf_get(s), "hello world") != 0) {
        debug("test_trim: 4: expected \"hello world\", got: %s\n",
                ibuf_get(s));
        return 3;
    }

    debug("test_trim: Succeeded.\n");
    return 0;
}
Example #8
0
void
tcp_read_buf(int s, short event, void *arg)
{
	ssize_t			 br;
	char			 rbuf[SMALL_READ_BUF_SIZE];
	struct ctl_tcp_event	*cte = arg;

	if (event == EV_TIMEOUT) {
		cte->host->up = HOST_DOWN;
		ibuf_free(cte->buf);
		close(s);
		hce_notify_done(cte->host, HCE_TCP_READ_TIMEOUT);
		return;
	}

	bzero(rbuf, sizeof(rbuf));
	br = read(s, rbuf, sizeof(rbuf) - 1);
	switch (br) {
	case -1:
		if (errno == EAGAIN || errno == EINTR)
			goto retry;
		cte->host->up = HOST_DOWN;
		ibuf_free(cte->buf);
		close(cte->s);
		hce_notify_done(cte->host, HCE_TCP_READ_FAIL);
		return;
	case 0:
		cte->host->up = HOST_DOWN;
		(void)cte->validate_close(cte);
		close(cte->s);
		ibuf_free(cte->buf);
		hce_notify_done(cte->host, cte->host->he);
		return;
	default:
		if (ibuf_add(cte->buf, rbuf, br) == -1)
			fatal("tcp_read_buf: buf_add error");
		if (cte->validate_read != NULL) {
			if (cte->validate_read(cte) != 0)
				goto retry;

			close(cte->s);
			ibuf_free(cte->buf);
			hce_notify_done(cte->host, cte->host->he);
			return;
		}
		break; /* retry */
	}
retry:
	event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
	    &cte->tv_start, &cte->table->conf.timeout, cte);
}
Example #9
0
void
gen_address_list_tlv(struct ibuf *buf, struct iface *iface, u_int16_t size)
{
	struct address_list_tlv	 alt;
	struct iface		*niface;

	/* We want just the size of the value */
	size -= TLV_HDR_LEN;

	bzero(&alt, sizeof(alt));
	alt.type = TLV_TYPE_ADDRLIST;
	alt.length = htons(size);
	/* XXX: just ipv4 for now */
	alt.family = htons(ADDR_IPV4);

	ibuf_add(buf, &alt, sizeof(alt));

	if (iface == NULL)
		LIST_FOREACH(niface, &leconf->iface_list, entry)
			ibuf_add(buf, &niface->addr, sizeof(niface->addr));
	else
		ibuf_add(buf, &iface->addr, sizeof(iface->addr));
}
Example #10
0
int highlight_node(const char *filename, struct buffer *buf)
{
    int ret;
    int length = 0;
    int lasttype = -1;
    struct ibuf *ibuf = ibuf_init();
    struct tokenizer *t = tokenizer_init();

    if (tokenizer_set_file(t, filename, buf->language) == -1) {
        if_print_message("%s:%d tokenizer_set_file error", __FILE__, __LINE__);
        return -1;
    }

    while ((ret = tokenizer_get_token(t)) > 0) {
        enum tokenizer_type e = tokenizer_get_packet_type(t);

        /*if_print_message  ( "TOKEN(%d:%s)\n", e, tokenizer_get_printable_enum ( e ) ); */

        if (e == TOKENIZER_NEWLINE) {
            sbpush(buf->tlines, strdup(ibuf_get(ibuf)));

            if (length > buf->max_width)
                buf->max_width = length;

            length = 0;
            lasttype = -1;
            ibuf_clear(ibuf);
        } else {
            const char *tok_data = tokenizer_get_data(t);
            enum hl_group_kind hlg = hlg_from_tokenizer_type(e, tok_data);

            if (hlg == HLG_LAST) {
                logger_write_pos(logger, __FILE__, __LINE__, "Bad hlg_type for '%s', e==%d\n", tok_data, e);
                hlg = HLG_TEXT;
            }

            /* Set the highlight group type */
            add_type(ibuf, &lasttype, hlg);
            /* Add the text and bump our length */
            length += ibuf_add(ibuf, tok_data);
        }
    }

    ibuf_free(ibuf);
    tokenizer_destroy(t);
    return 0;
}
Example #11
0
int
gen_hello_prms_tlv(struct iface *iface, struct ibuf *buf, u_int16_t size)
{
	struct hello_prms_tlv	parms;

	/* We want just the size of the value */
	size -= TLV_HDR_LEN;

	bzero(&parms, sizeof(parms));
	parms.type = htons(TLV_TYPE_COMMONHELLO);
	parms.length = htons(size);
	/* XXX */
	parms.holdtime = htons(iface->holdtime);
	parms.flags = 0;

	return (ibuf_add(buf, &parms, sizeof(parms)));
}
Example #12
0
int
gen_status_tlv(struct ibuf *buf, u_int32_t status, u_int32_t msgid,
    u_int32_t type)
{
	struct status_tlv	st;

	bzero(&st, sizeof(st));

	st.type = htons(TLV_TYPE_STATUS);
	st.length = htons(STATUS_TLV_LEN);
	st.status_code = htonl(status);

	st.msg_id = msgid;
	st.msg_type = type;

	return (ibuf_add(buf, &st, STATUS_SIZE));
}
Example #13
0
int
gen_status_tlv(struct ibuf *buf, uint32_t status_code, uint32_t msg_id,
    uint16_t msg_type)
{
	struct status_tlv	st;

	memset(&st, 0, sizeof(st));
	st.type = htons(TLV_TYPE_STATUS);
	st.length = htons(STATUS_TLV_LEN);
	st.status_code = htonl(status_code);
	/*
	 * For convenience, msg_id and msg_type are already in network
	 * byte order.
	 */
	st.msg_id = msg_id;
	st.msg_type = msg_type;

	return (ibuf_add(buf, &st, STATUS_SIZE));
}
Example #14
0
int
gen_init_prms_tlv(struct ibuf *buf, struct nbr *nbr, u_int16_t size)
{
	struct sess_prms_tlv	parms;

	/* We want just the size of the value */
	size -= TLV_HDR_LEN;

	bzero(&parms, sizeof(parms));
	parms.type = htons(TLV_TYPE_COMMONSESSION);
	parms.length = htons(size);
	parms.proto_version = htons(LDP_VERSION);
	parms.keepalive_time = htons(leconf->keepalive);
	parms.reserved = 0;
	parms.pvlim = 0;
	parms.max_pdu_len = 0;
	parms.lsr_id = nbr->id.s_addr;
	parms.lspace_id = 0;

	return (ibuf_add(buf, &parms, SESS_PRMS_SIZE));
}
Example #15
0
static int test_dup(ibuf s)
{

    ibuf t;

    /* Test duplicating a string. */
    ibuf_add(s, "test string 1");
    t = ibuf_dup(s);

    if (t == NULL) {
        debug("test_dup: ibuf_dup (attempt #1) returned NULL\n");
        return 1;
    }

    if (strcmp(ibuf_get(s), ibuf_get(t)) != 0) {
        debug("test_dup: Strings mismatched: \"%s\" != \"%s\"\n",
                ibuf_get(s), ibuf_get(t));
        return 1;
    }
    ibuf_free(t);

    /* Corner case: duplicate an empty string */
    ibuf_clear(s);
    t = ibuf_dup(s);

    if (t == NULL) {
        debug("test_dup: ibuf_dup (attempt #2) returned NULL\n");
        return 1;
    }

    if (strcmp(ibuf_get(t), "") != 0) {
        debug("test_dup: Expected empty string, got: %s\n", ibuf_get(t));
        return 1;
    }
    ibuf_free(t);

    debug("test_dup: Succeeded.\n");
    return 0;
}
int Ctgdb::Send(char *command, enum tgdb_command_choice command_choice, ITarget* target)
{
	struct tgdb_command *tc;
	struct ibuf *temp_command = ibuf_init ();
	int length = strlen (command);

	/* Add a newline to the end of the command if it doesn't exist */
	ibuf_add (temp_command, command);

	if (command[length - 1] != '\n')
		ibuf_addchar (temp_command, '\n');

	/* Create the client command */
	tc = tgdb_command_create (ibuf_get (temp_command), command_choice, NULL);
	tc->ITarget = (void*) target;

	ibuf_free (temp_command);
	temp_command = NULL;

	if (Run_or_queue_command(tc) == -1)
	{
		Logger_write_pos( __FILE__, __LINE__,
				"tgdb_run_or_queue_command failed");
		return -1;
	}

	if (tgdb_client_tgdb_ran_command(tcc) == -1)
	{
		Logger_write_pos( __FILE__, __LINE__,
				"tgdb_client_tgdb_ran_command failed");
		return -1;
	}

	Process_client_commands();

	return 0;
}
Example #17
0
/* database description packet handling */
int
send_db_description(struct nbr *nbr)
{
	struct in6_addr		 dst;
	struct db_dscrp_hdr	 dd_hdr;
	struct lsa_entry	*le, *nle;
	struct ibuf		*buf;
	int			 ret = 0;
	u_int8_t		 bits = 0;

	if ((buf = ibuf_open(nbr->iface->mtu - sizeof(struct ip))) == NULL)
		fatal("send_db_description");

	/* OSPF header */
	if (gen_ospf_hdr(buf, nbr->iface, PACKET_TYPE_DD))
		goto fail;

	/* reserve space for database description header */
	if (ibuf_reserve(buf, sizeof(dd_hdr)) == NULL)
		goto fail;

	switch (nbr->state) {
	case NBR_STA_DOWN:
	case NBR_STA_ATTEMPT:
	case NBR_STA_INIT:
	case NBR_STA_2_WAY:
	case NBR_STA_SNAP:
		log_debug("send_db_description: cannot send packet in state %s,"
		    " neighbor ID %s", nbr_state_name(nbr->state),
		    inet_ntoa(nbr->id));
		ret = -1;
		goto done;
	case NBR_STA_XSTRT:
		bits |= OSPF_DBD_MS | OSPF_DBD_M | OSPF_DBD_I;
		nbr->dd_more = 1;
		break;
	case NBR_STA_XCHNG:
		if (nbr->dd_master)
			bits |= OSPF_DBD_MS;
		else
			bits &= ~OSPF_DBD_MS;

		if (TAILQ_EMPTY(&nbr->db_sum_list)) {
			bits &= ~OSPF_DBD_M;
			nbr->dd_more = 0;
		} else {
			bits |= OSPF_DBD_M;
			nbr->dd_more = 1;
		}

		bits &= ~OSPF_DBD_I;

		/* build LSA list */
		for (le = TAILQ_FIRST(&nbr->db_sum_list); le != NULL &&
		    buf->wpos + sizeof(struct lsa_hdr) < buf->max; le = nle) {
			nbr->dd_end = nle = TAILQ_NEXT(le, entry);
			if (ibuf_add(buf, le->le_lsa, sizeof(struct lsa_hdr)))
				goto fail;
		}
		break;
	case NBR_STA_LOAD:
	case NBR_STA_FULL:
		if (nbr->dd_master)
			bits |= OSPF_DBD_MS;
		else
			bits &= ~OSPF_DBD_MS;
		bits &= ~OSPF_DBD_M;
		bits &= ~OSPF_DBD_I;

		nbr->dd_more = 0;
		break;
	default:
		fatalx("send_db_description: unknown neighbor state");
	}

	bzero(&dd_hdr, sizeof(dd_hdr));

	switch (nbr->iface->type) {
	case IF_TYPE_POINTOPOINT:
		inet_pton(AF_INET6, AllSPFRouters, &dst);
		dd_hdr.iface_mtu = htons(nbr->iface->mtu);
		break;
	case IF_TYPE_BROADCAST:
		dst = nbr->addr;
		dd_hdr.iface_mtu = htons(nbr->iface->mtu);
		break;
	case IF_TYPE_NBMA:
	case IF_TYPE_POINTOMULTIPOINT:
		/* XXX not supported */
		break;
	case IF_TYPE_VIRTUALLINK:
		dst = nbr->iface->dst;
		dd_hdr.iface_mtu = 0;
		break;
	default:
		fatalx("send_db_description: unknown interface type");
	}

	dd_hdr.opts = htonl(area_ospf_options(area_find(oeconf,
	    nbr->iface->area_id)));
	dd_hdr.bits = bits;
	dd_hdr.dd_seq_num = htonl(nbr->dd_seq_num);

	memcpy(ibuf_seek(buf, sizeof(struct ospf_hdr), sizeof(dd_hdr)),
	    &dd_hdr, sizeof(dd_hdr));

	/* calculate checksum */
	if (upd_ospf_hdr(buf, nbr->iface))
		goto fail;

	/* transmit packet */
	ret = send_packet(nbr->iface, buf->buf, buf->wpos, &dst);
done:
	ibuf_free(buf);
	return (ret);
fail:
	log_warn("send_db_description");
	ibuf_free(buf);
	return (-1);
}
Example #18
0
void
ssl_read(int s, short event, void *arg)
{
	char			 rbuf[SMALL_READ_BUF_SIZE];
	struct ctl_tcp_event	*cte = arg;
	int			 retry_flag = EV_READ;
	int			 tls_err = 0;
	int			 ret;

	if (event == EV_TIMEOUT) {
		cte->host->up = HOST_DOWN;
		ssl_cleanup(cte);
		hce_notify_done(cte->host, HCE_TLS_READ_TIMEOUT);
		return;
	}

	bzero(rbuf, sizeof(rbuf));

	ret = SSL_read(cte->ssl, rbuf, sizeof(rbuf));
	if (ret <= 0) {
		tls_err = SSL_get_error(cte->ssl, ret);
		switch (tls_err) {
		case SSL_ERROR_WANT_READ:
			retry_flag = EV_READ;
			goto retry;
		case SSL_ERROR_WANT_WRITE:
			retry_flag = EV_WRITE;
			goto retry;
		case SSL_ERROR_ZERO_RETURN: /* FALLTHROUGH */
		case SSL_ERROR_SYSCALL:
			if (ret == 0) {
				cte->host->up = HOST_DOWN;
				(void)cte->validate_close(cte);
				ssl_cleanup(cte);
				hce_notify_done(cte->host, cte->host->he);
				return;
			}
			/* FALLTHROUGH */
		default:
			cte->host->up = HOST_DOWN;
			ssl_error(cte->host->conf.name, "cannot read");
			ssl_cleanup(cte);
			hce_notify_done(cte->host, HCE_TLS_READ_ERROR);
			break;
		}
		return;
	}
	if (ibuf_add(cte->buf, rbuf, ret) == -1)
		fatal("ssl_read: buf_add error");
	if (cte->validate_read != NULL) {
		if (cte->validate_read(cte) != 0)
			goto retry;

		ssl_cleanup(cte);
		hce_notify_done(cte->host, cte->host->he);
		return;
	}

retry:
	event_again(&cte->ev, s, EV_TIMEOUT|retry_flag, ssl_read,
	    &cte->tv_start, &cte->table->conf.timeout, cte);
	return;
}
Example #19
0
struct ibuf *
ikev2_msg_encrypt(struct iked *env, struct iked_sa *sa, struct ibuf *src)
{
	size_t			 len, encrlen, integrlen, blocklen, outlen;
	uint8_t			*buf, pad = 0, *ptr;
	struct ibuf		*encr, *dst = NULL, *out = NULL;

	buf = ibuf_data(src);
	len = ibuf_size(src);

	log_debug("%s: decrypted length %zu", __func__, len);
	print_hex(buf, 0, len);

	if (sa == NULL ||
	    sa->sa_encr == NULL ||
	    sa->sa_integr == NULL) {
		log_debug("%s: invalid SA", __func__);
		goto done;
	}

	if (sa->sa_hdr.sh_initiator)
		encr = sa->sa_key_iencr;
	else
		encr = sa->sa_key_rencr;

	blocklen = cipher_length(sa->sa_encr);
	integrlen = hash_length(sa->sa_integr);
	encrlen = roundup(len + sizeof(pad), blocklen);
	pad = encrlen - (len + sizeof(pad));

	/*
	 * Pad the payload and encrypt it
	 */
	if (pad) {
		if ((ptr = ibuf_advance(src, pad)) == NULL)
			goto done;
		arc4random_buf(ptr, pad);
	}
	if (ibuf_add(src, &pad, sizeof(pad)) != 0)
		goto done;

	log_debug("%s: padded length %zu", __func__, ibuf_size(src));
	print_hex(ibuf_data(src), 0, ibuf_size(src));

	cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr));
	cipher_setiv(sa->sa_encr, NULL, 0);
	cipher_init_encrypt(sa->sa_encr);

	if ((dst = ibuf_dup(sa->sa_encr->encr_iv)) == NULL)
		goto done;

	if ((out = ibuf_new(NULL,
	    cipher_outlength(sa->sa_encr, encrlen))) == NULL)
		goto done;

	outlen = ibuf_size(out);
	cipher_update(sa->sa_encr,
	    ibuf_data(src), encrlen, ibuf_data(out), &outlen);

	if (outlen && ibuf_add(dst, ibuf_data(out), outlen) != 0)
		goto done;

	if ((ptr = ibuf_advance(dst, integrlen)) == NULL)
		goto done;
	explicit_bzero(ptr, integrlen);

	log_debug("%s: length %zu, padding %d, output length %zu",
	    __func__, len + sizeof(pad), pad, ibuf_size(dst));
	print_hex(ibuf_data(dst), 0, ibuf_size(dst));

	ibuf_release(src);
	ibuf_release(out);
	return (dst);
 done:
	ibuf_release(src);
	ibuf_release(out);
	ibuf_release(dst);
	return (NULL);
}
Example #20
0
static int highlight_node ( struct list_node *node ) {
    struct tokenizer *t = tokenizer_init ();
    int ret;
    struct ibuf *ibuf = ibuf_init ();
    ibuf_addchar ( ibuf, HL_CHAR );
    ibuf_addchar ( ibuf, HLG_TEXT );

    /* Initialize */
    node->buf.length = 0;
    node->buf.tlines = NULL;
    node->buf.max_width = 0;

    if ( tokenizer_set_file ( t, node->path, node->language ) == -1 ) {
        if_print_message ("%s:%d tokenizer_set_file error", __FILE__, __LINE__);
        return -1;
    }

    while ( ( ret = tokenizer_get_token ( t ) ) > 0 ) {
        enum tokenizer_type e = tokenizer_get_packet_type ( t );
        /*if_print_message  ( "TOKEN(%d:%s)\n", e, tokenizer_get_printable_enum ( e ) );*/

        switch ( e ) {
        case TOKENIZER_KEYWORD:
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_KEYWORD );
            ibuf_add ( ibuf, tokenizer_get_data ( t ) );
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_TEXT );
            break;
        case TOKENIZER_TYPE:
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_TYPE );
            ibuf_add ( ibuf, tokenizer_get_data ( t ) );
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_TEXT );
            break;
        case TOKENIZER_LITERAL:
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_LITERAL );
            ibuf_add ( ibuf, tokenizer_get_data ( t ) );
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_TEXT );
            break;
        case TOKENIZER_NUMBER:
            ibuf_add ( ibuf, tokenizer_get_data ( t ) );
            break;
        case TOKENIZER_COMMENT:
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_COMMENT );
            ibuf_add ( ibuf, tokenizer_get_data ( t ) );
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_TEXT );
            break;
        case TOKENIZER_DIRECTIVE:
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_DIRECTIVE );
            ibuf_add ( ibuf, tokenizer_get_data ( t ) );
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_TEXT );
            break;
        case TOKENIZER_TEXT:
            ibuf_add ( ibuf, tokenizer_get_data ( t ) );
            break;
        case TOKENIZER_NEWLINE:
            node->buf.length++;
            node->buf.tlines = realloc ( node->buf.tlines, sizeof ( char *) * node->buf.length );
            node->buf.tlines[node->buf.length-1] = strdup ( ibuf_get ( ibuf ) );

            if ( ibuf_length ( ibuf ) > node->buf.max_width )
                node->buf.max_width = ibuf_length ( ibuf );

            ibuf_clear ( ibuf );
            ibuf_addchar ( ibuf, HL_CHAR );
            ibuf_addchar ( ibuf, HLG_TEXT );
            break;
        case TOKENIZER_ERROR:
            ibuf_add ( ibuf, tokenizer_get_data ( t ) );
            break;
        default:
            return -1;
            break;
        }
    }

    return 0;
}
Example #21
0
int
ca_reload(struct iked *env)
{
	struct ca_store		*store = env->sc_priv;
	uint8_t			 md[EVP_MAX_MD_SIZE];
	char			 file[PATH_MAX];
	struct iovec		 iov[2];
	struct dirent		*entry;
	STACK_OF(X509_OBJECT)	*h;
	X509_OBJECT		*xo;
	X509			*x509;
	DIR			*dir;
	int			 i, len, iovcnt = 0;

	/*
	 * Load CAs
	 */
	if ((dir = opendir(IKED_CA_DIR)) == NULL)
		return (-1);

	while ((entry = readdir(dir)) != NULL) {
		if ((entry->d_type != DT_REG) &&
		    (entry->d_type != DT_LNK))
			continue;

		if (snprintf(file, sizeof(file), "%s%s",
		    IKED_CA_DIR, entry->d_name) == -1)
			continue;

		if (!X509_load_cert_file(store->ca_calookup, file,
		    X509_FILETYPE_PEM)) {
			log_warn("%s: failed to load ca file %s", __func__,
			    entry->d_name);
			ca_sslerror(__func__);
			continue;
		}
		log_debug("%s: loaded ca file %s", __func__, entry->d_name);
	}
	closedir(dir);

	/*
	 * Load CRLs for the CAs
	 */
	if ((dir = opendir(IKED_CRL_DIR)) == NULL)
		return (-1);

	while ((entry = readdir(dir)) != NULL) {
		if ((entry->d_type != DT_REG) &&
		    (entry->d_type != DT_LNK))
			continue;

		if (snprintf(file, sizeof(file), "%s%s",
		    IKED_CRL_DIR, entry->d_name) == -1)
			continue;

		if (!X509_load_crl_file(store->ca_calookup, file,
		    X509_FILETYPE_PEM)) {
			log_warn("%s: failed to load crl file %s", __func__,
			    entry->d_name);
			ca_sslerror(__func__);
			continue;
		}

		/* Only enable CRL checks if we actually loaded a CRL */
		X509_STORE_set_flags(store->ca_cas, X509_V_FLAG_CRL_CHECK);

		log_debug("%s: loaded crl file %s", __func__, entry->d_name);
	}
	closedir(dir);

	/*
	 * Save CAs signatures for the IKEv2 CERTREQ
	 */
	ibuf_release(env->sc_certreq);
	if ((env->sc_certreq = ibuf_new(NULL, 0)) == NULL)
		return (-1);

	h = store->ca_cas->objs;
	for (i = 0; i < sk_X509_OBJECT_num(h); i++) {
		xo = sk_X509_OBJECT_value(h, i);
		if (xo->type != X509_LU_X509)
			continue;

		x509 = xo->data.x509;
		len = sizeof(md);
		ca_subjectpubkey_digest(x509, md, &len);
		log_debug("%s: %s", __func__, x509->name);

		if (ibuf_add(env->sc_certreq, md, len) != 0) {
			ibuf_release(env->sc_certreq);
			return (-1);
		}
	}

	if (ibuf_length(env->sc_certreq)) {
		env->sc_certreqtype = IKEV2_CERT_X509_CERT;
		iov[0].iov_base = &env->sc_certreqtype;
		iov[0].iov_len = sizeof(env->sc_certreqtype);
		iovcnt++;
		iov[1].iov_base = ibuf_data(env->sc_certreq);
		iov[1].iov_len = ibuf_length(env->sc_certreq);
		iovcnt++;

		log_debug("%s: loaded %zu ca certificate%s", __func__,
		    ibuf_length(env->sc_certreq) / SHA_DIGEST_LENGTH,
		    ibuf_length(env->sc_certreq) == SHA_DIGEST_LENGTH ?
		    "" : "s");

		(void)proc_composev(&env->sc_ps, PROC_IKEV2, IMSG_CERTREQ,
		    iov, iovcnt);
	}

	/*
	 * Load certificates
	 */
	if ((dir = opendir(IKED_CERT_DIR)) == NULL)
		return (-1);

	while ((entry = readdir(dir)) != NULL) {
		if ((entry->d_type != DT_REG) &&
		    (entry->d_type != DT_LNK))
			continue;

		if (snprintf(file, sizeof(file), "%s%s",
		    IKED_CERT_DIR, entry->d_name) == -1)
			continue;

		if (!X509_load_cert_file(store->ca_certlookup, file,
		    X509_FILETYPE_PEM)) {
			log_warn("%s: failed to load cert file %s", __func__,
			    entry->d_name);
			ca_sslerror(__func__);
			continue;
		}
		log_debug("%s: loaded cert file %s", __func__, entry->d_name);
	}
	closedir(dir);

	h = store->ca_certs->objs;
	for (i = 0; i < sk_X509_OBJECT_num(h); i++) {
		xo = sk_X509_OBJECT_value(h, i);
		if (xo->type != X509_LU_X509)
			continue;

		x509 = xo->data.x509;

		(void)ca_validate_cert(env, NULL, x509, 0);
	}

	if (!env->sc_certreqtype)
		env->sc_certreqtype = store->ca_pubkey.id_type;

	log_debug("%s: local cert type %s", __func__,
	    print_map(env->sc_certreqtype, ikev2_cert_map));

	iov[0].iov_base = &env->sc_certreqtype;
	iov[0].iov_len = sizeof(env->sc_certreqtype);
	if (iovcnt == 0)
		iovcnt++;
	(void)proc_composev(&env->sc_ps, PROC_IKEV2, IMSG_CERTREQ, iov, iovcnt);

	return (0);
}
Example #22
0
int
eap_mschap(struct iked *env, struct iked_sa *sa, struct eap_message *eap)
{
	struct iked_user		*usr;
	struct eap_message		*resp;
	struct eap_mschap_response	*msr;
	struct eap_mschap_peer		*msp;
	struct eap_mschap		*ms;
	struct eap_mschap_success	*mss;
	u_int8_t			*ptr, *pass;
	size_t				 len, passlen;
	char				*name, *msg;
	u_int8_t			 ntresponse[EAP_MSCHAP_NTRESPONSE_SZ];
	u_int8_t			 successmsg[EAP_MSCHAP_SUCCESS_SZ];
	struct ibuf			*eapmsg = NULL;
	int				 ret = -1;

	if (!sa_stateok(sa, IKEV2_STATE_EAP)) {
		log_debug("%s: unexpected EAP", __func__);
		return (0);	/* ignore */
	}

	if (sa->sa_hdr.sh_initiator) {
		log_debug("%s: initiator EAP not supported", __func__);
		return (-1);
	}

	/* Only MSCHAP-V2 */
	if (eap->eap_type != EAP_TYPE_MSCHAP_V2) {
		log_debug("%s: unsupported type EAP-%s", __func__,
		    print_map(eap->eap_type, eap_type_map));
		return (-1);
	}

	if (betoh16(eap->eap_length) < (sizeof(*eap) + sizeof(*ms))) {
		log_debug("%s: short message", __func__);
		return (-1);
	}

	ms = (struct eap_mschap *)(eap + 1);
	ptr = (u_int8_t *)(eap + 1);

	switch (ms->ms_opcode) {
	case EAP_MSOPCODE_RESPONSE:
		msr = (struct eap_mschap_response *)ms;
		if (betoh16(eap->eap_length) < (sizeof(*eap) + sizeof(*msr))) {
			log_debug("%s: short response", __func__);
			return (-1);
		}
		ptr += sizeof(*msr);
		len = betoh16(eap->eap_length) -
		    sizeof(*eap) - sizeof(*msr);
		if (len == 0 && sa->sa_eapid != NULL)
			name = strdup(sa->sa_eapid);
		else
			name = get_string(ptr, len);
		if (name == NULL) {
			log_debug("%s: invalid response name", __func__);
			return (-1);
		}
		if ((usr = user_lookup(env, name)) == NULL) {
			log_debug("%s: unknown user '%s'", __func__, name);
			free(name);
			return (-1);
		}
		free(name);

		if ((pass = string2unicode(usr->usr_pass, &passlen)) == NULL)
			return (-1);

		msp = &msr->msr_response.resp_peer;
		mschap_nt_response(ibuf_data(sa->sa_eap.id_buf),
		    msp->msp_challenge, usr->usr_name, strlen(usr->usr_name),
		    pass, passlen, ntresponse);

		if (memcmp(ntresponse, msp->msp_ntresponse,
		    sizeof(ntresponse)) != 0) {
			log_debug("%s: '%s' authentication failed", __func__,
			    usr->usr_name);
			free(pass);

			/* XXX should we send an EAP failure packet? */
			return (-1);
		}

		bzero(&successmsg, sizeof(successmsg));
		mschap_auth_response(pass, passlen,
		    ntresponse, ibuf_data(sa->sa_eap.id_buf),
		    msp->msp_challenge, usr->usr_name, strlen(usr->usr_name),
		    successmsg);
		if ((sa->sa_eapmsk = ibuf_new(NULL, MSCHAP_MSK_SZ)) == NULL) {
			log_debug("%s: failed to get MSK", __func__);
			free(pass);
			return (-1);
		}
		mschap_msk(pass, passlen, ntresponse,
		    ibuf_data(sa->sa_eapmsk));
		free(pass);

		log_info("%s: '%s' authenticated", __func__, usr->usr_name);


		if ((eapmsg = ibuf_static()) == NULL)
			return (-1);

		msg = " M=Welcome";

		if ((resp = ibuf_advance(eapmsg, sizeof(*resp))) == NULL)
			goto done;
		resp->eap_code = EAP_CODE_REQUEST;
		resp->eap_id = eap->eap_id + 1;
		resp->eap_length = htobe16(sizeof(*resp) + sizeof(*mss) +
		    sizeof(successmsg) + strlen(msg));
		resp->eap_type = EAP_TYPE_MSCHAP_V2;

		if ((mss = ibuf_advance(eapmsg, sizeof(*mss))) == NULL)
			goto done;
		mss->mss_opcode = EAP_MSOPCODE_SUCCESS;
		mss->mss_id = msr->msr_id;
		mss->mss_length = htobe16(sizeof(*mss) +
		    sizeof(successmsg) + strlen(msg));
		if (ibuf_add(eapmsg, successmsg, sizeof(successmsg)) != 0)
			goto done;
		if (ibuf_add(eapmsg, msg, strlen(msg)) != 0)
			goto done;
		break;
	case EAP_MSOPCODE_SUCCESS:
		if ((eapmsg = ibuf_static()) == NULL)
			return (-1);
		if ((resp = ibuf_advance(eapmsg, sizeof(*resp))) == NULL)
			goto done;
		resp->eap_code = EAP_CODE_RESPONSE;
		resp->eap_id = eap->eap_id;
		resp->eap_length = htobe16(sizeof(*resp) + sizeof(*ms));
		resp->eap_type = EAP_TYPE_MSCHAP_V2;
		if ((ms = ibuf_advance(eapmsg, sizeof(*ms))) == NULL)
			goto done;
		ms->ms_opcode = EAP_MSOPCODE_SUCCESS;
		break;
	case EAP_MSOPCODE_FAILURE:
	case EAP_MSOPCODE_CHANGE_PASSWORD:
	case EAP_MSOPCODE_CHALLENGE:
	default:
		log_debug("%s: EAP-%s unsupported "
		    "responder operation %s", __func__,
		    print_map(eap->eap_type, eap_type_map),
		    print_map(ms->ms_opcode, eap_msopcode_map));
		return (-1);
	}

	if (eapmsg != NULL)
		ret = ikev2_send_ike_e(env, sa, eapmsg,
		    IKEV2_PAYLOAD_EAP, IKEV2_EXCHANGE_IKE_AUTH, 1);

	if (ret == 0)
		sa_state(env, sa, IKEV2_STATE_AUTH_SUCCESS);

 done:
	ibuf_release(eapmsg);
	return (ret);
}
Example #23
0
int
ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
    struct iked_message *msg, off_t offset)
{
	struct iked_childsa	**peersas = NULL;
	struct iked_sa		*sa = msg->msg_sa;
	struct ikev2_delete	*del, *localdel;
	struct ibuf		*resp = NULL;
	u_int64_t		*localspi = NULL;
	u_int64_t		 spi64, spi = 0;
	u_int32_t		 spi32;
	u_int8_t		*buf, *msgbuf = ibuf_data(msg->msg_data);
	size_t			 found = 0, failed = 0;
	int			 cnt, i, len, sz, ret = -1;

	/* Skip if it's a reply and we don't have to deal with it */
	if (ikev2_msg_frompeer(msg) && sa &&
	    (sa->sa_stateflags & IKED_REQ_INF)) {
		sa->sa_stateflags &= ~IKED_REQ_INF;
		if ((sa->sa_stateflags & IKED_REQ_DELETE) == 0)
			return (0);
	}

	if ((del = ibuf_seek(msg->msg_data, offset, sizeof(*del))) == NULL)
		return (-1);
	cnt = betoh16(del->del_nspi);
	sz = del->del_spisize;

	log_debug("%s: proto %s spisize %d nspi %d",
	    __func__, print_map(del->del_protoid, ikev2_saproto_map),
	    sz, cnt);

	buf = msgbuf + offset + sizeof(*del);
	len = betoh16(pld->pld_length) - sizeof(*pld) - sizeof(*del);

	print_hex(buf, 0, len);

	switch (sz) {
	case 4:
	case 8:
		break;
	default:
		if (ikev2_msg_frompeer(msg) &&
		    del->del_protoid == IKEV2_SAPROTO_IKE) {
			/* Send an empty informational response */
			if ((resp = ibuf_static()) == NULL)
				goto done;
			ret = ikev2_send_ike_e(env, sa, resp,
			    IKEV2_PAYLOAD_NONE,
			    IKEV2_EXCHANGE_INFORMATIONAL, 1);
			ibuf_release(resp);
			sa_state(env, sa, IKEV2_STATE_CLOSED);
			return (ret);
		}
		log_debug("%s: invalid SPI size", __func__);
		return (-1);
	}

	if ((len / sz) != cnt) {
		log_debug("%s: invalid payload length %d/%d != %d",
		    __func__, len, sz, cnt);
		return (-1);
	}

	if (ikev2_msg_frompeer(msg) &&
	    ((peersas = calloc(cnt, sizeof(struct iked_childsa *))) == NULL ||
	     (localspi = calloc(cnt, sizeof(u_int64_t))) == NULL)) {
		log_warn("%s", __func__);
		goto done;
	}

	for (i = 0; i < cnt; i++) {
		switch (sz) {
		case 4:
			memcpy(&spi32, buf + (i * sz), sizeof(spi32));
			spi = betoh32(spi32);
			break;
		case 8:
			memcpy(&spi64, buf + (i * sz), sizeof(spi64));
			spi = betoh64(spi64);
			break;
		}

		log_debug("%s: spi %s", __func__, print_spi(spi, sz));

		if (peersas == NULL || sa == NULL)
			continue;

		if ((peersas[i] = childsa_lookup(sa, spi,
		    del->del_protoid)) == NULL) {
			log_warnx("%s: CHILD SA doesn't exist for spi %s",
			    __func__, print_spi(spi, del->del_spisize));
			goto done;
		}

		if (ikev2_childsa_delete(env, sa, del->del_protoid, spi,
		    &localspi[i], 0) == -1)
			failed++;
		else
			found++;

		/*
		 * Flows are left in the require mode so that it would be
		 * possible to quickly negotiate a new Child SA
		 */
	}

	/* Parsed outgoing message? */
	if (!ikev2_msg_frompeer(msg))
		goto done;

	if (sa && (sa->sa_stateflags & IKED_REQ_DELETE)) {
		/* Finish rekeying */
		sa->sa_stateflags &= ~IKED_REQ_DELETE;
		ret = 0;
		goto done;
	}

	/* Response to the INFORMATIONAL with Delete payload */

	if ((resp = ibuf_static()) == NULL)
		goto done;

	if (found) {
		if ((localdel = ibuf_advance(resp, sizeof(*localdel))) == NULL)
			goto done;

		localdel->del_protoid = del->del_protoid;
		localdel->del_spisize = del->del_spisize;
		localdel->del_nspi = htobe16(found);

		for (i = 0; i < cnt; i++) {
			switch (sz) {
			case 4:
				spi32 = htobe32(localspi[i]);
				if (ibuf_add(resp, &spi32, sizeof(spi32)) != 0)
					goto done;
				break;
			case 8:
				spi64 = htobe64(localspi[i]);
				if (ibuf_add(resp, &spi64, sizeof(spi64)) != 0)
					goto done;
				break;
			}
		}

		log_warnx("%s: deleted %d spis", __func__, found);
	}

	if (found) {
		ret = ikev2_send_ike_e(env, sa, resp, IKEV2_PAYLOAD_DELETE,
		    IKEV2_EXCHANGE_INFORMATIONAL, 1);
	} else {
		/* XXX should we send an INVALID_SPI notification? */
		ret = 0;
	}

 done:
	if (localspi)
		free(localspi);
	if (peersas)
		free(peersas);
	ibuf_release(resp);
	return (ret);
}
Example #24
0
File: cgdb.c Project: i4fumi/cgdb
/* Please forgive me for adding all the comment below. This function
 * has some strange bahaviors that I thought should be well explained.
 */
void rlctx_send_user_command(char *line)
{
    char *cline;
    int length;
    char *rline_prompt;
    tgdb_request_ptr request_ptr;

    if (line == NULL) {
        /* NULL line means rl_callback_read_char received EOF */
        ibuf_add(current_line, "quit");
    } else {
        /* Add the line passed in to the current line */
        ibuf_add(current_line, line);
    }

    /* Get current line, and current line length */
    cline = ibuf_get(current_line);
    length = ibuf_length(current_line);

    /* Check to see if the user is escaping the line, to use a 
     * multi line command. If so, return so that the user can
     * continue the command. This data should not go into the history
     * buffer, or be sent to gdb yet. 
     *
     * Also, notice the length > 0 condition. (length == 0) can happen 
     * when the user simply hits Enter on the keyboard. */
    if (length > 0 && cline[length - 1] == '\\') {
        /* The \ char is for continuation only, it is not meant to be sent
         * to GDB as a character. */
        ibuf_delchar(current_line);

        /* Only need to change the prompt the first time the \ char is used.
         * Doing it a second time would erase the real rline_last_prompt,
         * since the prompt has already been set to "".
         */
        if (!rline_last_prompt) {
            rline_get_prompt(rline, &rline_prompt);
            rline_last_prompt = strdup(rline_prompt);
            /* GDB set's the prompt to nothing when doing continuation.
             * This is here just for compatibility. */
            rline_set_prompt(rline, "");
        }

        return;
    }

    /* If here, a full command has been sent. Restore the prompt. */
    if (rline_last_prompt) {
        rline_set_prompt(rline, rline_last_prompt);
        free(rline_last_prompt);
        rline_last_prompt = NULL;
    }

    /* Don't add the enter command to the history */
    if (length > 0)
        rline_add_history(rline, cline);

    request_ptr = tgdb_request_run_console_command(tgdb, cline);
    if (!request_ptr)
        logger_write_pos(logger, __FILE__, __LINE__,
                "rlctx_send_user_command\n");

    /* Send this command to TGDB */
    handle_request(tgdb, request_ptr);

    ibuf_clear(current_line);
}