]> granicus.if.org Git - apache/blob - modules/ssl/ssl_util.c
Silly compiler, const char* is for text :)
[apache] / modules / ssl / ssl_util.c
1 /*                      _             _
2 **  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
3 ** | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
4 ** | | | | | | (_) | (_| |   \__ \__ \ |  www.modssl.org
5 ** |_| |_| |_|\___/ \__,_|___|___/___/_|  ftp.modssl.org
6 **                      |_____|
7 **  ssl_util.c
8 **  Utility Functions
9 */
10
11 /* ====================================================================
12  * The Apache Software License, Version 1.1
13  *
14  * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
15  * reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  *
21  * 1. Redistributions of source code must retain the above copyright
22  *    notice, this list of conditions and the following disclaimer.
23  *
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in
26  *    the documentation and/or other materials provided with the
27  *    distribution.
28  *
29  * 3. The end-user documentation included with the redistribution,
30  *    if any, must include the following acknowledgment:
31  *       "This product includes software developed by the
32  *        Apache Software Foundation (http://www.apache.org/)."
33  *    Alternately, this acknowledgment may appear in the software itself,
34  *    if and wherever such third-party acknowledgments normally appear.
35  *
36  * 4. The names "Apache" and "Apache Software Foundation" must
37  *    not be used to endorse or promote products derived from this
38  *    software without prior written permission. For written
39  *    permission, please contact apache@apache.org.
40  *
41  * 5. Products derived from this software may not be called "Apache",
42  *    nor may "Apache" appear in their name, without prior written
43  *    permission of the Apache Software Foundation.
44  *
45  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
49  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56  * SUCH DAMAGE.
57  * ====================================================================
58  */
59                              /* ``Every day of my life
60                                   I am forced to add another
61                                   name to the list of people
62                                   who piss me off!''
63                                             -- Calvin          */
64 #include "mod_ssl.h"
65
66 /*  _________________________________________________________________
67 **
68 **  Utility Functions
69 **  _________________________________________________________________
70 */
71
72 char *ssl_util_vhostid(apr_pool_t *p, server_rec *s)
73 {
74     char *id;
75     SSLSrvConfigRec *sc;
76     char *host;
77     apr_port_t port;
78
79     host = s->server_hostname;
80     if (s->port != 0)
81         port = s->port;
82     else {
83         sc = mySrvConfig(s);
84         if (sc->bEnabled)
85             port = DEFAULT_HTTPS_PORT;
86         else
87             port = DEFAULT_HTTP_PORT;
88     }
89     id = apr_psprintf(p, "%s:%lu", host, (unsigned long)port);
90     return id;
91 }
92
93 void ssl_util_strupper(char *s)
94 {
95     for (; *s; ++s)
96         *s = apr_toupper(*s);
97     return;
98 }
99
100 static const char ssl_util_uuencode_six2pr[64+1] =
101     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
102
103 void ssl_util_uuencode(char *szTo, const char *szFrom, BOOL bPad)
104 {
105     ssl_util_uuencode_binary((unsigned char *)szTo,
106                              (const unsigned char *)szFrom,
107                              strlen(szFrom), bPad);
108 }
109
110 void ssl_util_uuencode_binary(
111     unsigned char *szTo, const unsigned char *szFrom, int nLength, BOOL bPad)
112 {
113     const unsigned char *s;
114     int nPad = 0;
115
116     for (s = szFrom; nLength > 0; s += 3) {
117         *szTo++ = ssl_util_uuencode_six2pr[s[0] >> 2];
118         *szTo++ = ssl_util_uuencode_six2pr[(s[0] << 4 | s[1] >> 4) & 0x3f];
119         if (--nLength == 0) {
120             nPad = 2;
121             break;
122         }
123         *szTo++ = ssl_util_uuencode_six2pr[(s[1] << 2 | s[2] >> 6) & 0x3f];
124         if (--nLength == 0) {
125             nPad = 1;
126             break;
127         }
128         *szTo++ = ssl_util_uuencode_six2pr[s[2] & 0x3f];
129         --nLength;
130     }
131     while(bPad && nPad--)
132         *szTo++ = NUL;
133     *szTo = NUL;
134     return;
135 }
136
137 apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, char *cmd)
138 {
139     apr_procattr_t *procattr;
140     apr_proc_t *proc;
141
142     if (apr_procattr_create(&procattr, p) != APR_SUCCESS) 
143         return NULL;
144     if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK, 
145                             APR_FULL_BLOCK) != APR_SUCCESS)
146         return NULL;
147     if (apr_procattr_dir_set(procattr, 
148                              ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS)
149         return NULL;
150     if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
151         return NULL;
152     if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL)
153         return NULL;
154     if (apr_proc_create(proc, cmd, NULL, NULL, procattr, p) != APR_SUCCESS)
155         return NULL;
156     return proc->out;
157 }
158
159 void ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
160 {
161     apr_file_close(fp);
162     return;
163 }
164
165 /*
166  * Run a filter program and read the first line of its stdout output
167  */
168 char *ssl_util_readfilter(server_rec *s, apr_pool_t *p, char *cmd)
169 {
170     static char buf[MAX_STRING_LEN];
171     apr_file_t *fp;
172     apr_size_t nbytes;
173     char c;
174     int k;
175
176     if ((fp = ssl_util_ppopen(s, p, cmd)) == NULL)
177         return NULL;
178     for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
179                 && nbytes == 1 && (k < MAX_STRING_LEN-1)     ; ) {
180         if (c == '\n' || c == '\r')
181             break;
182         buf[k++] = c;
183     }
184     buf[k] = NUL;
185     ssl_util_ppclose(s, p, fp);
186
187     return buf;
188 }
189
190 BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
191 {
192     apr_finfo_t finfo;
193
194     if (path == NULL)
195         return FALSE;
196     if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path, 
197                                 APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
198         return FALSE;
199     if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
200         return FALSE;
201     if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
202         return FALSE;
203     if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
204         return FALSE;
205     return TRUE;
206 }
207
208 ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey) 
209 {
210     ssl_algo_t t;
211             
212     t = SSL_ALGO_UNKNOWN;
213     if (pCert != NULL)
214         pKey = X509_get_pubkey(pCert);
215     if (pKey != NULL) {
216         switch (EVP_PKEY_type(pKey->type)) {
217             case EVP_PKEY_RSA: 
218                 t = SSL_ALGO_RSA;
219                 break;
220             case EVP_PKEY_DSA: 
221                 t = SSL_ALGO_DSA;
222                 break;
223             default:
224                 break;
225         }
226     }
227     return t;
228 }
229
230 char *ssl_util_algotypestr(ssl_algo_t t) 
231 {
232     char *cp;
233
234     cp = "UNKNOWN";
235     switch (t) {
236         case SSL_ALGO_RSA: 
237             cp = "RSA";
238             break;
239         case SSL_ALGO_DSA: 
240             cp = "DSA";
241             break;
242         default:
243             break;
244     }
245     return cp;
246 }
247
248 char *ssl_util_ptxtsub(
249     apr_pool_t *p, const char *cpLine, const char *cpMatch, char *cpSubst)
250 {
251 #define MAX_PTXTSUB 100
252     char *cppMatch[MAX_PTXTSUB];
253     char *cpResult;
254     int nResult;
255     int nLine;
256     int nSubst;
257     int nMatch;
258     char *cpI;
259     char *cpO;
260     char *cp;
261     int i;
262
263     /*
264      * Pass 1: find substitution locations and calculate sizes
265      */
266     nLine  = strlen(cpLine);
267     nMatch = strlen(cpMatch);
268     nSubst = strlen(cpSubst);
269     for (cpI = (char *)cpLine, i = 0, nResult = 0;
270          cpI < cpLine+nLine && i < MAX_PTXTSUB;    ) {
271         if ((cp = strstr(cpI, cpMatch)) != NULL) {
272             cppMatch[i++] = cp;
273             nResult += ((cp-cpI)+nSubst);
274             cpI = (cp+nMatch);
275         }
276         else {
277             nResult += strlen(cpI);
278             break;
279         }
280     }
281     cppMatch[i] = NULL;
282     if (i == 0)
283         return NULL;
284
285     /*
286      * Pass 2: allocate memory and assemble result
287      */
288     cpResult = apr_pcalloc(p, nResult+1);
289     for (cpI = (char *)cpLine, cpO = cpResult, i = 0; cppMatch[i] != NULL; i++) {
290         apr_cpystrn(cpO, cpI, cppMatch[i]-cpI+1);
291         cpO += (cppMatch[i]-cpI);
292         apr_cpystrn(cpO, cpSubst, nSubst+1);
293         cpO += nSubst;
294         cpI = (cppMatch[i]+nMatch);
295     }
296     apr_cpystrn(cpO, cpI, cpResult+nResult-cpO+1);
297
298     return cpResult;
299 }
300
301 apr_status_t
302 ssl_util_setmodconfig(
303     server_rec *s, const char *key, SSLModConfigRec *mc)
304 {
305     return apr_pool_userdata_set((void *)mc, key, apr_pool_cleanup_null, s->process->pool);
306 }
307
308 SSLModConfigRec *
309 ssl_util_getmodconfig(
310     server_rec *s, const char *key)
311 {
312     SSLModConfigRec *mc = NULL;
313
314     if (apr_pool_userdata_get((void **)&mc, key, s->process->pool) != APR_SUCCESS)
315         ssl_log(s, SSL_LOG_TRACE, "Unable to retrieve SSLModConfig from global pool");
316     return mc;
317 }
318
319 SSLModConfigRec *
320 ssl_util_getmodconfig_ssl(
321     SSL *ssl, const char *key)
322 {
323     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
324     SSLModConfigRec *mc = NULL;
325      
326     if (c != NULL)
327         mc = ssl_util_getmodconfig(c->base_server, key);
328     return mc;
329 }
330