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