Apache HTTPD
tls_util.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <assert.h>
17#include <apr_lib.h>
18#include <apr_file_info.h>
19#include <apr_strings.h>
20
21#include <httpd.h>
22#include <http_core.h>
23#include <http_log.h>
24
25#include <rustls.h>
26
27#include "tls_proto.h"
28#include "tls_util.h"
29
30
31extern module AP_MODULE_DECLARE_DATA tls_module;
33
34
36{
38 d.data = (const unsigned char*)s;
39 d.len = s? strlen(s) : 0;
40 return d;
41}
42
44{
45 tls_data_t copy;
46 copy.data = apr_pmemdup(p, d->data, d->len);
47 copy.len = d->len;
48 return copy;
49}
50
52{
53 tls_data_t *copy;
54 copy = apr_pcalloc(p, sizeof(*copy));
55 *copy = tls_data_assign_copy(p, d);
56 return copy;
57}
58
60{
61 char *s = apr_pcalloc(p, d->len+1);
62 memcpy(s, d->data, d->len);
63 return s;
64}
65
67 apr_pool_t *p, rustls_result rr, const char **perr_descr)
68{
69 if (perr_descr) {
71 apr_size_t len = 0;
72
73 rustls_error(rr, buffer, sizeof(buffer), &len);
75 }
76 return APR_EGENERAL;
77}
78
80 apr_pool_t *p, const char *fpath)
81{
82 apr_finfo_t finfo;
83
84 return (fpath != NULL
86 && finfo.filetype == APR_REG);
87}
88
91{
92 apr_finfo_t finfo;
93 apr_status_t rv;
94 apr_file_t *f = NULL;
95 unsigned char *buffer;
97 const char *err = NULL;
99
101 if (APR_SUCCESS != rv) {
102 err = "cannot stat"; goto cleanup;
103 }
104 if (finfo.filetype != APR_REG) {
105 err = "not a plain file";
106 rv = APR_EINVAL; goto cleanup;
107 }
108 if (finfo.size > LONG_MAX) {
109 err = "file is too large";
110 rv = APR_EINVAL; goto cleanup;
111 }
112 len = (apr_size_t)finfo.size;
114 err = "file size not in allowed range";
115 rv = APR_EINVAL; goto cleanup;
116 }
117 d = apr_pcalloc(p, sizeof(*d));
118 buffer = apr_pcalloc(p, len+1); /* keep it NUL terminated in any case */
119 rv = apr_file_open(&f, fpath, APR_FOPEN_READ, 0, p);
120 if (APR_SUCCESS != rv) {
121 err = "error opening"; goto cleanup;
122 }
123 rv = apr_file_read(f, buffer, &len);
124 if (APR_SUCCESS != rv) {
125 err = "error reading"; goto cleanup;
126 }
127cleanup:
128 if (f) apr_file_close(f);
129 if (APR_SUCCESS == rv) {
130 data->data = buffer;
131 data->len = len;
132 }
133 else {
134 memset(data, 0, sizeof(*data));
136 "Failed to load file %s: %s", fpath, err? err: "-");
137 }
138 return rv;
139}
140
142{
143 int i;
144 for (i = 0; i < a->nelts; ++i) {
145 if (APR_ARRAY_IDX(a, i, apr_uint16_t) == n) return 1;
146 }
147 return 0;
148}
149
152{
155 int i, j;
156
157 for (i = 0; i < from->nelts; ++i) {
158 id = APR_ARRAY_IDX(from, i, apr_uint16_t);
160 if (na == NULL) {
161 /* first removal, make a new result array, copy elements before */
162 na = apr_array_make(pool, from->nelts, sizeof(apr_uint16_t));
163 for (j = 0; j < i; ++j) {
165 }
166 }
167 }
168 else if (na) {
170 }
171 }
172 return na? na : from;
173}
174
178{
179 apr_bucket *b;
182 const char *ign;
184
185 *pnout = 0;
186 while (!APR_BRIGADE_EMPTY(src)) {
188
192 }
193 else {
194 if (remain == (apr_off_t)b->length) {
195 /* fall through */
196 }
197 else if (remain <= 0) {
198 goto cleanup;
199 }
200 else {
201 if (b->length == ((apr_size_t)-1)) {
203 if (APR_SUCCESS != rv) goto cleanup;
204 }
205 if (remain < (apr_off_t)b->length) {
207 }
208 }
211 remain -= (apr_off_t)b->length;
212 *pnout += (apr_off_t)b->length;
213 }
214 }
215cleanup:
216 return rv;
217}
218
222{
223 apr_bucket *b, *next;
226 const char *ign;
228
229 *pnout = 0;
230 for (b = APR_BRIGADE_FIRST(src);
232 b = next) {
233 next = APR_BUCKET_NEXT(b);
234
236 /* fall through */
237 }
238 else {
239 if (remain == (apr_off_t)b->length) {
240 /* fall through */
241 }
242 else if (remain <= 0) {
243 goto cleanup;
244 }
245 else {
246 if (b->length == ((apr_size_t)-1)) {
248 if (APR_SUCCESS != rv) goto cleanup;
249 }
250 if (remain < (apr_off_t)b->length) {
252 }
253 }
254 }
255 rv = apr_bucket_copy(b, &b);
256 if (APR_SUCCESS != rv) goto cleanup;
258 remain -= (apr_off_t)b->length;
259 *pnout += (apr_off_t)b->length;
260 }
261cleanup:
262 return rv;
263}
264
269{
271 apr_status_t rv;
272
275 if (APR_SUCCESS != rv) goto cleanup;
277 /* apr_brigade_split_line() has the nasty habit of leaving a 0-length bucket
278 * at the start of the brigade when it transferred the whole content. Get rid of it.
279 */
280 if (!APR_BRIGADE_EMPTY(src)) {
282 if (!APR_BUCKET_IS_METADATA(b) && 0 == b->length) {
285 }
286 }
287cleanup:
288 *pnout = (APR_SUCCESS == rv)? (nend - nstart) : 0;
289 return rv;
290}
291
293{
295 char **alias;
296 int i;
297
298 if (!s || !s->server_hostname) return 0;
299 if (!strcasecmp(name, s->server_hostname)) return 1;
300 /* first the fast equality match, then the pattern wild_name matches */
301 names = s->names;
302 if (!names) return 0;
303 alias = (char **)names->elts;
304 for (i = 0; i < names->nelts; ++i) {
305 if (alias[i] && !strcasecmp(name, alias[i])) return 1;
306 }
307 names = s->wild_names;
308 if (!names) return 0;
309 alias = (char **)names->elts;
310 for (i = 0; i < names->nelts; ++i) {
311 if (alias[i] && !ap_strcasecmp_match(name, alias[i])) return 1;
312 }
313 return 0;
314}
315
317 apr_bucket *b, const char *sep)
318{
319 apr_size_t off = 0;
320 if (sep && *sep) {
322 }
323
324 if (bmax <= off) {
325 return off;
326 }
327 else if (APR_BUCKET_IS_METADATA(b)) {
328 off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s", b->type->name);
329 }
330 else if (bmax > off) {
331 off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s[%ld]",
332 b->type->name, (long)(b->length == ((apr_size_t)-1)?
333 -1 : (int)b->length));
334 }
335 return off;
336}
337
339 const char *tag, const char *sep,
341{
342 apr_size_t off = 0;
343 const char *sp = "";
344 apr_bucket *b;
345
346 if (bmax > 1) {
347 if (bb) {
348 memset(buffer, 0, bmax--);
349 off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s(", tag);
350 for (b = APR_BRIGADE_FIRST(bb);
351 (bmax > off) && (b != APR_BRIGADE_SENTINEL(bb));
352 b = APR_BUCKET_NEXT(b)) {
353
355 sp = " ";
356 }
357 if (bmax > off) {
358 off += (size_t)apr_snprintf(buffer+off, bmax-off, ")%s", sep);
359 }
360 }
361 else {
362 off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s(null)%s", tag, sep);
363 }
364 }
365 return off;
366}
367
int n
Definition ap_regex.h:278
const char apr_size_t len
Definition ap_regex.h:187
APR File Information.
APR general purpose library routines.
apr_size_t const unsigned char unsigned int unsigned int d
Definition apr_siphash.h:72
APR Strings library.
#define APLOG_USE_MODULE(foo)
#define HUGE_STRING_LEN
Definition httpd.h:303
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
#define ap_log_perror
Definition http_log.h:412
#define APR_EGENERAL
Definition apr_errno.h:313
#define APR_EINVAL
Definition apr_errno.h:711
apr_file_t * f
#define APR_BUCKET_REMOVE(e)
#define APR_BUCKET_IS_METADATA(e)
#define APR_BRIGADE_INSERT_TAIL(b, e)
#define apr_bucket_split(e, point)
#define APR_BUCKET_NEXT(e)
apr_read_type_e
Definition apr_buckets.h:57
#define APR_BRIGADE_EMPTY(b)
#define APR_BRIGADE_SENTINEL(b)
#define apr_bucket_delete(e)
#define apr_bucket_copy(e, c)
apr_bucket apr_bucket_brigade * a
#define APR_BRIGADE_FIRST(b)
#define apr_bucket_read(e, str, len, block)
int apr_off_t * length
@ APR_BLOCK_READ
Definition apr_buckets.h:58
const char * src
Definition apr_encode.h:167
int ap_strcasecmp_match(const char *str, const char *expected)
Definition util.c:199
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
@ APR_REG
void * data
void const char apr_status_t(* cleanup)(void *))
char * buffer
#define APR_FOPEN_READ
Definition apr_file_io.h:54
#define APR_FINFO_TYPE
#define APR_FINFO_SIZE
int strcasecmp(const char *a, const char *b)
const char apr_uint32_t * id
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * sep
const char * s
Definition apr_strings.h:95
#define APR_ARRAY_PUSH(ary, type)
Definition apr_tables.h:150
#define APR_ARRAY_IDX(ary, i, type)
Definition apr_tables.h:141
apr_int32_t apr_int32_t apr_int32_t err
CORE HTTP Daemon.
Apache Logging library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
char * name
apr_filetype_e filetype
apr_off_t size
A structure to store information for each virtual server.
Definition httpd.h:1322
apr_size_t len
Definition tls_util.h:28
const unsigned char * data
Definition tls_util.h:27
apr_size_t tls_util_bucket_print(char *buffer, apr_size_t bmax, apr_bucket *b, const char *sep)
Definition tls_util.c:316
apr_status_t tls_util_brigade_transfer(apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length, apr_off_t *pnout)
Definition tls_util.c:175
int tls_util_name_matches_server(const char *name, server_rec *s)
Definition tls_util.c:292
int tls_util_is_file(apr_pool_t *p, const char *fpath)
Definition tls_util.c:79
tls_data_t tls_data_from_str(const char *s)
Definition tls_util.c:35
tls_data_t tls_data_assign_copy(apr_pool_t *p, const tls_data_t *d)
Definition tls_util.c:43
apr_size_t tls_util_bb_print(char *buffer, apr_size_t bmax, const char *tag, const char *sep, apr_bucket_brigade *bb)
Definition tls_util.c:338
apr_status_t tls_util_rustls_error(apr_pool_t *p, rustls_result rr, const char **perr_descr)
Definition tls_util.c:66
apr_status_t tls_util_brigade_copy(apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length, apr_off_t *pnout)
Definition tls_util.c:219
tls_data_t * tls_data_copy(apr_pool_t *p, const tls_data_t *d)
Definition tls_util.c:51
apr_status_t tls_util_brigade_split_line(apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_read_type_e block, apr_off_t length, apr_off_t *pnout)
Definition tls_util.c:265
apr_status_t tls_util_file_load(apr_pool_t *p, const char *fpath, apr_size_t min_len, apr_size_t max_len, tls_data_t *data)
Definition tls_util.c:89
const apr_array_header_t * tls_util_array_uint16_remove(apr_pool_t *pool, const apr_array_header_t *from, const apr_array_header_t *others)
Definition tls_util.c:150
int tls_util_array_uint16_contains(const apr_array_header_t *a, apr_uint16_t n)
Definition tls_util.c:141
const char * tls_data_to_str(apr_pool_t *p, const tls_data_t *d)
Definition tls_util.c:59
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray