unsigned long be_enum_val::Value () { AST_Expression * enumExpr; AST_Expression::AST_ExprValue * exprValue; enumExpr = constant_value (); if (enumExpr) { exprValue = enumExpr->eval (AST_Expression::EK_positive_int); if (exprValue) { assert (exprValue->et == AST_Expression::EV_ulong); return exprValue->u.eval; } else { assert(pbfalse); } } else { assert(pbfalse); } return 0; }
void sanguis::server::entities::property::constant_change( sanguis::server::entities::property::base &_base, sanguis::server::entities::property::value const &_value ) { sanguis::server::entities::property::constant constant_value( _base.constant() ); constant_value.change( _value ); _base.constant( constant_value ); }
bool ObjectType::is_loaded() const { assert(is_constant(), "must be"); return constant_value()->is_loaded(); }
jobject ObjectType::encoding() const { assert(is_constant(), "must be"); return constant_value()->constant_encoding(); }
/* Offer a set of transforms to the responder in the MSG message. */ int ike_phase_1_initiator_send_SA (struct message *msg) { struct exchange *exchange = msg->exchange; struct ipsec_exch *ie = exchange->data; u_int8_t *proposal = 0, *sa_buf = 0, *saved_nextp, *attr; u_int8_t **transform = 0; size_t transforms_len = 0, proposal_len, sa_len; size_t *transform_len = 0; struct conf_list *conf, *life_conf; struct conf_list_node *xf, *life; int i, value, update_nextp; struct payload *p; struct proto *proto; int group_desc = -1, new_group_desc; /* Get the list of transforms. */ conf = conf_get_list (exchange->policy, "Transforms"); if (!conf) return -1; transform = calloc (conf->cnt, sizeof *transform); if (!transform) { log_error ("ike_phase_1_initiator_send_SA: calloc (%d, %lu) failed", conf->cnt, (unsigned long)sizeof *transform); goto bail_out; } transform_len = calloc (conf->cnt, sizeof *transform_len); if (!transform_len) { log_error ("ike_phase_1_initiator_send_SA: calloc (%d, %lu) failed", conf->cnt, (unsigned long)sizeof *transform_len); goto bail_out; } for (xf = TAILQ_FIRST (&conf->fields), i = 0; i < conf->cnt; i++, xf = TAILQ_NEXT (xf, link)) { /* XXX The sizing needs to be dynamic. */ transform[i] = malloc (ISAKMP_TRANSFORM_SA_ATTRS_OFF + 16 * ISAKMP_ATTR_VALUE_OFF); if (!transform[i]) { log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed", ISAKMP_TRANSFORM_SA_ATTRS_OFF + 16 * ISAKMP_ATTR_VALUE_OFF); goto bail_out; } SET_ISAKMP_TRANSFORM_NO (transform[i], i); SET_ISAKMP_TRANSFORM_ID (transform[i], IPSEC_TRANSFORM_KEY_IKE); SET_ISAKMP_TRANSFORM_RESERVED (transform[i], 0); attr = transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF; if (attribute_set_constant (xf->field, "ENCRYPTION_ALGORITHM", ike_encrypt_cst, IKE_ATTR_ENCRYPTION_ALGORITHM, &attr)) goto bail_out; if (attribute_set_constant (xf->field, "HASH_ALGORITHM", ike_hash_cst, IKE_ATTR_HASH_ALGORITHM, &attr)) goto bail_out; if (attribute_set_constant (xf->field, "AUTHENTICATION_METHOD", ike_auth_cst, IKE_ATTR_AUTHENTICATION_METHOD, &attr)) goto bail_out; if (attribute_set_constant (xf->field, "GROUP_DESCRIPTION", ike_group_desc_cst, IKE_ATTR_GROUP_DESCRIPTION, &attr)) { /* * If no group description exists, try looking for a user-defined * one. */ if (attribute_set_constant (xf->field, "GROUP_TYPE", ike_group_cst, IKE_ATTR_GROUP_TYPE, &attr)) goto bail_out; #if 0 if (attribute_set_bignum (xf->field, "GROUP_PRIME", IKE_ATTR_GROUP_PRIME, &attr)) goto bail_out; if (attribute_set_bignum (xf->field, "GROUP_GENERATOR_2", IKE_ATTR_GROUP_GENERATOR_2, &attr)) goto bail_out; if (attribute_set_bignum (xf->field, "GROUP_GENERATOR_2", IKE_ATTR_GROUP_GENERATOR_2, &attr)) goto bail_out; if (attribute_set_bignum (xf->field, "GROUP_CURVE_A", IKE_ATTR_GROUP_CURVE_A, &attr)) goto bail_out; if (attribute_set_bignum (xf->field, "GROUP_CURVE_B", IKE_ATTR_GROUP_CURVE_B, &attr)) goto bail_out; #endif } /* * Life durations are special, we should be able to specify * several, one per type. */ life_conf = conf_get_list (xf->field, "Life"); if (life_conf) { for (life = TAILQ_FIRST (&life_conf->fields); life; life = TAILQ_NEXT (life, link)) { attribute_set_constant (life->field, "LIFE_TYPE", ike_duration_cst, IKE_ATTR_LIFE_TYPE, &attr); /* XXX Deals with 16 and 32 bit lifetimes only */ value = conf_get_num (life->field, "LIFE_DURATION", 0); if (value) { if (value <= 0xffff) attr = attribute_set_basic (attr, IKE_ATTR_LIFE_DURATION, value); else { value = htonl (value); attr = attribute_set_var (attr, IKE_ATTR_LIFE_DURATION, (u_int8_t *)&value, sizeof value); } } } conf_free_list (life_conf); } attribute_set_constant (xf->field, "PRF", ike_prf_cst, IKE_ATTR_PRF, &attr); value = conf_get_num (xf->field, "KEY_LENGTH", 0); if (value) attr = attribute_set_basic (attr, IKE_ATTR_KEY_LENGTH, value); value = conf_get_num (xf->field, "FIELD_SIZE", 0); if (value) attr = attribute_set_basic (attr, IKE_ATTR_FIELD_SIZE, value); value = conf_get_num (xf->field, "GROUP_ORDER", 0); if (value) attr = attribute_set_basic (attr, IKE_ATTR_GROUP_ORDER, value); /* Record the real transform size. */ transforms_len += transform_len[i] = attr - transform[i]; /* XXX I don't like exchange-specific stuff in here. */ if (exchange->type == ISAKMP_EXCH_AGGRESSIVE) { /* * Make sure that if a group description is specified, it is * specified for all transforms equally. */ attr = (u_int8_t *)conf_get_str (xf->field, "GROUP_DESCRIPTION"); new_group_desc = attr ? constant_value (ike_group_desc_cst, (char *)attr) : 0; if (group_desc == -1) group_desc = new_group_desc; else if (group_desc != new_group_desc) { log_print ("ike_phase_1_initiator_send_SA: " "differing group descriptions in a proposal"); goto bail_out; } } /* We need to check that we actually support our configuration. */ if (attribute_map (transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF, transform_len[i] - ISAKMP_TRANSFORM_SA_ATTRS_OFF, exchange->doi->is_attribute_incompatible, msg)) { log_print ("ike_phase_1_initiator_send_SA: " "section [%s] has unsupported attribute(s)", xf->field); goto bail_out; } } /* XXX I don't like exchange-specific stuff in here. */ if (exchange->type == ISAKMP_EXCH_AGGRESSIVE) ie->group = group_get (group_desc); proposal_len = ISAKMP_PROP_SPI_OFF; proposal = malloc (proposal_len); if (!proposal) { log_error ("ike_phase_1_initiator_send_SA: malloc (%lu) failed", (unsigned long)proposal_len); goto bail_out; } SET_ISAKMP_PROP_NO (proposal, 1); SET_ISAKMP_PROP_PROTO (proposal, ISAKMP_PROTO_ISAKMP); SET_ISAKMP_PROP_SPI_SZ (proposal, 0); SET_ISAKMP_PROP_NTRANSFORMS (proposal, conf->cnt); /* XXX I would like to see this factored out. */ proto = calloc (1, sizeof *proto); if (!proto) { log_error ("ike_phase_1_initiator_send_SA: calloc (1, %lu) failed", (unsigned long)sizeof *proto); goto bail_out; } proto->no = 1; proto->proto = ISAKMP_PROTO_ISAKMP; proto->sa = TAILQ_FIRST (&exchange->sa_list); TAILQ_INSERT_TAIL (&TAILQ_FIRST (&exchange->sa_list)->protos, proto, link); sa_len = ISAKMP_SA_SIT_OFF + IPSEC_SIT_SIT_LEN; sa_buf = malloc (sa_len); if (!sa_buf) { log_error ("ike_phase_1_initiator_send_SA: malloc (%lu) failed", (unsigned long)sa_len); goto bail_out; } SET_ISAKMP_SA_DOI (sa_buf, IPSEC_DOI_IPSEC); SET_IPSEC_SIT_SIT (sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY); /* * Add the payloads. As this is a SA, we need to recompute the * lengths of the payloads containing others. */ if (message_add_payload (msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1)) goto bail_out; SET_ISAKMP_GEN_LENGTH (sa_buf, sa_len + proposal_len + transforms_len); sa_buf = 0; saved_nextp = msg->nextp; if (message_add_payload (msg, ISAKMP_PAYLOAD_PROPOSAL, proposal, proposal_len, 0)) goto bail_out; SET_ISAKMP_GEN_LENGTH (proposal, proposal_len + transforms_len); proposal = 0; update_nextp = 0; for (i = 0; i < conf->cnt; i++) { if (message_add_payload (msg, ISAKMP_PAYLOAD_TRANSFORM, transform[i], transform_len[i], update_nextp)) goto bail_out; update_nextp = 1; transform[i] = 0; } msg->nextp = saved_nextp; /* Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len. */ ie->sa_i_b_len = sa_len + proposal_len + transforms_len - ISAKMP_GEN_SZ; ie->sa_i_b = malloc (ie->sa_i_b_len); if (!ie->sa_i_b) { log_error ("ike_phase_1_initiator_send_SA: malloc (%lu) failed", (unsigned long)ie->sa_i_b_len); goto bail_out; } memcpy (ie->sa_i_b, TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA])->p + ISAKMP_GEN_SZ, sa_len - ISAKMP_GEN_SZ); memcpy (ie->sa_i_b + sa_len - ISAKMP_GEN_SZ, TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL])->p, proposal_len); transforms_len = 0; for (i = 0, p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); i < conf->cnt; i++, p = TAILQ_NEXT (p, link)) { memcpy (ie->sa_i_b + sa_len + proposal_len + transforms_len - ISAKMP_GEN_SZ, p->p, transform_len[i]); transforms_len += transform_len[i]; } conf_free_list (conf); free (transform); free (transform_len); return 0; bail_out: if (sa_buf) free (sa_buf); if (proposal) free (proposal); if (transform) { for (i = 0; i < conf->cnt; i++) if (transform[i]) free (transform[i]); free (transform); } if (transform_len) free (transform_len); conf_free_list (conf); return -1; }
/* * Look at the attribute of type TYPE, located at VALUE for LEN bytes forward. * The VVS argument holds a validation state kept across invocations. * If the attribute is unacceptable to use, return non-zero, otherwise zero. */ static int attribute_unacceptable (u_int16_t type, u_int8_t *value, u_int16_t len, void *vvs) { struct validation_state *vs = vvs; struct conf_list *life_conf; struct conf_list_node *xf = vs->xf, *life; char *tag = constant_lookup (ike_attr_cst, type); char *str; struct constant_map *map; struct attr_node *node; int rv; if (!tag) { LOG_DBG ((LOG_NEGOTIATION, 60, "attribute_unacceptable: attribute type %d not known", type)); return 1; } switch (type) { case IKE_ATTR_ENCRYPTION_ALGORITHM: case IKE_ATTR_HASH_ALGORITHM: case IKE_ATTR_AUTHENTICATION_METHOD: case IKE_ATTR_GROUP_DESCRIPTION: case IKE_ATTR_GROUP_TYPE: case IKE_ATTR_PRF: str = conf_get_str (xf->field, tag); if (!str) { /* This attribute does not exist in this policy. */ LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: attr %s does not exist in %s", tag, xf->field)); return 1; } map = constant_link_lookup (ike_attr_cst, type); if (!map) return 1; if ((constant_value (map, str) == decode_16 (value)) || (!strcmp (str, "ANY"))) { /* Mark this attribute as seen. */ node = malloc (sizeof *node); if (!node) { log_error ("attribute_unacceptable: malloc (%lu) failed", (unsigned long)sizeof *node); return 1; } node->type = type; LIST_INSERT_HEAD (&vs->attrs, node, link); return 0; } LOG_DBG ((LOG_NEGOTIATION, 30, "attribute_unacceptable: %s: got '%s', expected '%s'", tag, constant_name (map, decode_16 (value)), str)); return 1; case IKE_ATTR_GROUP_PRIME: case IKE_ATTR_GROUP_GENERATOR_1: case IKE_ATTR_GROUP_GENERATOR_2: case IKE_ATTR_GROUP_CURVE_A: case IKE_ATTR_GROUP_CURVE_B: /* XXX Bignums not handled yet. */ return 1; case IKE_ATTR_LIFE_TYPE: case IKE_ATTR_LIFE_DURATION: life_conf = conf_get_list (xf->field, "Life"); if (life_conf && !strcmp (conf_get_str (xf->field, "Life"), "ANY")) return 0; rv = 1; if (!life_conf) { /* Life attributes given, but not in our policy. */ LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: " "received unexpected life attribute")); return 1; } /* * Each lifetime type must match, otherwise we turn the proposal down. * In order to do this we need to find the specific section of our * policy's "Life" list and match its duration */ switch (type) { case IKE_ATTR_LIFE_TYPE: for (life = TAILQ_FIRST (&life_conf->fields); life; life = TAILQ_NEXT (life, link)) { str = conf_get_str (life->field, "LIFE_TYPE"); if (!str) { LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: " "section [%s] has no LIFE_TYPE", life->field)); continue; } /* * If this is the type we are looking at, save a pointer * to this section in vs->life. */ if (constant_value (ike_duration_cst, str) == decode_16 (value)) { vs->life = strdup (life->field); rv = 0; goto bail_out; } } LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: unrecognized LIFE_TYPE %d", decode_16 (value))); vs->life = 0; break; case IKE_ATTR_LIFE_DURATION: if (!vs->life) { LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: " "LIFE_DURATION without LIFE_TYPE")); rv = 1; goto bail_out; } str = conf_get_str (vs->life, "LIFE_DURATION"); if (str) { if (!strcmp (str, "ANY")) rv = 0; else rv = !conf_match_num (vs->life, "LIFE_DURATION", len == 4 ? decode_32 (value) : decode_16 (value)); } else { LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: " "section [%s] has no LIFE_DURATION", vs->life)); rv = 1; } free (vs->life); vs->life = 0; break; } bail_out: conf_free_list (life_conf); return rv; case IKE_ATTR_KEY_LENGTH: case IKE_ATTR_FIELD_SIZE: case IKE_ATTR_GROUP_ORDER: if (conf_match_num (xf->field, tag, decode_16 (value))) { /* Mark this attribute as seen. */ node = malloc (sizeof *node); if (!node) { log_error ("attribute_unacceptable: malloc (%lu) failed", (unsigned long)sizeof *node); return 1; } node->type = type; LIST_INSERT_HEAD (&vs->attrs, node, link); return 0; } return 1; } return 1; }
/* Validate a proposal inside SA according to EXCHANGE's policy. */ static int ike_phase_1_validate_prop (struct exchange *exchange, struct sa *sa, struct sa *isakmp_sa) { struct conf_list *conf, *tags; struct conf_list_node *xf, *tag; struct proto *proto; struct validation_state vs; struct attr_node *node, *next_node; /* Get the list of transforms. */ conf = conf_get_list (exchange->policy, "Transforms"); if (!conf) return 0; for (xf = TAILQ_FIRST (&conf->fields); xf; xf = TAILQ_NEXT (xf, link)) { for (proto = TAILQ_FIRST (&sa->protos); proto; proto = TAILQ_NEXT (proto, link)) { /* Mark all attributes in our policy as unseen. */ LIST_INIT (&vs.attrs); vs.xf = xf; vs.life = 0; if (attribute_map (proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF, GET_ISAKMP_GEN_LENGTH (proto->chosen->p) - ISAKMP_TRANSFORM_SA_ATTRS_OFF, attribute_unacceptable, &vs)) goto try_next; /* Sweep over unseen tags in this section. */ tags = conf_get_tag_list (xf->field); if (tags) { for (tag = TAILQ_FIRST (&tags->fields); tag; tag = TAILQ_NEXT (tag, link)) /* * XXX Should we care about attributes we have, they do not * provide? */ for (node = LIST_FIRST (&vs.attrs); node; node = next_node) { next_node = LIST_NEXT (node, link); if (node->type == constant_value (ike_attr_cst, tag->field)) { LIST_REMOVE (node, link); free (node); } } conf_free_list (tags); } /* Are there leftover tags in this section? */ node = LIST_FIRST (&vs.attrs); if (node) goto try_next; } /* All protocols were OK, we succeeded. */ LOG_DBG ((LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: success")); conf_free_list (conf); if (vs.life) free (vs.life); return 1; try_next: /* Are there leftover tags in this section? */ node = LIST_FIRST (&vs.attrs); while (node) { LIST_REMOVE (node, link); free (node); node = LIST_FIRST (&vs.attrs); } if (vs.life) free (vs.life); } LOG_DBG ((LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: failure")); conf_free_list (conf); return 0; }
ciType* InstanceConstant::exact_type() const { ciObject* c = constant_value(); return (c != NULL && !c->is_null_object()) ? c->klass() : NULL; }