source: mod_gnutls/src/gnutls_util.c

mod_gnutls/0.9.1
Last change on this file was b6c7866, checked in by Fiona Klute <fiona.klute@…>, 12 months ago

Update copyright headers of files changed this year

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 *  Copyright 2016-2019 Fiona Klute
3 *
4 *  Licensed under the Apache License, Version 2.0 (the "License");
5 *  you may not use this file except in compliance with the License.
6 *  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
17#include "gnutls_util.h"
18
19#include <apr_strings.h>
20#include <gnutls/gnutls.h>
21
22
23
24/** Compiled version of MGS_DEFAULT_PRIORITY, must be initialized
25 * using mgs_default_priority_init() in the pre_config hook and
26 * deinitialized in the matching pool cleanup hook. */
27static gnutls_priority_t default_prio;
28
29
30
31const char* http_post_header(apr_pool_t *p, apr_uri_t *uri,
32                             const char *content_type, const char *accept,
33                             apr_size_t size)
34{
35    return apr_psprintf(p, "POST %s HTTP/1.0\r\n"
36                        "Host: %s\r\n"
37                        "Content-Type: %s\r\n"
38                        "Accept: %s\r\n"
39                        "Content-Length: %" APR_SIZE_T_FMT "\r\n\r\n",
40                        apr_uri_unparse(p, uri, APR_URI_UNP_OMITSITEPART),
41                        uri->hostname, content_type,
42                        accept != NULL ? accept : "*/*",
43                        size);
44}
45
46
47
48apr_status_t sock_send_buf(apr_socket_t *sock, const char *buf,
49                           const apr_size_t size)
50{
51    apr_status_t rv = APR_EINIT;
52    apr_size_t len = 0;
53    for (apr_size_t sent = 0; sent < size; sent += len)
54    {
55        len = size - sent;
56        rv = apr_socket_send(sock, buf + sent, &len);
57        /* API documentation for apr_socket_send(): "It is possible
58         * for both bytes to be sent and an error to be returned."
59         *
60         * So break if there was an error, unless bytes were also
61         * sent. In the latter case try to continue. */
62        if (rv != APR_SUCCESS && len == 0)
63            break;
64    }
65    return rv;
66}
67
68
69
70const char* read_line(apr_pool_t *p, apr_bucket_brigade *sockb,
71                      apr_bucket_brigade *lineb)
72{
73    apr_brigade_cleanup(lineb);
74    apr_status_t rv = apr_brigade_split_line(lineb, sockb,
75                                             APR_BLOCK_READ,
76                                             HTTP_HDR_LINE_MAX);
77    if (rv != APR_SUCCESS)
78        return NULL;
79
80    char *line;
81    apr_size_t len;
82    rv = apr_brigade_pflatten(lineb, &line, &len, p);
83    if (rv != APR_SUCCESS)
84        return NULL;
85
86    /* The last two characters on a correct header line are
87     * "\r\n". Switch \r to \0 to chomp off the line break. */
88    if (len >= 2 && line[len-1] == '\n' && line[len-2] == '\r')
89    {
90        line[len-2] = '\0';
91        return line;
92    }
93    else
94        return NULL;
95}
96
97
98
99apr_status_t datum_from_file(apr_pool_t *p, const char* filename,
100                             gnutls_datum_t *datum)
101{
102    apr_status_t rv = APR_EINIT;
103    apr_file_t *file;
104    apr_finfo_t finfo;
105    apr_size_t br = 0;
106    rv = apr_file_open(&file, filename,
107                       APR_READ | APR_BINARY, APR_OS_DEFAULT, p);
108    if (rv != APR_SUCCESS)
109        return rv;
110
111    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, file);
112    if (rv != APR_SUCCESS)
113        return rv;
114
115    datum->data = apr_palloc(p, finfo.size);
116    rv = apr_file_read_full(file, datum->data, finfo.size, &br);
117    if (rv != APR_SUCCESS)
118        return rv;
119
120    apr_file_close(file);
121
122    /* safe integer type conversion: unsigned int and apr_size_t might
123     * have different sizes */
124#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
125    if (__builtin_expect(br > UINT_MAX, 0))
126        return APR_EINVAL;
127    else
128        datum->size = (unsigned int) br;
129#else
130    if (__builtin_add_overflow(br, 0, &datum->size))
131        return APR_EINVAL;
132#endif
133
134    return rv;
135}
136
137
138
139mgs_handle_t *init_gnutls_ctxt(conn_rec *c)
140{
141    mgs_handle_t *ctxt = (mgs_handle_t *)
142        ap_get_module_config(c->conn_config, &gnutls_module);
143    if (ctxt == NULL)
144    {
145        ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
146        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
147
148        /* Get mod_gnutls server configuration */
149        mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
150            ap_get_module_config(c->base_server->module_config,
151                                 &gnutls_module);
152
153        /* Set up connection and server references */
154        ctxt->c = c;
155        ctxt->sc = sc;
156        /* Default, unconditionally changed in proxy setup functions */
157        ctxt->is_proxy = GNUTLS_ENABLED_FALSE;
158        /* Other default values */
159        ctxt->sni_name = NULL;
160    }
161    return ctxt;
162}
163
164
165
166int mgs_default_priority_init()
167{
168    return gnutls_priority_init(&default_prio, MGS_DEFAULT_PRIORITY, NULL);
169}
170
171
172
173gnutls_priority_t mgs_get_default_prio()
174{
175    return default_prio;
176}
177
178
179
180void mgs_default_priority_deinit()
181{
182    gnutls_priority_deinit(default_prio);
183}
184
185
186
187gnutls_datum_t * mgs_str_array_to_datum_array(const apr_array_header_t *src,
188                                              apr_pool_t *pool,
189                                              const int min_elements)
190{
191    int num = min_elements > src->nelts ? min_elements : src->nelts;
192    gnutls_datum_t *dest = apr_palloc(pool, num * sizeof(gnutls_datum_t));
193    for (int i = 0; i < src->nelts; i++)
194    {
195        dest[i].data = (void *) APR_ARRAY_IDX(src, i, char *);
196        dest[i].size = strlen(APR_ARRAY_IDX(src, i, char *));
197    }
198    return dest;
199}
Note: See TracBrowser for help on using the repository browser.