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