static ZSockAddr * z_dispatch_iface_to_sa(gint family, void *addr, guint16 port) { gchar buf[16]; switch (family) { case AF_INET: z_inet_ntoa(buf, sizeof(buf), *((struct in_addr *) addr)); return z_sockaddr_inet_new(buf, port); default: g_assert_not_reached(); break; } return NULL; }
gboolean z_proxy_ssl_host_iface_check_name_method(ZProxyHostIface *s, const gchar *host_name, gchar *reason_buf, gsize reason_len) { ZProxySslHostIface *self = Z_CAST(s, ZProxySslHostIface); gint ext_ndx; gboolean found = FALSE, result = FALSE; gchar pattern_buf[256]; if (self->hostname_checked) return self->hostname_check_result; pattern_buf[0] = 0; ext_ndx = X509_get_ext_by_NID(self->server_cert, NID_subject_alt_name, -1); if (ext_ndx >= 0) { /* ok, there's a subjectAltName extension, check that */ X509_EXTENSION *ext; STACK_OF(GENERAL_NAME) *alt_names; GENERAL_NAME *gen_name; ext = X509_get_ext(self->server_cert, ext_ndx); alt_names = X509V3_EXT_d2i(ext); if (alt_names) { gint num, i; num = sk_GENERAL_NAME_num(alt_names); for (i = 0; i < num; i++) { gen_name = sk_GENERAL_NAME_value(alt_names, i); if (gen_name->type == GEN_DNS) { guchar *dnsname = ASN1_STRING_data(gen_name->d.dNSName); guint dnsname_len = ASN1_STRING_length(gen_name->d.dNSName); if (dnsname_len > sizeof(pattern_buf) - 1) { found = TRUE; result = FALSE; break; } memcpy(pattern_buf, dnsname, dnsname_len); pattern_buf[dnsname_len] = 0; /* we have found a DNS name as alternative subject name */ found = TRUE; result = z_proxy_ssl_host_iface_check_wildcard(s->owner, host_name, pattern_buf); break; } else if (gen_name->type == GEN_IPADD) { z_inet_ntoa(pattern_buf, sizeof(pattern_buf), *(struct in_addr *) gen_name->d.iPAddress->data); found = TRUE; result = strcmp(host_name, pattern_buf) == 0; break; } } sk_GENERAL_NAME_free(alt_names); } } if (!found) { /* hmm. there was no subjectAltName (this is deprecated, but still * widely used), look up the Subject, most specific CN */ X509_NAME *name; name = X509_get_subject_name(self->server_cert); if (X509_NAME_get_text_by_NID(name, NID_commonName, pattern_buf, sizeof(pattern_buf)) != -1) { result = z_proxy_ssl_host_iface_check_wildcard(s->owner, host_name, pattern_buf); } } if (!result && reason_buf) { g_snprintf(reason_buf, reason_len, "Certificate does not belong to target host (certificate: %s, host %s)", pattern_buf, host_name); } self->hostname_checked = TRUE; self->hostname_check_result = result; return result; }
gchar * z_dispatch_bind_format(ZDispatchBind *self, gchar *buf, gsize buflen) { gchar sabuf[MAX_SOCKADDR_STRING]; gchar ipbuf[16]; switch (self->type) { case ZD_BIND_SOCKADDR: g_snprintf(buf, buflen, "SA(proto=%d,addr=%s)", self->protocol, z_sockaddr_format(self->sa.addr, sabuf, sizeof(sabuf))); break; case ZD_BIND_IFACE: /* FIXME: preferred IP should be formatted according to family */ g_snprintf(buf, buflen, "IFACE(proto=%d,iface=%s,ip=%s,port=%d,family=%d)", self->protocol, self->iface.iface, z_inet_ntoa(ipbuf, sizeof(ipbuf), self->iface.ip4), self->iface.port, self->iface.family); break; case ZD_BIND_IFACE_GROUP: g_snprintf(buf, buflen, "IFGROUP(proto=%d,iface_group=0x%x,port=%d,family=%d)", self->protocol, self->iface_group.group, self->iface_group.port, self->iface_group.family); break; default: g_assert_not_reached(); } return buf; }