1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  *	support.c
24  *
25  *	Copyright (c) 1997, by Sun Microsystems, Inc.
26  *	All rights reserved.
27  *
28  */
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <libintl.h>
33 #include <locale.h>
34 
35 #include "dh_gssapi.h"
36 
37 /*
38  * __dh_gss_display_status: This is the routine that implements
39  * gss_display_status for Diffie-Hellman mechanism. Note we will
40  * return failure if the status_type parameter is GSS_C_GSS_CODE
41  * since libgss should handle the mechanism independent codes.
42  */
43 OM_uint32
__dh_gss_display_status(void * ctx,OM_uint32 * minor,OM_uint32 status_value,int status_type,gss_OID mech,OM_uint32 * mesg_ctx,gss_buffer_t status_str)44 __dh_gss_display_status(void *ctx, /* Per mechanism context */
45 			OM_uint32 *minor, /* This mechanism's status */
46 			OM_uint32 status_value, /* The value to dispaly */
47 			int status_type, /* Shoud alway be GSS_C_MECH_COE */
48 			gss_OID mech, /* Our OID or GSS_C_NO_OID */
49 			OM_uint32* mesg_ctx, /* Message context for continues */
50 			gss_buffer_t  status_str /* The displayed output */)
51 {
52 	char *str;
53 	OM_uint32 major = GSS_S_COMPLETE;
54 
55 	if (!minor)
56 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
57 	*minor = DH_SUCCESS;
58 
59 	if (!mesg_ctx)
60 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
61 
62 	/* We only have one message per status value */
63 	*mesg_ctx = 0;
64 
65 
66 	/*
67 	 * If status_type equals GSS_C_GSS_CODE, we'll return
68 	 * GSS_S_FAILURE. This status type is handled by the caller,
69 	 * libgss, since it is mechanism independent. We should never see
70 	 * this. If the status type does not equal GSS_C_MECH_CODE and
71 	 * does not equal GSS_C_GSS_CODE we return GSS_S_BAD_STATUS as per
72 	 * spec.
73 	 */
74 
75 	if (status_type != GSS_C_MECH_CODE)
76 		return ((status_type == GSS_C_GSS_CODE ?
77 			GSS_S_FAILURE : GSS_S_BAD_STATUS));
78 
79 	if (mech != GSS_C_NO_OID &&
80 	    !__OID_equal(((dh_context_t)ctx)->mech, mech))
81 		return (GSS_S_BAD_MECH);
82 
83 	/* Convert the DH status value to an internationalize string */
84 	switch (status_value) {
85 	case DH_SUCCESS:
86 		str = dgettext(TEXT_DOMAIN, "mech_dh: Success");
87 		break;
88 	case DH_NOMEM_FAILURE:
89 		str = dgettext(TEXT_DOMAIN, "mech_dh: No memory");
90 		break;
91 	case DH_ENCODE_FAILURE:
92 		str = dgettext(TEXT_DOMAIN,
93 			    "mech_dh: Could not encode token");
94 		break;
95 	case DH_DECODE_FAILURE:
96 		str = dgettext(TEXT_DOMAIN,
97 			    "mech_dh: Could not decode token");
98 		break;
99 	case DH_BADARG_FAILURE:
100 		str = dgettext(TEXT_DOMAIN, "mech_dh: Bad argument");
101 		break;
102 	case DH_CIPHER_FAILURE:
103 		str = dgettext(TEXT_DOMAIN, "mech_dh: Cipher failure");
104 		break;
105 	case DH_VERIFIER_FAILURE:
106 		str = dgettext(TEXT_DOMAIN, "mech_dh: Verifier failure");
107 		break;
108 	case DH_SESSION_CIPHER_FAILURE:
109 		str = dgettext(TEXT_DOMAIN, "mech_dh: Session cipher failure");
110 		break;
111 	case DH_NO_SECRET:
112 		str = dgettext(TEXT_DOMAIN, "mech_dh: No secret key");
113 		break;
114 	case DH_NO_PRINCIPAL:
115 		str = dgettext(TEXT_DOMAIN, "mech_dh: No principal");
116 		break;
117 	case DH_NOT_LOCAL:
118 		str = dgettext(TEXT_DOMAIN, "mech_dh: Not local principal");
119 		break;
120 	case DH_UNKNOWN_QOP:
121 		str = dgettext(TEXT_DOMAIN, "mech_dh: Unkown QOP");
122 		break;
123 	case DH_VERIFIER_MISMATCH:
124 		str = dgettext(TEXT_DOMAIN, "mech_dh: Verifier mismatch");
125 		break;
126 	case DH_NO_SUCH_USER:
127 		str = dgettext(TEXT_DOMAIN, "mech_dh: No such user");
128 		break;
129 	case DH_NETNAME_FAILURE:
130 		str = dgettext(TEXT_DOMAIN,
131 			    "mech_dh: Could not generate netname");
132 		break;
133 	case DH_BAD_CRED:
134 		str = dgettext(TEXT_DOMAIN, "mech_dh: Invalid credential");
135 		break;
136 	case DH_BAD_CONTEXT:
137 		str = dgettext(TEXT_DOMAIN, "mech_dh: Invalid GSS context");
138 		break;
139 	case DH_PROTO_MISMATCH:
140 		str = dgettext(TEXT_DOMAIN, "mech_dh: Diffie-Hellman protocol "
141 			    "mismatch");
142 		break;
143 	default:
144 		str = dgettext(TEXT_DOMAIN, "mech_dh: Invalid or "
145 			    "unknown error");
146 		major = GSS_S_BAD_STATUS;
147 		break;
148 	}
149 
150 	/* Copy the string to the output */
151 	status_str->value = strdup(str);
152 	if (status_str == 0) {
153 		*minor = DH_NOMEM_FAILURE;
154 		return (GSS_S_FAILURE);
155 	}
156 	status_str->length = strlen(str);
157 
158 	/* Return the GSS status of GSS_S_COMPLETE or GSS_S_BAD_STATUS */
159 	return (major);
160 }
161 
162 
163 /*
164  * This function is completely implemented in libgss. Its entry point is
165  * set to NULL in dhmech.c
166  */
167 /*
168  * OM_uint32
169  * __dh_gss_indicate_mechs(void *ctx, OM_uint32 *minor, gss_OID_set *mechs)
170  * {
171  *	return (GSS_S_UNAVAILABLE);
172  * }
173  */
174