/* compare two struct id values */ bool same_id(const struct id *a, const struct id *b) { a = resolve_myid(a); b = resolve_myid(b); if(b->kind == ID_NONE || a->kind==ID_NONE) { return TRUE; /* it's the wildcard */ } if (a->kind != b->kind) return FALSE; switch (a->kind) { case ID_NONE: return TRUE; /* repeat of above for completeness */ case ID_IPV4_ADDR: case ID_IPV6_ADDR: return sameaddr(&a->ip_addr, &b->ip_addr); case ID_FQDN: case ID_USER_FQDN: /* assumptions: * - case should be ignored * - trailing "." should be ignored (even if the only character?) */ { size_t al = a->name.len , bl = b->name.len; while (al > 0 && a->name.ptr[al - 1] == '.') al--; while (bl > 0 && b->name.ptr[bl - 1] == '.') bl--; return al == bl && strncasecmp((char *)a->name.ptr , (char *)b->name.ptr, al) == 0; } case ID_DER_ASN1_DN: return same_dn(a->name, b->name); case ID_KEY_ID: return a->name.len == b->name.len && memcmp(a->name.ptr, b->name.ptr, a->name.len) == 0; default: bad_case(a->kind); } /* NOTREACHED */ return FALSE; }
/* is this a "match anything" id */ bool any_id(const struct id *a) { a = resolve_myid(a); switch (a->kind) { case ID_NONE: return TRUE; /* wildcard */ case ID_IPV4_ADDR: case ID_IPV6_ADDR: return isanyaddr(&a->ip_addr); case ID_FQDN: case ID_USER_FQDN: case ID_DER_ASN1_DN: case ID_KEY_ID: return FALSE; default: bad_case(a->kind); } /* NOTREACHED */ return FALSE; }
/* build an ID payload * Note: no memory is allocated for the body of the payload (tl->ptr). * We assume it will end up being a pointer into a sufficiently * stable datastructure. It only needs to last a short time. */ void build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end) { const struct id *id = resolve_myid(&end->id); zero(hd); zero(tl); hd->isaiid_idtype = id->kind; switch (id->kind) { case ID_NONE: hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr; tl->len = addrbytesptr(&end->host_addr, &tl->ptr); /* sets tl->ptr too */ break; case ID_FQDN: case ID_USER_FQDN: case ID_DER_ASN1_DN: case ID_KEY_ID: *tl = id->name; break; case ID_IPV4_ADDR: case ID_IPV6_ADDR: tl->len = addrbytesptr(&id->ip_addr, &tl->ptr); /* sets tl->ptr too */ break; case ID_NULL: tl->len = 0; tl->ptr = NULL; break; default: bad_case(id->kind); } }
int idtoa(const struct id *id, char *dst, size_t dstlen) { int n; id = resolve_myid(id); switch (id->kind) { case ID_MYID: n = snprintf(dst, dstlen, "%s", "%myid"); break; case ID_FROMCERT: n = snprintf(dst, dstlen, "%s", "%fromcert"); break; case ID_NONE: n = snprintf(dst, dstlen, "%s", "(none)"); break; case ID_IPV4_ADDR: case ID_IPV6_ADDR: if(isanyaddr(&id->ip_addr)) { dst[0]='\0'; strncat(dst, "%any", dstlen); n = strlen(dst); } else { n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1; } break; case ID_FQDN: n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr); break; case ID_USER_FQDN: n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr); break; case ID_DER_ASN1_DN: n = dntoa(dst, dstlen, id->name); break; case ID_KEY_ID: passert(dstlen > 4); dst[0]='@'; dst[1]='#'; dstlen-=2; dst+=2; n = keyidtoa(dst, dstlen, id->name); n+= 2; break; default: n = snprintf(dst, dstlen, "unknown id kind %d", id->kind); break; } /* "Sanitize" string so that log isn't endangered: * replace unprintable characters with '?'. */ if (n > 0) { for ( ; *dst != '\0'; dst++) if (!isprint(*dst)) *dst = '?'; } return n; }
/* compare two struct id values */ bool same_id(const struct id *a, const struct id *b) { a = resolve_myid(a); b = resolve_myid(b); if (b->kind == ID_NONE || a->kind == ID_NONE) { DBG(DBG_PARSING, DBG_log("id type with ID_NONE means wildcard match")); return TRUE; /* it's the wildcard */ } if (a->kind != b->kind) { return FALSE; } switch (a->kind) { case ID_NONE: return TRUE; /* repeat of above for completeness */ case ID_NULL: if (a->kind == b->kind) { DBG(DBG_PARSING, DBG_log("ID_NULL: id kind matches")); return TRUE; } return FALSE; case ID_IPV4_ADDR: case ID_IPV6_ADDR: return sameaddr(&a->ip_addr, &b->ip_addr); case ID_FQDN: case ID_USER_FQDN: /* * assumptions: * - case should be ignored * - trailing "." should be ignored * (even if the only character?) */ { size_t al = a->name.len, bl = b->name.len; while (al > 0 && a->name.ptr[al - 1] == '.') al--; while (bl > 0 && b->name.ptr[bl - 1] == '.') bl--; return al == bl && strncaseeq((char *)a->name.ptr, (char *)b->name.ptr, al); } case ID_FROMCERT: DBG(DBG_CONTROL, DBG_log("same_id() received ID_FROMCERT - unexpected")); /* FALLTHROUGH */ case ID_DER_ASN1_DN: return same_dn(a->name, b->name); case ID_KEY_ID: return a->name.len == b->name.len && memeq(a->name.ptr, b->name.ptr, a->name.len); default: bad_case(a->kind); /* NOTREACHED */ return FALSE; } }