]> granicus.if.org Git - apache/blob - modules/http2/h2_h2.c
Backport
[apache] / modules / http2 / h2_h2.c
1 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <assert.h>
17
18 #include <apr_strings.h>
19 #include <apr_optional.h>
20 #include <apr_optional_hooks.h>
21
22 #include <httpd.h>
23 #include <http_core.h>
24 #include <http_config.h>
25 #include <http_connection.h>
26 #include <http_protocol.h>
27 #include <http_request.h>
28 #include <http_log.h>
29
30 #include "mod_ssl.h"
31
32 #include "mod_http2.h"
33 #include "h2_private.h"
34
35 #include "h2_stream.h"
36 #include "h2_task.h"
37 #include "h2_config.h"
38 #include "h2_ctx.h"
39 #include "h2_conn.h"
40 #include "h2_request.h"
41 #include "h2_session.h"
42 #include "h2_util.h"
43 #include "h2_h2.h"
44 #include "mod_http2.h"
45
46 const char *h2_tls_protos[] = {
47     "h2", NULL
48 };
49
50 const char *h2_clear_protos[] = {
51     "h2c", NULL
52 };
53
54 const char *H2_MAGIC_TOKEN = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
55
56 /*******************************************************************************
57  * The optional mod_ssl functions we need. 
58  */
59 static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *opt_ssl_engine_disable;
60 static APR_OPTIONAL_FN_TYPE(ssl_is_https) *opt_ssl_is_https;
61 static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *opt_ssl_var_lookup;
62
63
64 /*******************************************************************************
65  * HTTP/2 error stuff
66  */
67 static const char *h2_err_descr[] = {
68     "no error",                    /* 0x0 */
69     "protocol error",
70     "internal error",
71     "flow control error",
72     "settings timeout",
73     "stream closed",               /* 0x5 */
74     "frame size error",
75     "refused stream",
76     "cancel",
77     "compression error",
78     "connect error",               /* 0xa */
79     "enhance your calm",
80     "inadequate security",
81     "http/1.1 required",
82 };
83
84 const char *h2_h2_err_description(unsigned int h2_error)
85 {
86     if (h2_error < (sizeof(h2_err_descr)/sizeof(h2_err_descr[0]))) {
87         return h2_err_descr[h2_error];
88     }
89     return "unknown http/2 error code";
90 }
91
92 /*******************************************************************************
93  * Check connection security requirements of RFC 7540
94  */
95
96 /*
97  * Black Listed Ciphers from RFC 7549 Appendix A
98  *
99  */
100 static const char *RFC7540_names[] = {
101     /* ciphers with NULL encrpytion */
102     "NULL-MD5",                         /* TLS_NULL_WITH_NULL_NULL */
103     /* same */                          /* TLS_RSA_WITH_NULL_MD5 */
104     "NULL-SHA",                         /* TLS_RSA_WITH_NULL_SHA */
105     "NULL-SHA256",                      /* TLS_RSA_WITH_NULL_SHA256 */
106     "PSK-NULL-SHA",                     /* TLS_PSK_WITH_NULL_SHA */
107     "DHE-PSK-NULL-SHA",                 /* TLS_DHE_PSK_WITH_NULL_SHA */
108     "RSA-PSK-NULL-SHA",                 /* TLS_RSA_PSK_WITH_NULL_SHA */
109     "PSK-NULL-SHA256",                  /* TLS_PSK_WITH_NULL_SHA256 */
110     "PSK-NULL-SHA384",                  /* TLS_PSK_WITH_NULL_SHA384 */
111     "DHE-PSK-NULL-SHA256",              /* TLS_DHE_PSK_WITH_NULL_SHA256 */
112     "DHE-PSK-NULL-SHA384",              /* TLS_DHE_PSK_WITH_NULL_SHA384 */
113     "RSA-PSK-NULL-SHA256",              /* TLS_RSA_PSK_WITH_NULL_SHA256 */
114     "RSA-PSK-NULL-SHA384",              /* TLS_RSA_PSK_WITH_NULL_SHA384 */
115     "ECDH-ECDSA-NULL-SHA",              /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
116     "ECDHE-ECDSA-NULL-SHA",             /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
117     "ECDH-RSA-NULL-SHA",                /* TLS_ECDH_RSA_WITH_NULL_SHA */
118     "ECDHE-RSA-NULL-SHA",               /* TLS_ECDHE_RSA_WITH_NULL_SHA */
119     "AECDH-NULL-SHA",                   /* TLS_ECDH_anon_WITH_NULL_SHA */
120     "ECDHE-PSK-NULL-SHA",               /* TLS_ECDHE_PSK_WITH_NULL_SHA */
121     "ECDHE-PSK-NULL-SHA256",            /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
122     "ECDHE-PSK-NULL-SHA384",            /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
123     
124     /* DES/3DES ciphers */
125     "PSK-3DES-EDE-CBC-SHA",             /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
126     "DHE-PSK-3DES-EDE-CBC-SHA",         /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
127     "RSA-PSK-3DES-EDE-CBC-SHA",         /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
128     "ECDH-ECDSA-DES-CBC3-SHA",          /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
129     "ECDHE-ECDSA-DES-CBC3-SHA",         /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
130     "ECDH-RSA-DES-CBC3-SHA",            /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
131     "ECDHE-RSA-DES-CBC3-SHA",           /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
132     "AECDH-DES-CBC3-SHA",               /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
133     "SRP-3DES-EDE-CBC-SHA",             /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
134     "SRP-RSA-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
135     "SRP-DSS-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
136     "ECDHE-PSK-3DES-EDE-CBC-SHA",       /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
137     "DES-CBC-SHA",                      /* TLS_RSA_WITH_DES_CBC_SHA */
138     "DES-CBC3-SHA",                     /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
139     "DHE-DSS-DES-CBC3-SHA",             /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
140     "DHE-RSA-DES-CBC-SHA",              /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
141     "DHE-RSA-DES-CBC3-SHA",             /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
142     "ADH-DES-CBC-SHA",                  /* TLS_DH_anon_WITH_DES_CBC_SHA */
143     "ADH-DES-CBC3-SHA",                 /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
144     "EXP-DH-DSS-DES-CBC-SHA",           /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
145     "DH-DSS-DES-CBC-SHA",               /* TLS_DH_DSS_WITH_DES_CBC_SHA */
146     "DH-DSS-DES-CBC3-SHA",              /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
147     "EXP-DH-RSA-DES-CBC-SHA",           /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
148     "DH-RSA-DES-CBC-SHA",               /* TLS_DH_RSA_WITH_DES_CBC_SHA */
149     "DH-RSA-DES-CBC3-SHA",              /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
150
151     /* blacklisted EXPORT ciphers */
152     "EXP-RC4-MD5",                      /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
153     "EXP-RC2-CBC-MD5",                  /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
154     "EXP-DES-CBC-SHA",                  /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
155     "EXP-DHE-DSS-DES-CBC-SHA",          /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
156     "EXP-DHE-RSA-DES-CBC-SHA",          /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
157     "EXP-ADH-DES-CBC-SHA",              /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
158     "EXP-ADH-RC4-MD5",                  /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
159
160     /* blacklisted RC4 encryption */
161     "RC4-MD5",                          /* TLS_RSA_WITH_RC4_128_MD5 */
162     "RC4-SHA",                          /* TLS_RSA_WITH_RC4_128_SHA */
163     "ADH-RC4-MD5",                      /* TLS_DH_anon_WITH_RC4_128_MD5 */
164     "KRB5-RC4-SHA",                     /* TLS_KRB5_WITH_RC4_128_SHA */
165     "KRB5-RC4-MD5",                     /* TLS_KRB5_WITH_RC4_128_MD5 */
166     "EXP-KRB5-RC4-SHA",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
167     "EXP-KRB5-RC4-MD5",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
168     "PSK-RC4-SHA",                      /* TLS_PSK_WITH_RC4_128_SHA */
169     "DHE-PSK-RC4-SHA",                  /* TLS_DHE_PSK_WITH_RC4_128_SHA */
170     "RSA-PSK-RC4-SHA",                  /* TLS_RSA_PSK_WITH_RC4_128_SHA */
171     "ECDH-ECDSA-RC4-SHA",               /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
172     "ECDHE-ECDSA-RC4-SHA",              /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
173     "ECDH-RSA-RC4-SHA",                 /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
174     "ECDHE-RSA-RC4-SHA",                /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
175     "AECDH-RC4-SHA",                    /* TLS_ECDH_anon_WITH_RC4_128_SHA */
176     "ECDHE-PSK-RC4-SHA",                /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
177
178     /* blacklisted AES128 encrpytion ciphers */
179     "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA */
180     "DH-DSS-AES128-SHA",                /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
181     "DH-RSA-AES128-SHA",                /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
182     "DHE-DSS-AES128-SHA",               /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
183     "DHE-RSA-AES128-SHA",               /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
184     "ADH-AES128-SHA",                   /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
185     "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
186     "DH-DSS-AES128-SHA256",             /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
187     "DH-RSA-AES128-SHA256",             /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
188     "DHE-DSS-AES128-SHA256",            /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
189     "DHE-RSA-AES128-SHA256",            /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
190     "ECDH-ECDSA-AES128-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
191     "ECDHE-ECDSA-AES128-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
192     "ECDH-RSA-AES128-SHA",              /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
193     "ECDHE-RSA-AES128-SHA",             /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
194     "AECDH-AES128-SHA",                 /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
195     "ECDHE-ECDSA-AES128-SHA256",        /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
196     "ECDH-ECDSA-AES128-SHA256",         /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
197     "ECDHE-RSA-AES128-SHA256",          /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
198     "ECDH-RSA-AES128-SHA256",           /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
199     "ADH-AES128-SHA256",                /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
200     "PSK-AES128-CBC-SHA",               /* TLS_PSK_WITH_AES_128_CBC_SHA */
201     "DHE-PSK-AES128-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
202     "RSA-PSK-AES128-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
203     "PSK-AES128-CBC-SHA256",            /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
204     "DHE-PSK-AES128-CBC-SHA256",        /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
205     "RSA-PSK-AES128-CBC-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
206     "ECDHE-PSK-AES128-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
207     "ECDHE-PSK-AES128-CBC-SHA256",      /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
208     "AES128-CCM",                       /* TLS_RSA_WITH_AES_128_CCM */
209     "AES128-CCM8",                      /* TLS_RSA_WITH_AES_128_CCM_8 */
210     "PSK-AES128-CCM",                   /* TLS_PSK_WITH_AES_128_CCM */
211     "PSK-AES128-CCM8",                  /* TLS_PSK_WITH_AES_128_CCM_8 */
212     "AES128-GCM-SHA256",                /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
213     "DH-RSA-AES128-GCM-SHA256",         /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
214     "DH-DSS-AES128-GCM-SHA256",         /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
215     "ADH-AES128-GCM-SHA256",            /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
216     "PSK-AES128-GCM-SHA256",            /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
217     "RSA-PSK-AES128-GCM-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
218     "ECDH-ECDSA-AES128-GCM-SHA256",     /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
219     "ECDH-RSA-AES128-GCM-SHA256",       /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
220     "SRP-AES-128-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
221     "SRP-RSA-AES-128-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
222     "SRP-DSS-AES-128-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
223     
224     /* blacklisted AES256 encrpytion ciphers */
225     "AES256-SHA",                       /* TLS_RSA_WITH_AES_256_CBC_SHA */
226     "DH-DSS-AES256-SHA",                /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
227     "DH-RSA-AES256-SHA",                /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
228     "DHE-DSS-AES256-SHA",               /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
229     "DHE-RSA-AES256-SHA",               /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
230     "ADH-AES256-SHA",                   /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
231     "AES256-SHA256",                    /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
232     "DH-DSS-AES256-SHA256",             /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
233     "DH-RSA-AES256-SHA256",             /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
234     "DHE-DSS-AES256-SHA256",            /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
235     "DHE-RSA-AES256-SHA256",            /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
236     "ADH-AES256-SHA256",                /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
237     "ECDH-ECDSA-AES256-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
238     "ECDHE-ECDSA-AES256-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
239     "ECDH-RSA-AES256-SHA",              /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
240     "ECDHE-RSA-AES256-SHA",             /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
241     "AECDH-AES256-SHA",                 /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
242     "ECDHE-ECDSA-AES256-SHA384",        /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
243     "ECDH-ECDSA-AES256-SHA384",         /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
244     "ECDHE-RSA-AES256-SHA384",          /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
245     "ECDH-RSA-AES256-SHA384",           /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
246     "PSK-AES256-CBC-SHA",               /* TLS_PSK_WITH_AES_256_CBC_SHA */
247     "DHE-PSK-AES256-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
248     "RSA-PSK-AES256-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
249     "PSK-AES256-CBC-SHA384",            /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
250     "DHE-PSK-AES256-CBC-SHA384",        /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
251     "RSA-PSK-AES256-CBC-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
252     "ECDHE-PSK-AES256-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
253     "ECDHE-PSK-AES256-CBC-SHA384",      /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
254     "SRP-AES-256-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
255     "SRP-RSA-AES-256-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
256     "SRP-DSS-AES-256-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
257     "AES256-CCM",                       /* TLS_RSA_WITH_AES_256_CCM */
258     "AES256-CCM8",                      /* TLS_RSA_WITH_AES_256_CCM_8 */
259     "PSK-AES256-CCM",                   /* TLS_PSK_WITH_AES_256_CCM */
260     "PSK-AES256-CCM8",                  /* TLS_PSK_WITH_AES_256_CCM_8 */
261     "AES256-GCM-SHA384",                /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
262     "DH-RSA-AES256-GCM-SHA384",         /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
263     "DH-DSS-AES256-GCM-SHA384",         /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
264     "ADH-AES256-GCM-SHA384",            /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
265     "PSK-AES256-GCM-SHA384",            /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
266     "RSA-PSK-AES256-GCM-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
267     "ECDH-ECDSA-AES256-GCM-SHA384",     /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
268     "ECDH-RSA-AES256-GCM-SHA384",       /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
269     
270     /* blacklisted CAMELLIA128 encrpytion ciphers */
271     "CAMELLIA128-SHA",                  /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
272     "DH-DSS-CAMELLIA128-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
273     "DH-RSA-CAMELLIA128-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
274     "DHE-DSS-CAMELLIA128-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
275     "DHE-RSA-CAMELLIA128-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
276     "ADH-CAMELLIA128-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
277     "ECDHE-ECDSA-CAMELLIA128-SHA256",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
278     "ECDH-ECDSA-CAMELLIA128-SHA256",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
279     "ECDHE-RSA-CAMELLIA128-SHA256",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
280     "ECDH-RSA-CAMELLIA128-SHA256",      /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
281     "PSK-CAMELLIA128-SHA256",           /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
282     "DHE-PSK-CAMELLIA128-SHA256",       /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
283     "RSA-PSK-CAMELLIA128-SHA256",       /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
284     "ECDHE-PSK-CAMELLIA128-SHA256",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
285     "CAMELLIA128-GCM-SHA256",           /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
286     "DH-RSA-CAMELLIA128-GCM-SHA256",    /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
287     "DH-DSS-CAMELLIA128-GCM-SHA256",    /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
288     "ADH-CAMELLIA128-GCM-SHA256",       /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
289     "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
290     "ECDH-RSA-CAMELLIA128-GCM-SHA256",  /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
291     "PSK-CAMELLIA128-GCM-SHA256",       /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
292     "RSA-PSK-CAMELLIA128-GCM-SHA256",   /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
293     "CAMELLIA128-SHA256",               /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
294     "DH-DSS-CAMELLIA128-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
295     "DH-RSA-CAMELLIA128-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
296     "DHE-DSS-CAMELLIA128-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
297     "DHE-RSA-CAMELLIA128-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
298     "ADH-CAMELLIA128-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
299     
300     /* blacklisted CAMELLIA256 encrpytion ciphers */
301     "CAMELLIA256-SHA",                  /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
302     "DH-RSA-CAMELLIA256-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
303     "DH-DSS-CAMELLIA256-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
304     "DHE-DSS-CAMELLIA256-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
305     "DHE-RSA-CAMELLIA256-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
306     "ADH-CAMELLIA256-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
307     "ECDHE-ECDSA-CAMELLIA256-SHA384",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
308     "ECDH-ECDSA-CAMELLIA256-SHA384",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
309     "ECDHE-RSA-CAMELLIA256-SHA384",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
310     "ECDH-RSA-CAMELLIA256-SHA384",      /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
311     "PSK-CAMELLIA256-SHA384",           /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
312     "DHE-PSK-CAMELLIA256-SHA384",       /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
313     "RSA-PSK-CAMELLIA256-SHA384",       /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
314     "ECDHE-PSK-CAMELLIA256-SHA384",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
315     "CAMELLIA256-SHA256",               /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
316     "DH-DSS-CAMELLIA256-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
317     "DH-RSA-CAMELLIA256-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
318     "DHE-DSS-CAMELLIA256-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
319     "DHE-RSA-CAMELLIA256-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
320     "ADH-CAMELLIA256-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
321     "CAMELLIA256-GCM-SHA384",           /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
322     "DH-RSA-CAMELLIA256-GCM-SHA384",    /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
323     "DH-DSS-CAMELLIA256-GCM-SHA384",    /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
324     "ADH-CAMELLIA256-GCM-SHA384",       /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
325     "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
326     "ECDH-RSA-CAMELLIA256-GCM-SHA384",  /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
327     "PSK-CAMELLIA256-GCM-SHA384",       /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
328     "RSA-PSK-CAMELLIA256-GCM-SHA384",   /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
329     
330     /* The blacklisted ARIA encrpytion ciphers */
331     "ARIA128-SHA256",                   /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
332     "ARIA256-SHA384",                   /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
333     "DH-DSS-ARIA128-SHA256",            /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
334     "DH-DSS-ARIA256-SHA384",            /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
335     "DH-RSA-ARIA128-SHA256",            /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
336     "DH-RSA-ARIA256-SHA384",            /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
337     "DHE-DSS-ARIA128-SHA256",           /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
338     "DHE-DSS-ARIA256-SHA384",           /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
339     "DHE-RSA-ARIA128-SHA256",           /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
340     "DHE-RSA-ARIA256-SHA384",           /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
341     "ADH-ARIA128-SHA256",               /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
342     "ADH-ARIA256-SHA384",               /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
343     "ECDHE-ECDSA-ARIA128-SHA256",       /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
344     "ECDHE-ECDSA-ARIA256-SHA384",       /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
345     "ECDH-ECDSA-ARIA128-SHA256",        /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
346     "ECDH-ECDSA-ARIA256-SHA384",        /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
347     "ECDHE-RSA-ARIA128-SHA256",         /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
348     "ECDHE-RSA-ARIA256-SHA384",         /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
349     "ECDH-RSA-ARIA128-SHA256",          /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
350     "ECDH-RSA-ARIA256-SHA384",          /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
351     "ARIA128-GCM-SHA256",               /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
352     "ARIA256-GCM-SHA384",               /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
353     "DH-DSS-ARIA128-GCM-SHA256",        /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
354     "DH-DSS-ARIA256-GCM-SHA384",        /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
355     "DH-RSA-ARIA128-GCM-SHA256",        /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
356     "DH-RSA-ARIA256-GCM-SHA384",        /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
357     "ADH-ARIA128-GCM-SHA256",           /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
358     "ADH-ARIA256-GCM-SHA384",           /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
359     "ECDH-ECDSA-ARIA128-GCM-SHA256",    /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
360     "ECDH-ECDSA-ARIA256-GCM-SHA384",    /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
361     "ECDH-RSA-ARIA128-GCM-SHA256",      /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
362     "ECDH-RSA-ARIA256-GCM-SHA384",      /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
363     "PSK-ARIA128-SHA256",               /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
364     "PSK-ARIA256-SHA384",               /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
365     "DHE-PSK-ARIA128-SHA256",           /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
366     "DHE-PSK-ARIA256-SHA384",           /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
367     "RSA-PSK-ARIA128-SHA256",           /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
368     "RSA-PSK-ARIA256-SHA384",           /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
369     "ARIA128-GCM-SHA256",               /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
370     "ARIA256-GCM-SHA384",               /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
371     "RSA-PSK-ARIA128-GCM-SHA256",       /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
372     "RSA-PSK-ARIA256-GCM-SHA384",       /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
373     "ECDHE-PSK-ARIA128-SHA256",         /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
374     "ECDHE-PSK-ARIA256-SHA384",         /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
375
376     /* blacklisted SEED encryptions */
377     "SEED-SHA",                         /*TLS_RSA_WITH_SEED_CBC_SHA */
378     "DH-DSS-SEED-SHA",                  /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
379     "DH-RSA-SEED-SHA",                  /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
380     "DHE-DSS-SEED-SHA",                 /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
381     "DHE-RSA-SEED-SHA",                 /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */               
382     "ADH-SEED-SHA",                     /* TLS_DH_anon_WITH_SEED_CBC_SHA */
383
384     /* blacklisted KRB5 ciphers */
385     "KRB5-DES-CBC-SHA",                 /* TLS_KRB5_WITH_DES_CBC_SHA */
386     "KRB5-DES-CBC3-SHA",                /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
387     "KRB5-IDEA-CBC-SHA",                /* TLS_KRB5_WITH_IDEA_CBC_SHA */
388     "KRB5-DES-CBC-MD5",                 /* TLS_KRB5_WITH_DES_CBC_MD5 */
389     "KRB5-DES-CBC3-MD5",                /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
390     "KRB5-IDEA-CBC-MD5",                /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
391     "EXP-KRB5-DES-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
392     "EXP-KRB5-DES-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
393     "EXP-KRB5-RC2-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
394     "EXP-KRB5-RC2-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
395   
396     /* blacklisted exoticas */
397     "DHE-DSS-CBC-SHA",                  /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
398     "IDEA-CBC-SHA",                     /* TLS_RSA_WITH_IDEA_CBC_SHA */
399     
400     /* not really sure if the following names are correct */
401     "SSL3_CK_SCSV",                     /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
402     "SSL3_CK_FALLBACK_SCSV"
403 };
404 static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
405
406
407 static apr_hash_t *BLCNames;
408
409 static void cipher_init(apr_pool_t *pool)
410 {
411     apr_hash_t *hash = apr_hash_make(pool);
412     const char *source;
413     unsigned int i;
414     
415     source = "rfc7540";
416     for (i = 0; i < RFC7540_names_LEN; ++i) {
417         apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
418     }
419     
420     BLCNames = hash;
421 }
422
423 static int cipher_is_blacklisted(const char *cipher, const char **psource)
424 {   
425     *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
426     return !!*psource;
427 }
428
429 /*******************************************************************************
430  * Hooks for processing incoming connections:
431  * - process_conn take over connection in case of h2
432  */
433 static int h2_h2_process_conn(conn_rec* c);
434 static int h2_h2_pre_close_conn(conn_rec* c);
435 static int h2_h2_post_read_req(request_rec *r);
436
437 /*******************************************************************************
438  * Once per lifetime init, retrieve optional functions
439  */
440 apr_status_t h2_h2_init(apr_pool_t *pool, server_rec *s)
441 {
442     (void)pool;
443     ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "h2_h2, child_init");
444     opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
445     opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
446     opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
447     
448     if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
449         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
450                      APLOGNO(02951) "mod_ssl does not seem to be enabled");
451     }
452     
453     cipher_init(pool);
454     
455     return APR_SUCCESS;
456 }
457
458 int h2_h2_is_tls(conn_rec *c)
459 {
460     return opt_ssl_is_https && opt_ssl_is_https(c);
461 }
462
463 int h2_is_acceptable_connection(conn_rec *c, int require_all) 
464 {
465     int is_tls = h2_h2_is_tls(c);
466     const h2_config *cfg = h2_config_get(c);
467
468     if (is_tls && h2_config_geti(cfg, H2_CONF_MODERN_TLS_ONLY) > 0) {
469         /* Check TLS connection for modern TLS parameters, as defined in
470          * RFC 7540 and https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
471          */
472         apr_pool_t *pool = c->pool;
473         server_rec *s = c->base_server;
474         char *val;
475         
476         if (!opt_ssl_var_lookup) {
477             /* unable to check */
478             return 0;
479         }
480         
481         /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
482          */
483         val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_PROTOCOL");
484         if (val && *val) {
485             if (strncmp("TLS", val, 3) 
486                 || !strcmp("TLSv1", val) 
487                 || !strcmp("TLSv1.1", val)) {
488                 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03050)
489                               "h2_h2(%ld): tls protocol not suitable: %s", 
490                               (long)c->id, val);
491                 return 0;
492             }
493         }
494         else if (require_all) {
495             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03051)
496                           "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
497             return 0;
498         }
499
500         /* Check TLS cipher blacklist
501          */
502         val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_CIPHER");
503         if (val && *val) {
504             const char *source;
505             if (cipher_is_blacklisted(val, &source)) {
506                 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03052)
507                               "h2_h2(%ld): tls cipher %s blacklisted by %s", 
508                               (long)c->id, val, source);
509                 return 0;
510             }
511         }
512         else if (require_all) {
513             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03053)
514                           "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
515             return 0;
516         }
517     }
518     return 1;
519 }
520
521 int h2_allows_h2_direct(conn_rec *c)
522 {
523     const h2_config *cfg = h2_config_get(c);
524     int is_tls = h2_h2_is_tls(c);
525     const char *needed_protocol = is_tls? "h2" : "h2c";
526     int h2_direct = h2_config_geti(cfg, H2_CONF_DIRECT);
527     
528     if (h2_direct < 0) {
529         h2_direct = is_tls? 0 : 1;
530     }
531     return (h2_direct 
532             && ap_is_allowed_protocol(c, NULL, NULL, needed_protocol));
533 }
534
535 int h2_allows_h2_upgrade(conn_rec *c)
536 {
537     const h2_config *cfg = h2_config_get(c);
538     int h2_upgrade = h2_config_geti(cfg, H2_CONF_UPGRADE);
539     
540     return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(c));
541 }
542
543 /*******************************************************************************
544  * Register various hooks
545  */
546 static const char* const mod_ssl[]        = { "mod_ssl.c", NULL};
547 static const char* const mod_reqtimeout[] = { "mod_reqtimeout.c", NULL};
548
549 void h2_h2_register_hooks(void)
550 {
551     /* Our main processing needs to run quite late. Definitely after mod_ssl,
552      * as we need its connection filters, but also before reqtimeout as its
553      * method of timeouts is specific to HTTP/1.1 (as of now).
554      * The core HTTP/1 processing run as REALLY_LAST, so we will have
555      * a chance to take over before it.
556      */
557     ap_hook_process_connection(h2_h2_process_conn, 
558                                mod_ssl, mod_reqtimeout, APR_HOOK_LAST);
559     
560     /* One last chance to properly say goodbye if we have not done so
561      * already. */
562     ap_hook_pre_close_connection(h2_h2_pre_close_conn, NULL, mod_ssl, APR_HOOK_LAST);
563
564     /* With "H2SerializeHeaders On", we install the filter in this hook
565      * that parses the response. This needs to happen before any other post
566      * read function terminates the request with an error. Otherwise we will
567      * never see the response.
568      */
569     ap_hook_post_read_request(h2_h2_post_read_req, NULL, NULL, APR_HOOK_REALLY_FIRST);
570 }
571
572 int h2_h2_process_conn(conn_rec* c)
573 {
574     apr_status_t status;
575     h2_ctx *ctx;
576     
577     if (c->master) {
578         return DECLINED;
579     }
580     
581     ctx = h2_ctx_get(c, 0);
582     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn");
583     if (h2_ctx_is_task(ctx)) {
584         /* our stream pseudo connection */
585         ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "h2_h2, task, declined");
586         return DECLINED;
587     }
588     
589     if (!ctx && c->keepalives == 0) {
590         const char *proto = ap_get_protocol(c);
591         
592         if (APLOGctrace1(c)) {
593             ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn, "
594                           "new connection using protocol '%s', direct=%d, "
595                           "tls acceptable=%d", proto, h2_allows_h2_direct(c), 
596                           h2_is_acceptable_connection(c, 1));
597         }
598         
599         if (!strcmp(AP_PROTOCOL_HTTP1, proto)
600             && h2_allows_h2_direct(c) 
601             && h2_is_acceptable_connection(c, 1)) {
602             /* Fresh connection still is on http/1.1 and H2Direct is enabled. 
603              * Otherwise connection is in a fully acceptable state.
604              * -> peek at the first 24 incoming bytes
605              */
606             apr_bucket_brigade *temp;
607             char *s = NULL;
608             apr_size_t slen;
609             
610             temp = apr_brigade_create(c->pool, c->bucket_alloc);
611             status = ap_get_brigade(c->input_filters, temp,
612                                     AP_MODE_SPECULATIVE, APR_BLOCK_READ, 24);
613             
614             if (status != APR_SUCCESS) {
615                 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, APLOGNO(03054)
616                               "h2_h2, error reading 24 bytes speculative");
617                 apr_brigade_destroy(temp);
618                 return DECLINED;
619             }
620             
621             apr_brigade_pflatten(temp, &s, &slen, c->pool);
622             if ((slen >= 24) && !memcmp(H2_MAGIC_TOKEN, s, 24)) {
623                 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
624                               "h2_h2, direct mode detected");
625                 if (!ctx) {
626                     ctx = h2_ctx_get(c, 1);
627                 }
628                 h2_ctx_protocol_set(ctx, h2_h2_is_tls(c)? "h2" : "h2c");
629             }
630             else {
631                 ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
632                               "h2_h2, not detected in %d bytes: %s", 
633                               (int)slen, s);
634             }
635             
636             apr_brigade_destroy(temp);
637         }
638     }
639
640     if (ctx) {
641         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "process_conn");
642         if (!h2_ctx_session_get(ctx)) {
643             status = h2_conn_setup(ctx, c, NULL);
644             ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, c, "conn_setup");
645             if (status != APR_SUCCESS) {
646                 return status;
647             }
648         }
649         return h2_conn_run(ctx, c);
650     }
651     
652     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, declined");
653     return DECLINED;
654 }
655
656 static int h2_h2_pre_close_conn(conn_rec *c)
657 {
658     h2_ctx *ctx;
659
660     /* slave connection? */
661     if (c->master) {
662         return DECLINED;
663     }
664
665     ctx = h2_ctx_get(c, 0);
666     if (ctx) {
667         /* If the session has been closed correctly already, we will not
668          * fiond a h2_ctx here. The presence indicates that the session
669          * is still ongoing. */
670         return h2_conn_pre_close(ctx, c);
671     }
672     return DECLINED;
673 }
674
675 static int h2_h2_post_read_req(request_rec *r)
676 {
677     /* slave connection? */
678     if (r->connection->master) {
679         h2_ctx *ctx = h2_ctx_rget(r);
680         struct h2_task *task = h2_ctx_get_task(ctx);
681         /* This hook will get called twice on internal redirects. Take care
682          * that we manipulate filters only once. */
683         if (task && !task->filters_set) {
684             ap_filter_t *f;
685             
686             /* setup the correct output filters to process the response
687              * on the proper mod_http2 way. */
688             ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "adding task output filter");
689             if (task->ser_headers) {
690                 ap_add_output_filter("H1_TO_H2_RESP", task, r, r->connection);
691             }
692             else {
693                 /* replace the core http filter that formats response headers
694                  * in HTTP/1 with our own that collects status and headers */
695                 ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
696                 ap_add_output_filter("H2_RESPONSE", task, r, r->connection);
697             }
698             
699             /* trailers processing. Incoming trailers are added to this
700              * request via our h2 input filter, outgoing trailers
701              * in a special h2 out filter. */
702             for (f = r->input_filters; f; f = f->next) {
703                 if (!strcmp("H2_TO_H1", f->frec->name)) {
704                     f->r = r;
705                     break;
706                 }
707             }
708             ap_add_output_filter("H2_TRAILERS", task, r, r->connection);
709             task->filters_set = 1;
710         }
711     }
712     return DECLINED;
713 }
714