/* Helper function to check whether given host name or ip-address matches a specified pattern. Returns FALSE if a match is found, and TRUE otherwise. */ Boolean match_host_id(char *host_name, char *host_ip, char *pattern) { Boolean is_ip_pattern; const char *p; /* if the pattern does not contain any alpha characters then assume that it is a IP address (with possible wildcards), otherwise assume it is a hostname */ if (host_ip) is_ip_pattern = TRUE; else is_ip_pattern = FALSE; for(p = pattern; *p; p++) if (!(isdigit(*p) || *p == '.' || *p == '?' || *p == '*')) { is_ip_pattern = FALSE; break; } if (is_ip_pattern) { return !ssh_match_pattern(host_ip, pattern); } return !ssh_match_pattern(host_name, pattern); }
Boolean ssh_match_pattern(const char *s, const char *pattern) { Boolean escaped = FALSE; for (;;) { escaped = FALSE; /* If at end of pattern, accept if also at end of string. */ if (*pattern == '\0') return (*s == '\0'); /* Process '*'. */ if (*pattern == '\\') { escaped = TRUE; pattern++; } if (*pattern == '*' && !escaped) { /* Skip the asterisk. */ pattern++; /* If at end of pattern, accept immediately. */ if (*pattern == '\0') return TRUE; /* If next character in pattern is known, optimize. */ if (*pattern != '?' && *pattern != '*') { /* Look instances of the next character in pattern, and try to match starting from those. */ for (; *s != '\0'; s++) if (*s == *pattern && ssh_match_pattern(s + 1, pattern + 1)) return TRUE; /* Failed. */ return FALSE; } /* Move ahead one character at a time and try to match at each position. */ for (; *s != '\0'; s++) if (ssh_match_pattern(s, pattern)) return TRUE; /* Failed. */ return FALSE; } /* There must be at least one more character in the string. If we are at the end, fail. */ if (*s == '\0') return FALSE; /* Check if the next character of the string is acceptable. */ if ((*pattern != '?' || (*pattern == '?' && escaped)) && *pattern != *s) return FALSE; /* Move to the next character, both in string and in pattern. */ s++; pattern++; } /*NOTREACHED*/ }
Boolean ssh_pm_ikev2_id_compare_pattern(SshIkev2PayloadID id, SshPmIdentityType type, const char *pattern) { if (!id || !pattern) { SSH_DEBUG(SSH_D_NICETOKNOW, ("both ID and PATTERN are needed")); return FALSE; } switch (id->id_type) { case SSH_IKEV2_ID_TYPE_IPV4_ADDR: case SSH_IKEV2_ID_TYPE_IPV6_ADDR: if (type == SSH_PM_IDENTITY_IP) { SshIpAddrStruct addr[1]; char buf[SSH_IP_ADDR_STRING_SIZE]; SSH_IP_DECODE(addr, id->id_data, id->id_data_size); ssh_ipaddr_print(addr, buf, sizeof(buf)); if (ssh_match_pattern(buf, pattern)) return TRUE; } break; case SSH_IKEV2_ID_TYPE_FQDN: case SSH_IKEV2_ID_TYPE_RFC822_ADDR: if (type == SSH_PM_IDENTITY_RFC822 || type == SSH_PM_IDENTITY_FQDN) if (ssh_match_pattern(id->id_data, pattern)) return TRUE; break; case SSH_IKEV2_ID_TYPE_ASN1_DN: case SSH_IKEV2_ID_TYPE_ASN1_GN: if (type == SSH_PM_IDENTITY_DN) { #ifdef SSHDIST_CERT SshDNStruct dn[1]; Boolean match = FALSE; char *buf; ssh_dn_init(dn); if (ssh_dn_decode_der(id->id_data, id->id_data_size, dn, NULL)) { if (ssh_dn_encode_ldap(dn, &buf)) { if (ssh_match_pattern(buf, pattern)) match = TRUE; ssh_free(buf); } } ssh_dn_clear(dn); return match; #else /* SSHDIST_CERT */ #ifdef WITH_MSCAPI char *buf = NULL; if ((buf = ssh_pm_mscapi_dn_to_str(id)) != NULL) { if (ssh_match_pattern(buf, pattern)) { ssh_free(buf); return TRUE; } } #else /* WITH_MSCAPI */ return FALSE; #endif /* WITH_MSCAPI */ #endif /* SSHDIST_CERT */ } break; case SSH_IKEV2_ID_TYPE_KEY_ID: if (type == SSH_PM_IDENTITY_KEY_ID) { if (ssh_match_pattern(id->id_data, pattern)) return TRUE; } break; } return FALSE; }
/* The URI handler. */ static Boolean proxy_handler(SshHttpServerContext ctx, SshHttpServerConnection conn, SshStream stream, void *context) { const char *method = ssh_http_server_get_method(conn); const char *uri = ssh_http_server_get_uri(conn); SshHttpClientParams params; ProxyRequest *req; SshBuffer error; ProxyCensor *c; SSH_DEBUG(SSH_D_HIGHSTART, ("method=%s, uri=%s", method, uri)); for (c = censor; c; c = c->next) if (ssh_match_pattern(uri, c->pattern)) { SSH_DEBUG(SSH_D_HIGHSTART, ("censored by pattern `%s'", c->pattern)); ssh_http_server_error(conn, 301, SSH_HTTP_HDR_LOCATION, "http://people.ssh.fi/mtr/censor.jpg", SSH_HTTP_HDR_FIELD, "Content-Type", "text/html", SSH_HTTP_HDR_END); ssh_stream_destroy(stream); return TRUE; } memset(¶ms, 0, sizeof(params)); params.http_proxy_url = proxy_url; params.num_redirections = 0; req = ssh_xcalloc(1, sizeof(*req)); req->server = ctx; req->conn = conn; req->server_stream = stream; req->client = ssh_http_client_init(¶ms); if (strcmp(method, "GET") == 0) ssh_http_get(req->client, uri, result_callback, req, SSH_HTTP_HDR_END); else if (strcmp(method, "HEAD") == 0) ssh_http_head(req->client, uri, result_callback, req, SSH_HTTP_HDR_END); else if (strcmp(method, "POST") == 0 || strcmp(method, "PUT") == 0) { SSH_DEBUG(SSH_D_ERROR, ("%s not implemented yet", method)); ssh_xfree(req); error = ssh_buffer_allocate(); ssh_buffer_append_cstrs(error, "<body><h1>Method `", method, "' not implemented yet</h1>\n", NULL); ssh_http_server_send_buffer(conn, error); } else { SSH_DEBUG(SSH_D_ERROR, ("unknown method `%s'", method)); ssh_xfree(req); error = ssh_buffer_allocate(); ssh_buffer_append_cstrs(error, "<body><h1>Unknown method `", method, "'</h1>\n", NULL); ssh_http_server_send_buffer(conn, error); } return TRUE; }