Lines 29-34
Link Here
|
29 |
time I was too famous.'' |
29 |
time I was too famous.'' |
30 |
-- Unknown */ |
30 |
-- Unknown */ |
31 |
#include "ssl_private.h" |
31 |
#include "ssl_private.h" |
|
|
32 |
#include "mod_ssl.h" |
32 |
#include "util_md5.h" |
33 |
#include "util_md5.h" |
33 |
|
34 |
|
34 |
static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); |
35 |
static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); |
Lines 2164-2166
Link Here
|
2164 |
return -1; |
2165 |
return -1; |
2165 |
} |
2166 |
} |
2166 |
#endif |
2167 |
#endif |
|
|
2168 |
|
2169 |
/* |
2170 |
* This callback function is executed when SSL needs to decide what protocols |
2171 |
* to advertise during Next Protocol Negotiation (NPN). It must produce a |
2172 |
* string in wire format -- a sequence of length-prefixed strings -- indicating |
2173 |
* the advertised protocols. Refer to SSL_CTX_set_next_protos_advertised_cb |
2174 |
* in OpenSSL for reference. |
2175 |
*/ |
2176 |
int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data_out, |
2177 |
unsigned int *size_out, void *arg) |
2178 |
{ |
2179 |
conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); |
2180 |
apr_array_header_t *protos; |
2181 |
int num_protos; |
2182 |
unsigned int size; |
2183 |
int i; |
2184 |
unsigned char *data; |
2185 |
unsigned char *start; |
2186 |
|
2187 |
*data_out = NULL; |
2188 |
*size_out = 0; |
2189 |
|
2190 |
/* If the connection object is not available, then there's nothing for us |
2191 |
* to do. */ |
2192 |
if (c == NULL) { |
2193 |
return SSL_TLSEXT_ERR_OK; |
2194 |
} |
2195 |
|
2196 |
/* Invoke our npn_advertise_protos hook, giving other modules a chance to |
2197 |
* add alternate protocol names to advertise. */ |
2198 |
protos = apr_array_make(c->pool, 0, sizeof(char*)); |
2199 |
ssl_run_npn_advertise_protos_hook(c, protos); |
2200 |
num_protos = protos->nelts; |
2201 |
|
2202 |
/* We now have a list of null-terminated strings; we need to concatenate |
2203 |
* them together into a single string, where each protocol name is prefixed |
2204 |
* by its length. First, calculate how long that string will be. */ |
2205 |
size = 0; |
2206 |
for (i = 0; i < num_protos; ++i) { |
2207 |
const char* string = APR_ARRAY_IDX(protos, i, const char*); |
2208 |
unsigned int length = strlen(string); |
2209 |
/* If the protocol name is too long (the length must fit in one byte), |
2210 |
* then log an error and skip it. */ |
2211 |
if (length > 255) { |
2212 |
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, |
2213 |
"SSL NPN protocol name too long (length=%u): %s", |
2214 |
length, string); |
2215 |
continue; |
2216 |
} |
2217 |
/* Leave room for the length prefix (one byte) plus the protocol name |
2218 |
* itself. */ |
2219 |
size += 1 + length; |
2220 |
} |
2221 |
|
2222 |
/* If there is nothing to advertise (either because no modules added |
2223 |
* anything to the protos array, or because all strings added to the array |
2224 |
* were skipped), then we're done. */ |
2225 |
if (size == 0) { |
2226 |
return SSL_TLSEXT_ERR_OK; |
2227 |
} |
2228 |
|
2229 |
/* Now we can build the string. Copy each protocol name string into the |
2230 |
* larger string, prefixed by its length. */ |
2231 |
data = apr_palloc(c->pool, size * sizeof(unsigned char)); |
2232 |
start = data; |
2233 |
for (i = 0; i < num_protos; ++i) { |
2234 |
const char *string = APR_ARRAY_IDX(protos, i, const char*); |
2235 |
apr_size_t length = strlen(string); |
2236 |
*start = (unsigned char)length; |
2237 |
++start; |
2238 |
memcpy(start, string, length * sizeof(unsigned char)); |
2239 |
start += length; |
2240 |
} |
2241 |
|
2242 |
/* Success. */ |
2243 |
apr_array_clear(protos); |
2244 |
*data_out = data; |
2245 |
*size_out = size; |
2246 |
return SSL_TLSEXT_ERR_OK; |
2247 |
} |