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  * Copyright (c) 1998-2003 Ralf S. Engelschall. All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  *
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following
23  *    disclaimer in the documentation and/or other materials
24  *    provided with the distribution.
25  *
26  * 3. All advertising materials mentioning features or use of this
27  *    software must display the following acknowledgment:
28  *    "This product includes software developed by
29  *     Ralf S. Engelschall <rse@engelschall.com> for use in the
30  *     mod_ssl project (http://www.modssl.org/)."
31  *
32  * 4. The names "mod_ssl" must not be used to endorse or promote
33  *    products derived from this software without prior written
34  *    permission. For written permission, please contact
35  *    rse@engelschall.com.
36  *
37  * 5. Products derived from this software may not be called "mod_ssl"
38  *    nor may "mod_ssl" appear in their names without prior
39  *    written permission of Ralf S. Engelschall.
40  *
41  * 6. Redistributions of any form whatsoever must retain the following
42  *    acknowledgment:
43  *    "This product includes software developed by
44  *     Ralf S. Engelschall <rse@engelschall.com> for use in the
45  *     mod_ssl project (http://www.modssl.org/)."
46  *
47  * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
48  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
50  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL RALF S. ENGELSCHALL OR
51  * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
58  * OF THE POSSIBILITY OF SUCH DAMAGE.
59  * ====================================================================
60  */
61 
62 /* ====================================================================
63  * Copyright (c) 1995-1999 Ben Laurie. All rights reserved.
64  *
65  * Redistribution and use in source and binary forms, with or without
66  * modification, are permitted provided that the following conditions
67  * are met:
68  *
69  * 1. Redistributions of source code must retain the above copyright
70  *    notice, this list of conditions and the following disclaimer.
71  *
72  * 2. Redistributions in binary form must reproduce the above copyright
73  *    notice, this list of conditions and the following disclaimer in
74  *    the documentation and/or other materials provided with the
75  *    distribution.
76  *
77  * 3. All advertising materials mentioning features or use of this
78  *    software must display the following acknowledgment:
79  *    "This product includes software developed by Ben Laurie
80  *    for use in the Apache-SSL HTTP server project."
81  *
82  * 4. The name "Apache-SSL Server" must not be used to
83  *    endorse or promote products derived from this software without
84  *    prior written permission.
85  *
86  * 5. Redistributions of any form whatsoever must retain the following
87  *    acknowledgment:
88  *    "This product includes software developed by Ben Laurie
89  *    for use in the Apache-SSL HTTP server project."
90  *
91  * THIS SOFTWARE IS PROVIDED BY BEN LAURIE ``AS IS'' AND ANY
92  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL BEN LAURIE OR
95  * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102  * OF THE POSSIBILITY OF SUCH DAMAGE.
103  * ====================================================================
104  */
105                              /* ``Every day of my life
106                                   I am forced to add another
107                                   name to the list of people
108                                   who piss me off!''
109                                             -- Calvin          */
110 #include "mod_ssl.h"
111 
112 
113 /*  _________________________________________________________________
114 **
115 **  Utility Functions
116 **  _________________________________________________________________
117 */
118 
ssl_util_server_root_relative(pool * p,char * what,char * arg)119 char *ssl_util_server_root_relative(pool *p, char *what, char *arg)
120 {
121     char *rv = NULL;
122 
123 #ifdef SSL_VENDOR
124     ap_hook_use("ap::mod_ssl::vendor::ssl_server_root_relative",
125                 AP_HOOK_SIG4(ptr,ptr,ptr,ptr), AP_HOOK_ALL, &rv, p, what, arg);
126     if (rv != NULL)
127         return rv;
128 #endif
129     rv = ap_server_root_relative(p, arg);
130     return rv;
131 }
132 
ssl_util_vhostid(pool * p,server_rec * s)133 char *ssl_util_vhostid(pool *p, server_rec *s)
134 {
135     char *id;
136     SSLSrvConfigRec *sc;
137     char *host;
138     unsigned int port;
139 
140     host = s->server_hostname;
141     if (s->port != 0)
142         port = s->port;
143     else {
144         sc = mySrvConfig(s);
145         if (sc->bEnabled)
146             port = DEFAULT_HTTPS_PORT;
147         else
148             port = DEFAULT_HTTP_PORT;
149     }
150     id = ap_psprintf(p, "%s:%u", host, port);
151     return id;
152 }
153 
ssl_util_ppopen(server_rec * s,pool * p,char * cmd)154 FILE *ssl_util_ppopen(server_rec *s, pool *p, char *cmd)
155 {
156     FILE *fpout;
157     int rc;
158 
159     fpout = NULL;
160     rc = ap_spawn_child(p, ssl_util_ppopen_child,
161                         (void *)cmd, kill_after_timeout,
162                         NULL, &fpout, NULL);
163     if (rc == 0 || fpout == NULL) {
164         ap_log_error(APLOG_MARK, APLOG_ERR, s,
165                      "ssl_util_ppopen: could not run: %s", cmd);
166         return NULL;
167     }
168     return (fpout);
169 }
170 
ssl_util_ppopen_child(void * cmd,child_info * pinfo)171 int ssl_util_ppopen_child(void *cmd, child_info *pinfo)
172 {
173     int child_pid = 1;
174 
175     /*
176      * Prepare for exec
177      */
178     ap_cleanup_for_exec();
179     signal(SIGHUP, SIG_IGN);
180 
181     /*
182      * Exec() the child program
183      */
184     /* Standard Unix */
185     execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, (char *)NULL);
186     return (child_pid);
187 }
188 
ssl_util_ppclose(server_rec * s,pool * p,FILE * fp)189 void ssl_util_ppclose(server_rec *s, pool *p, FILE *fp)
190 {
191     ap_pfclose(p, fp);
192     return;
193 }
194 
195 /*
196  * Run a filter program and read the first line of its stdout output
197  */
ssl_util_readfilter(server_rec * s,pool * p,char * cmd)198 char *ssl_util_readfilter(server_rec *s, pool *p, char *cmd)
199 {
200     static char buf[MAX_STRING_LEN];
201     FILE *fp;
202     char c;
203     int k;
204 
205     if ((fp = ssl_util_ppopen(s, p, cmd)) == NULL)
206         return NULL;
207     for (k = 0;    read(fileno(fp), &c, 1) == 1
208                 && (k < MAX_STRING_LEN-1)       ; ) {
209         if (c == '\n' || c == '\r')
210             break;
211         buf[k++] = c;
212     }
213     buf[k] = NUL;
214     ssl_util_ppclose(s, p, fp);
215 
216     return buf;
217 }
218 
ssl_util_path_check(ssl_pathcheck_t pcm,char * path)219 BOOL ssl_util_path_check(ssl_pathcheck_t pcm, char *path)
220 {
221     struct stat sb;
222 
223     if (path == NULL)
224         return FALSE;
225     if (pcm & SSL_PCM_EXISTS && stat(path, &sb) != 0)
226         return FALSE;
227     if (pcm & SSL_PCM_ISREG && !S_ISREG(sb.st_mode))
228         return FALSE;
229     if (pcm & SSL_PCM_ISDIR && !S_ISDIR(sb.st_mode))
230         return FALSE;
231     if (pcm & SSL_PCM_ISNONZERO && sb.st_mode <= 0)
232         return FALSE;
233     return TRUE;
234 }
235 
ssl_util_algotypeof(X509 * pCert,EVP_PKEY * pKey)236 ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
237 {
238     ssl_algo_t t;
239 
240     t = SSL_ALGO_UNKNOWN;
241     if (pCert != NULL)
242         pKey = X509_get_pubkey(pCert);
243     if (pKey != NULL) {
244         switch (EVP_PKEY_type(pKey->type)) {
245             case EVP_PKEY_RSA:
246                 t = SSL_ALGO_RSA;
247                 break;
248             case EVP_PKEY_DSA:
249                 t = SSL_ALGO_DSA;
250                 break;
251             default:
252                 break;
253         }
254     }
255     return t;
256 }
257 
ssl_util_algotypestr(ssl_algo_t t)258 char *ssl_util_algotypestr(ssl_algo_t t)
259 {
260     char *cp;
261 
262     cp = "UNKNOWN";
263     switch (t) {
264         case SSL_ALGO_RSA:
265             cp = "RSA";
266             break;
267         case SSL_ALGO_DSA:
268             cp = "DSA";
269             break;
270         default:
271             break;
272     }
273     return cp;
274 }
275 
ssl_util_ptxtsub(pool * p,const char * cpLine,const char * cpMatch,char * cpSubst)276 char *ssl_util_ptxtsub(
277     pool *p, const char *cpLine, const char *cpMatch, char *cpSubst)
278 {
279 #define MAX_PTXTSUB 100
280     char *cppMatch[MAX_PTXTSUB];
281     char *cpResult;
282     int nResult;
283     int nLine;
284     int nSubst;
285     int nMatch;
286     char *cpI;
287     char *cpO;
288     char *cp;
289     int i;
290 
291     /*
292      * Pass 1: find substitution locations and calculate sizes
293      */
294     nLine  = strlen(cpLine);
295     nMatch = strlen(cpMatch);
296     nSubst = strlen(cpSubst);
297     for (cpI = (char *)cpLine, i = 0, nResult = 0;
298          cpI < cpLine+nLine && i < MAX_PTXTSUB;    ) {
299         if ((cp = strstr(cpI, cpMatch)) != NULL) {
300             cppMatch[i++] = cp;
301             nResult += ((cp-cpI)+nSubst);
302             cpI = (cp+nMatch);
303         }
304         else {
305             nResult += strlen(cpI);
306             break;
307         }
308     }
309     cppMatch[i] = NULL;
310     if (i == 0)
311         return NULL;
312 
313     /*
314      * Pass 2: allocate memory and assemble result
315      */
316     cpResult = ap_pcalloc(p, nResult+1);
317     for (cpI = (char *)cpLine, cpO = cpResult, i = 0; cppMatch[i] != NULL; i++) {
318         ap_cpystrn(cpO, cpI, cppMatch[i]-cpI+1);
319         cpO += (cppMatch[i]-cpI);
320         ap_cpystrn(cpO, cpSubst, nSubst+1);
321         cpO += nSubst;
322         cpI = (cppMatch[i]+nMatch);
323     }
324     ap_cpystrn(cpO, cpI, cpResult+nResult-cpO+1);
325 
326     return cpResult;
327 }
328 
329 /*  _________________________________________________________________
330 **
331 **  Special Functions for Win32/OpenSSL
332 **  _________________________________________________________________
333 */
334 
ssl_util_thread_setup(void)335 void ssl_util_thread_setup(void)
336 {
337     return;
338 }
339 
ssl_util_thread_cleanup(void)340 void ssl_util_thread_cleanup(void)
341 {
342     return;
343 }
344 
345