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