Beispiel #1
0
/**
 * Unpack a message whack received
 * 
 * @param wp The whack message
 * @return err_t
 */
err_t unpack_whack_msg (struct whackpacker *wp)
{
    err_t ugh = NULL;

    if (wp->str_next > wp->str_roof)
    {
	ugh = builddiag("ignoring truncated message from whack: got %d bytes; expected %u"
			, (int) wp->n, (unsigned) sizeof(wp->msg));
    }
    if (!unpack_str(wp, &wp->msg->name)	          /* string 1 */
	|| !unpack_str(wp, &wp->msg->left.id)     /* string 2 */
	|| !unpack_str(wp, &wp->msg->left.cert)   /* string 3 */
	|| !unpack_str(wp, &wp->msg->left.ca)     /* string 4 */
	|| !unpack_str(wp, &wp->msg->left.groups) /* string 5 */
	|| !unpack_str(wp, &wp->msg->left.updown) /* string 6 */
    	|| !unpack_str(wp, &wp->msg->left.virt)   /* string 7 */
	|| !unpack_str(wp, &wp->msg->right.id)    /* string 8 */
    	|| !unpack_str(wp, &wp->msg->right.cert)  /* string 9 */
    	|| !unpack_str(wp, &wp->msg->right.ca)    /* string 10 */
	|| !unpack_str(wp, &wp->msg->right.groups)/* string 11 */
	|| !unpack_str(wp, &wp->msg->right.updown)/* string 12 */
    	|| !unpack_str(wp, &wp->msg->right.virt)  /* string 13 */
	|| !unpack_str(wp, &wp->msg->keyid)       /* string 14 */
	|| !unpack_str(wp, &wp->msg->myid)        /* string 15 */
    	|| !unpack_str(wp, &wp->msg->ike)         /* string 16 */
    	|| !unpack_str(wp, &wp->msg->esp)         /* string 17 */
    	|| !unpack_str(wp, &wp->msg->tpmeval)     /* string 18 */
    	|| !unpack_str(wp, &wp->msg->left.xauth_name)    /* string 19 */
    	|| !unpack_str(wp, &wp->msg->right.xauth_name)   /* string 20 */
    	|| !unpack_str(wp, &wp->msg->connalias)   /* string 21 */
    	|| !unpack_str(wp, &wp->msg->left.host_addr_name)    /* string 22 */
    	|| !unpack_str(wp, &wp->msg->right.host_addr_name)   /* string 23 */
	|| !unpack_str(wp, &wp->msg->string1)                /* string 24 */
	|| !unpack_str(wp, &wp->msg->string2)                /* string 25 */
	|| !unpack_str(wp, &wp->msg->string3)                /* string 26 */
	|| !unpack_str(wp, &wp->msg->dnshostname)  /* string 27 ? */
#ifdef HAVE_LABELED_IPSEC
	|| !unpack_str(wp, &wp->msg->policy_label) /* string 28 */
#endif
	|| wp->str_roof - wp->str_next != (ptrdiff_t)wp->msg->keyval.len)	/* check chunk */
    {
	ugh = "message from whack contains bad string";
    }

    return ugh;
}
Beispiel #2
0
/*******************************************************************************
函数名称: init_ws_ctl_socket
功能描述: 初始化web_services control套接字
输入参数:                          
输出参数: 无
返 回 值    :  err_t:返回错误信息,成功返回NULL
--------------------------------------------------------------------------------
最近一次修改记录 :
修改作者: tiangu        
修改目的: 创建新函数
修改日期: 2010-4-20
*******************************************************************************/
err_t init_ws_ctl_socket(void)
{
   err_t failed = NULL;

    delete_ws_ctl_socket();	/* preventative medicine */
    ws_ctl_fd = safe_socket(AF_UNIX, SOCK_STREAM, 0);
    int size = offsetof(struct sockaddr_un, sun_path) + strlen(ws_ctl_addr.sun_path);

    if (ws_ctl_fd == -1)
	{
	    failed = "create";    
    }
    else if (setsockopt(ws_ctl_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
    {
        failed = "setsockopt";
    }
    else
    {	   
	    mode_t ou = umask(0);
    
    	if (bind(ws_ctl_fd, (struct sockaddr *)&ws_ctl_addr, size) < 0)
    	{
    	    failed = "bind";
        }
        
	    umask(ou);
    }

   
    if (failed == NULL && listen(ws_ctl_fd, 5) < 0)
    {
        failed = "listen() on";
    }
    
    return failed == NULL? NULL : builddiag("could not %s ws_ctl socket: %d %s"
	    , failed, errno, strerror(errno));
    
}
Beispiel #3
0
/**
 * Unpack a message whack received
 * 
 * @param wp The whack message
 * @return err_t
 */
err_t unpack_whack_msg (struct whackpacker *wp)
{
    err_t ugh = NULL;

    if (wp->str_next > wp->str_roof)
    {
	ugh = builddiag("ignoring truncated message from whack: got %d bytes; expected %u"
			, (int) wp->n, (unsigned) sizeof(wp->msg));
    }
    if (!unpack_str(wp, &wp->msg->name)	          /* string 1 */
	|| !unpack_str(wp, &wp->msg->left.id)     /* string 2 */
	|| !unpack_str(wp, &wp->msg->left.cert)   /* string 3 */
	|| !unpack_str(wp, &wp->msg->left.ca)     /* string 4 */
	|| !unpack_str(wp, &wp->msg->left.groups) /* string 5 */
	|| !unpack_str(wp, &wp->msg->left.updown) /* string 6 */
#ifdef VIRTUAL_IP
    	|| !unpack_str(wp,&wp->msg->left.virt)    /* string 7 */
#endif
	|| !unpack_str(wp, &wp->msg->right.id)    /* string 8 */
    	|| !unpack_str(wp, &wp->msg->right.cert)  /* string 9 */
    	|| !unpack_str(wp, &wp->msg->right.ca)    /* string 10 */
	|| !unpack_str(wp, &wp->msg->right.groups)/* string 11 */
	|| !unpack_str(wp, &wp->msg->right.updown)/* string 12 */
#ifdef VIRTUAL_IP
    	|| !unpack_str(wp, &wp->msg->right.virt)  /* string 13 */
#endif
	|| !unpack_str(wp, &wp->msg->keyid)       /* string 14 */
	|| !unpack_str(wp, &wp->msg->myid)        /* string 15 */
    	|| !unpack_str(wp, &wp->msg->ike)         /* string 16 */
    	|| !unpack_str(wp, &wp->msg->esp)         /* string 17 */

       || wp->str_roof - wp->str_next != (ptrdiff_t)wp->msg->keyval.len)	/* check chunk */
    {
	ugh = "message from whack contains bad string";
    }

    return ugh;
}
Beispiel #4
0
bool
in_struct(void *struct_ptr, struct_desc *sd
, pb_stream *ins, pb_stream *obj_pbs)
{
    err_t ugh = NULL;
    u_int8_t *cur = ins->cur;

    if (ins->roof - cur < (ptrdiff_t)sd->size) {
	ugh = builddiag("not enough room in input packet for %s", sd->name);
    } else {
	u_int8_t *roof = cur + sd->size;    /* may be changed by a length field */
	u_int8_t *outp = struct_ptr;
	bool immediate = FALSE;
	field_desc *fp;

	for (fp = sd->fields; ugh == NULL; fp++) {
	    size_t i = fp->size;

	    passert(ins->roof - cur >= (ptrdiff_t)i);
	    passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i));
	    passert(outp - (cur - ins->cur) == struct_ptr);

#if 0
	    DBG(DBG_PARSING, DBG_log("%d %s"
		, (int) (cur - ins->cur), fp->name == NULL? "" : fp->name));
#endif
	    switch (fp->field_type) {
	    case ft_mbz:	/* must be zero */
		for (; i != 0; i--) {
		    if (*cur++ != 0) {
			ugh = builddiag("byte %d of %s must be zero, but is not"
			    , (int) (cur - ins->cur), sd->name);
			break;
		    }
		    *outp++ = '\0';	/* probably redundant */
		}
		break;

	    case ft_nat:	/* natural number (may be 0) */
	    case ft_len:	/* length of this struct and any following crud */
	    case ft_lv:		/* length/value field of attribute */
	    case ft_enum:	/* value from an enumeration */
	    case ft_loose_enum:	/* value from an enumeration with only some names known */
	    case ft_af_enum:	/* Attribute Format + value from an enumeration */
	    case ft_set:	/* bits representing set */
	    {
		u_int32_t n = 0;

		for (; i != 0; i--)
		    n = (n << BITS_PER_BYTE) | *cur++;

		switch (fp->field_type) {
		case ft_len:	/* length of this struct and any following crud */
		case ft_lv:	/* length/value field of attribute */
		{
		    u_int32_t len = fp->field_type == ft_len? n
			: immediate? sd->size : n + sd->size;

		    if (len < sd->size) {
			ugh = builddiag("%s of %s is smaller than minimum"
			    , fp->name, sd->name);
		    } else if (pbs_left(ins) < len) {
			ugh = builddiag("%s of %s is larger than can fit"
			    , fp->name, sd->name);
		    } else {
			roof = ins->cur + len;
		    }
		    break;
		}
		case ft_af_enum:	/* Attribute Format + value from an enumeration */
		    if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
			immediate = TRUE;
		    /* FALL THROUGH */
		case ft_enum:	/* value from an enumeration */
		    if (enum_name(fp->desc, n) == NULL) {
			ugh = builddiag("%s of %s has an unknown value: %lu"
			    , fp->name, sd->name, (unsigned long)n);
		    }
		    /* FALL THROUGH */
		case ft_loose_enum:	/* value from an enumeration with only some names known */
		    break;
		case ft_set:	/* bits representing set */
		    if (!testset(fp->desc, n)) {
			ugh = builddiag("bitset %s of %s has unknown member(s): %s"
			    , fp->name, sd->name, bitnamesof(fp->desc, n));
		    }
		    break;
		default:
			break;
		}
		i = fp->size;
		switch (i) {
		case 8/BITS_PER_BYTE:
		    *(u_int8_t *)outp = n;
		    break;
		case 16/BITS_PER_BYTE:
		    *(u_int16_t *)outp = n;
		    break;
		case 32/BITS_PER_BYTE:
		    *(u_int32_t *)outp = n;
		    break;
		default:
		    impossible();
		}
		outp += i;
		break;
	    }

	    case ft_raw:	/* bytes to be left in network-order */
		for (; i != 0; i--) {
		    *outp++ = *cur++;
		}
		break;

	    case ft_end:	/* end of field list */
		passert(cur == ins->cur + sd->size);
		if (obj_pbs != NULL) {
		    init_pbs(obj_pbs, ins->cur, roof - ins->cur, sd->name);
		    obj_pbs->container = ins;
		    obj_pbs->desc = sd;
		    obj_pbs->cur = cur;
		}
		ins->cur = roof;
		DBG(DBG_PARSING
		    , DBG_prefix_print_struct(ins, "parse ", struct_ptr, sd, TRUE));
		return TRUE;

	    default:
		impossible();
	    }
	}
    }

    /* some failure got us here: report it */
    loglog(RC_LOG_SERIOUS, ugh);
    return FALSE;
}
Beispiel #5
0
/* Handle a kernel request. Supposedly, there's a message in
 * the kernelsock socket.
 */
