1 /*
2  * Copyright (c) 2001 by Sun Microsystems, Inc.
3  * All rights reserved.
4  */
5 
6 /*
7  * The contents of this file are subject to the Netscape Public
8  * License Version 1.1 (the "License"); you may not use this file
9  * except in compliance with the License. You may obtain a copy of
10  * the License at http://www.mozilla.org/NPL/
11  *
12  * Software distributed under the License is distributed on an "AS
13  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14  * implied. See the License for the specific language governing
15  * rights and limitations under the License.
16  *
17  * The Original Code is Mozilla Communicator client code, released
18  * March 31, 1998.
19  *
20  * The Initial Developer of the Original Code is Netscape
21  * Communications Corporation. Portions created by Netscape are
22  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
23  * Rights Reserved.
24  *
25  * Contributor(s):
26  */
27 
28 /*
29  * errormap.c - map NSPR and OS errors to strings
30  *
31  * CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF NETSCAPE COMMUNICATIONS
32  * CORPORATION
33  *
34  * Copyright (C) 1998-9 Netscape Communications Corporation. All Rights Reserved.
35  *
36  * Use of this Source Code is subject to the terms of the applicable license
37  * agreement from Netscape Communications Corporation.
38  *
39  * The copyright notice(s) in this Source Code does not indicate actual or
40  * intended publication of this Source Code.
41  */
42 
43 /* XXX ceb
44  * This code was stolen from Directory server.
45  * ns/netsite/ldap/servers/slapd/errormap.c
46  * OS errors are not handled, so the os error has been removed.
47  */
48 
49 
50 #if defined( _WINDOWS )
51 #include <windows.h>
52 #include "proto-ntutil.h"
53 #endif
54 
55 #include <nspr.h>
56 #include <ssl.h>
57 
58 #include <ldap.h>
59 
60 #ifdef _SOLARIS_SDK
61 #include <synch.h>
62 #include <libintl.h>
63 #endif /* _SOLARIS_SDK */
64 
65 
66 /*
67  * function protoypes
68  */
69 static const char *SECU_Strerror(PRErrorCode errNum);
70 
71 
72 
73 /*
74  * return the string equivalent of an NSPR error
75  */
76 
77 const char *
78 LDAP_CALL
ldapssl_err2string(const int prerrno)79 ldapssl_err2string( const int prerrno )
80 {
81     const char	*s;
82 
83     if (( s = SECU_Strerror( (PRErrorCode)prerrno )) == NULL ) {
84 	s = dgettext(TEXT_DOMAIN, "unknown");
85     }
86 
87     return( s );
88 }
89 
90 /*
91  ****************************************************************************
92  * The code below this point was provided by Nelson Bolyard <nelsonb> of the
93  *	Netscape Certificate Server team on 27-March-1998.
94  *	Taken from the file ns/security/cmd/lib/secerror.c on NSS_1_BRANCH.
95  *	Last updated from there: 24-July-1998 by Mark Smith <mcs>
96  *	Last updated from there: 14-July-1999 by chuck boatwright <cboatwri>
97  *
98  *
99  * All of the Directory Server specific changes are enclosed inside
100  *	#ifdef NS_DIRECTORY.
101  ****************************************************************************
102  */
103 #include "nspr.h"
104 
105 /*
106  * XXXceb as a hack, we will locally define NS_DIRECTORY
107  */
108 #define NS_DIRECTORY 1
109 
110 struct tuple_str {
111     PRErrorCode	 errNum;
112     const char * errString;
113 };
114 
115 typedef struct tuple_str tuple_str;
116 
117 #ifndef _SOLARIS_SDK
118 #define ER2(a,b)   {a, b},
119 #define ER3(a,b,c) {a, c},
120 #else
121 #define ER2(a,b)   {a, NULL},
122 #define ER3(a,b,c) {a, NULL},
123 #endif
124 
125 #include "secerr.h"
126 #include "sslerr.h"
127 
128 #ifndef _SOLARIS_SDK
129 const tuple_str errStrings[] = {
130 #else
131 tuple_str errStrings[] = {
132 #endif
133 
134 /* keep this list in asceding order of error numbers */
135 #ifdef NS_DIRECTORY
136 #include "sslerrstrs.h"
137 #include "secerrstrs.h"
138 #include "prerrstrs.h"
139 /*
140  * XXXceb -- LDAPSDK won't care about disconnect
141 #include "disconnect_error_strings.h"
142  */
143 
144 #else /* NS_DIRECTORY */
145 #include "SSLerrs.h"
146 #include "SECerrs.h"
147 #include "NSPRerrs.h"
148 #endif /* NS_DIRECTORY */
149 
150 };
151 
152 const PRInt32 numStrings = sizeof(errStrings) / sizeof(tuple_str);
153 
154 /* Returns a UTF-8 encoded constant error string for "errNum".
155  * Returns NULL of errNum is unknown.
156  */
157 #ifndef _SOLARIS_SDK
158 #ifdef NS_DIRECTORY
159 static
160 #endif /* NS_DIRECTORY */
161 const char *
SECU_Strerror(PRErrorCode errNum)162 SECU_Strerror(PRErrorCode errNum) {
163     PRInt32 low  = 0;
164     PRInt32 high = numStrings - 1;
165     PRInt32 i;
166     PRErrorCode num;
167     static int initDone;
168 
169     /* make sure table is in ascending order.
170      * binary search depends on it.
171      */
172     if (!initDone) {
173 	PRErrorCode lastNum = 0x80000000;
174     	for (i = low; i <= high; ++i) {
175 	    num = errStrings[i].errNum;
176 	    if (num <= lastNum) {
177 
178 /*
179  * XXXceb
180  * We aren't handling out of sequence errors.
181  */
182 
183 
184 #if 0
185 #ifdef NS_DIRECTORY
186 		LDAPDebug( LDAP_DEBUG_ANY,
187 			"sequence error in error strings at item %d\n"
188 			"error %d (%s)\n",
189 			i, lastNum, errStrings[i-1].errString );
190 		LDAPDebug( LDAP_DEBUG_ANY,
191 			"should come after \n"
192 			"error %d (%s)\n",
193 			num, errStrings[i].errString, 0 );
194 #else /* NS_DIRECTORY */
195 	    	fprintf(stderr,
196 "sequence error in error strings at item %d\n"
197 "error %d (%s)\n"
198 "should come after \n"
199 "error %d (%s)\n",
200 		        i, lastNum, errStrings[i-1].errString,
201 			num, errStrings[i].errString);
202 #endif /* NS_DIRECTORY */
203 #endif /* 0 */
204 	    }
205 	    lastNum = num;
206 	}
207 	initDone = 1;
208     }
209 
210     /* Do binary search of table. */
211     while (low + 1 < high) {
212     	i = (low + high) / 2;
213 	num = errStrings[i].errNum;
214 	if (errNum == num)
215 	    return errStrings[i].errString;
216         if (errNum < num)
217 	    high = i;
218 	else
219 	    low = i;
220     }
221     if (errNum == errStrings[low].errNum)
222     	return errStrings[low].errString;
223     if (errNum == errStrings[high].errNum)
224     	return errStrings[high].errString;
225     return NULL;
226 }
227 #else /* _SOLARIS_SDK */
228 #undef ER3
229 #define	ER3(x, y, z) case (x):		\
230 			s = (z);	\
231 			break;
232 #undef ER2
233 #define	ER2(x, y) case (x):		\
234 			s = (y);	\
235 			break;
236 
237 static mutex_t		err_mutex = DEFAULTMUTEX;
238 
239 static const char *
getErrString(PRInt32 i,PRErrorCode errNum)240 getErrString(PRInt32 i, PRErrorCode errNum)
241 {
242 	char *s;
243 
244 	mutex_lock(&err_mutex);
245 
246 	if (errStrings[i].errString != NULL) {
247 		mutex_unlock(&err_mutex);
248 		return (errStrings[i].errString);
249 	}
250 
251 	switch (errNum) {
252 #include "sslerrstrs.h"
253 #include "secerrstrs.h"
254 #include "prerrstrs.h"
255 		default:
256 			s = NULL;
257 			break;
258 	}
259 	errStrings[i].errString = s;
260 	mutex_unlock(&err_mutex);
261 	return (s);
262 }
263 
264 static
265 const char *
SECU_Strerror(PRErrorCode errNum)266 SECU_Strerror(PRErrorCode errNum) {
267     PRInt32 low  = 0;
268     PRInt32 high = numStrings - 1;
269     PRInt32 i;
270     PRErrorCode num;
271 
272     /* ASSUME table is in ascending order.
273      * binary search depends on it.
274      */
275 
276     /* Do binary search of table. */
277     while (low + 1 < high) {
278     	i = (low + high) / 2;
279 	num = errStrings[i].errNum;
280 	if (errNum == num)
281 	    return getErrString(i, errNum);
282         if (errNum < num)
283 	    high = i;
284 	else
285 	    low = i;
286     }
287     if (errNum == errStrings[low].errNum)
288     	return getErrString(low, errNum);
289     if (errNum == errStrings[high].errNum)
290     	return getErrString(high, errNum);
291     return NULL;
292 }
293 #endif
294