void
whack_handle(int whackctlfd)
{
    struct whack_message msg;
    struct sockaddr_un whackaddr;
    int whackaddrlen = sizeof(whackaddr);
    int whackfd = accept(whackctlfd, (struct sockaddr *)&whackaddr, &whackaddrlen);
    ssize_t n;

    if (whackfd < 0)
    {
	log_errno((e, "accept() failed in whack_handle()"));
	return;
    }
    n = read(whackfd, &msg, sizeof(msg));
    if (n == -1)
    {
	log_errno((e, "read() failed in whack_handle()"));
	close(whackfd);
	return;
    }

    whack_log_fd = whackfd;

    /* sanity check message */
    {
	err_t ugh = NULL;

	next_str = msg.string;
	str_roof = (char *)&msg + n;

	if (next_str > str_roof)
	{
	    ugh = builddiag("truncated message from whack: got %d bytes; expected %d.  Message ignored."
		, n, (int) sizeof(msg));
	}
	else if (msg.magic != WHACK_MAGIC)
	{
	    ugh = builddiag("message from whack has bad magic %d; should be %d; probably wrong version.  Message ignored"
		, msg.magic, WHACK_MAGIC);
	}
	else if (!unpack_str(&msg.name)		/* string 1 */
	|| !unpack_str(&msg.left.id)		/* string 2 */
	|| !unpack_str(&msg.left.cert)		/* string 3 */
	|| !unpack_str(&msg.left.updown)	/* string 4 */
#ifdef VIRTUAL_IP
	|| !unpack_str(&msg.left.virt)
#endif
	|| !unpack_str(&msg.right.id)		/* string 5 */
	|| !unpack_str(&msg.right.cert)		/* string 6 */	
	|| !unpack_str(&msg.right.updown)	/* string 7 */
#ifdef VIRTUAL_IP
	|| !unpack_str(&msg.right.virt)
#endif
	|| !unpack_str(&msg.keyid)		/* string 8 */
	|| !unpack_str(&msg.ike)		/* string 9 */
	|| !unpack_str(&msg.esp)		/* string 10 */	
	|| !unpack_str(&msg.dnshostname)	/* string 11 */
	|| str_roof - next_str != (ptrdiff_t)msg.keyval.len)	/* check chunk */
	{
	    ugh = "message from whack contains bad string";
	}
	else
	{
	    msg.keyval.ptr = next_str;	/* grab chunk */
	}

	if (ugh != NULL)
	{
	    loglog(RC_BADWHACKMESSAGE, "%s", ugh);
	    whack_log_fd = NULL_FD;
	    close(whackfd);
	    return;
	}
    }

    if (msg.whack_options)
    {
#ifdef DEBUG
	if (msg.name == NULL)
	{
	    /* we do a two-step so that if either old or new would
	     * cause the message to print, it will be printed.
	     */
	    cur_debugging |= msg.debugging;
	    DBG(DBG_CONTROL
		, DBG_log("base debugging = %s"
		    , bitnamesof(debug_bit_names, msg.debugging)));
	    cur_debugging = base_debugging = msg.debugging;
	}
	else if (!msg.whack_connection)
	{
	    struct connection *c = con_by_name(msg.name, TRUE);

	    if (c != NULL)
	    {
		c->extra_debugging = msg.debugging;
		DBG(DBG_CONTROL
		    , DBG_log("\"%s\" extra_debugging = %s"
			, c->name
			, bitnamesof(debug_bit_names, c->extra_debugging)));
	    }
	}
#endif
    }

    /* Deleting combined with adding a connection works as replace.
     * To make this more useful, in only this combination,
     * delete will silently ignore the lack of the connection.
     */
    if (msg.whack_delete)
    {
	struct connection *c = con_by_name(msg.name, !msg.whack_connection);

	/* note: this is a "while" because road warrior
	 * leads to multiple connections with the same name.
	 */
	for (; c != NULL; c = con_by_name(msg.name, FALSE))
	    delete_connection(c);
    }

    if (msg.whack_deletestate)
    {
	struct state *st = state_with_serialno(msg.whack_deletestateno);

	if (st == NULL)
	{
	    loglog(RC_UNKNOWN_NAME, "no state #%lu to delete"
		, msg.whack_deletestateno);
	}
	else
	{
	    delete_state(st);
	}
    }

    if (msg.whack_connection)
	add_connection(&msg);

    /* process "listen" before any operation that could require it */
    if (msg.whack_listen)
    {
	log("listening for IKE messages");
	listening = TRUE;
	find_ifaces();
	load_preshared_secrets();
    }
    if (msg.whack_unlisten)
    {
	log("no longer listening for IKE messages");
	listening = FALSE;
    }

    if (msg.whack_reread & REREAD_SECRETS)
    {
	load_preshared_secrets();
    }

   if (msg.whack_reread & REREAD_MYCERT)
    {
	load_mycert();
    }

   if (msg.whack_reread & REREAD_CACERTS)
    {
	load_cacerts();
    }

   if (msg.whack_reread & REREAD_CRLS)
    {
	load_crls();
    }

   if (msg.whack_list & LIST_PUBKEYS)
    {
	list_public_keys(msg.whack_utc);
    }

    if (msg.whack_list & LIST_CERTS)
    {
	list_certs(msg.whack_utc);
    }

    if (msg.whack_list & LIST_CACERTS)
    {
	list_cacerts(msg.whack_utc);
    }

    if (msg.whack_list & LIST_CRLS)
    {
	list_crls(msg.whack_utc);
    }

    if (msg.whack_key)
    {
	/* add a public key */
	struct id keyid;
	err_t ugh = atoid(msg.keyid, &keyid);

	if (ugh != NULL)
	{
	    loglog(RC_BADID, "bad --keyid \"%s\": %s", msg.keyid, ugh);
	}
	else
	{
	    if (!msg.whack_addkey)
		delete_public_keys(&keyid, msg.pubkey_alg);

	    if (msg.keyval.len == 0)
	    {
		struct key_add_continuation *kc
		    = alloc_thing(struct key_add_continuation
			, "key add continuation");
		int wfd = dup_any(whackfd);

		kc->whack_fd = wfd;
		ugh = start_adns_query(&keyid
		    , NULL
		    , T_KEY
		    , key_add_continue
		    , &kc->ac);

		if (ugh != NULL)
		{
		    key_add_ugh(&keyid, ugh);
		    close_any(wfd);
		}
	    }
	    else
	    {
		ugh = add_public_key(&keyid, DAL_LOCAL, msg.pubkey_alg
		    , &msg.keyval, &pubkeys);
		if (ugh != NULL)
		    loglog(RC_LOG_SERIOUS, "%s", ugh);
	    }
	}
    }