use GSSEAP_ASSERT macro instead of assert
[moonshot.git] / moonshot / mech_eap / util_moonshot.c
1 /*
2  * Copyright (c) 2011, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #include "gssapiP_eap.h"
34
35 #ifdef HAVE_MOONSHOT_GET_IDENTITY
36 #include <libmoonshot.h>
37
38 static OM_uint32
39 libMoonshotMapError(OM_uint32 *minor,
40                     MoonshotError **pError)
41 {
42     MoonshotError *error = *pError;
43
44     GSSEAP_ASSERT(error != NULL);
45
46     switch (error->code) {
47     case MOONSHOT_ERROR_UNABLE_TO_START_SERVICE:
48         *minor = GSSEAP_UNABLE_TO_START_IDENTITY_SERVICE;
49         break;
50     case MOONSHOT_ERROR_NO_IDENTITY_SELECTED:
51         *minor = GSSEAP_NO_IDENTITY_SELECTED;
52         break;
53     case MOONSHOT_ERROR_INSTALLATION_ERROR:
54         *minor = GSSEAP_IDENTITY_SERVICE_INSTALL_ERROR;
55         break;
56     case MOONSHOT_ERROR_OS_ERROR:
57         *minor = GSSEAP_IDENTITY_SERVICE_OS_ERROR;
58         break;
59     case MOONSHOT_ERROR_IPC_ERROR:
60         *minor = GSSEAP_IDENTITY_SERVICE_IPC_ERROR;
61         break;
62     default:
63         *minor = GSSEAP_IDENTITY_SERVICE_UNKNOWN_ERROR;
64         break;
65     }
66
67     gssEapSaveStatusInfo(*minor, error->message);
68     moonshot_error_free(error);
69     *pError = NULL;
70
71     return GSS_S_CRED_UNAVAIL;
72 }
73
74 OM_uint32
75 libMoonshotResolveDefaultIdentity(OM_uint32 *minor,
76                                   const gss_cred_id_t cred,
77                                   gss_name_t *pName)
78 {
79     OM_uint32 major, tmpMinor;
80     gss_OID nameMech = gssEapPrimaryMechForCred(cred);
81     gss_name_t name = GSS_C_NO_NAME;
82     gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
83     char *nai = NULL;
84     char *password = NULL;
85     char *serverCertificateHash = NULL;
86     char *caCertificate = NULL;
87     char *subjectNameConstraint = NULL;
88     char *subjectAltNameConstraint = NULL;
89     MoonshotError *error = NULL;
90
91     *pName = GSS_C_NO_NAME;
92
93     if (!moonshot_get_default_identity(&nai,
94                                        &password,
95                                        &serverCertificateHash,
96                                        &caCertificate,
97                                        &subjectNameConstraint,
98                                        &subjectAltNameConstraint,
99                                        &error)) {
100         if (error->code == MOONSHOT_ERROR_NO_IDENTITY_SELECTED) {
101             major = GSS_S_CRED_UNAVAIL;
102             *minor = GSSEAP_NO_DEFAULT_IDENTITY;
103             moonshot_error_free(error);
104         } else
105             major = libMoonshotMapError(minor, &error);
106         goto cleanup;
107     }
108
109     tmpBuffer.value = nai;
110     tmpBuffer.length = strlen(nai);
111
112     major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME, nameMech, &name);
113     if (GSS_ERROR(major))
114         goto cleanup;
115
116     *pName = name;
117     name = GSS_C_NO_NAME;
118
119 cleanup:
120     moonshot_free(nai);
121     moonshot_free(password);
122     moonshot_free(serverCertificateHash);
123     moonshot_free(caCertificate);
124     moonshot_free(subjectNameConstraint);
125     moonshot_free(subjectAltNameConstraint);
126
127     gssEapReleaseName(&tmpMinor, &name);
128
129     return major;
130 }
131
132 OM_uint32
133 libMoonshotResolveInitiatorCred(OM_uint32 *minor,
134                                 gss_cred_id_t cred,
135                                 const gss_name_t targetName)
136 {
137     OM_uint32 major, tmpMinor;
138     gss_OID nameMech = gssEapPrimaryMechForCred(cred);
139     gss_buffer_desc initiator = GSS_C_EMPTY_BUFFER;
140     gss_buffer_desc target = GSS_C_EMPTY_BUFFER;
141     gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
142     char *nai = NULL;
143     char *password = NULL;
144     char *serverCertificateHash = NULL;
145     char *caCertificate = NULL;
146     char *subjectNameConstraint = NULL;
147     char *subjectAltNameConstraint = NULL;
148     MoonshotError *error = NULL;
149
150     if (cred->name != GSS_C_NO_NAME) {
151         major = gssEapExportName(minor, cred->name, &initiator);
152         if (GSS_ERROR(major))
153             goto cleanup;
154     }
155
156     if (targetName != GSS_C_NO_NAME) {
157         major = gssEapExportName(minor, targetName, &target);
158         if (GSS_ERROR(major))
159             goto cleanup;
160     }
161
162     if (!moonshot_get_identity((const char *)initiator.value,
163                                (const char *)cred->password.value,
164                                (const char *)target.value,
165                                &nai,
166                                &password,
167                                &serverCertificateHash,
168                                &caCertificate,
169                                &subjectNameConstraint,
170                                &subjectAltNameConstraint,
171                                &error)) {
172         major = libMoonshotMapError(minor, &error);
173         goto cleanup;
174     }
175
176     gssEapReleaseName(&tmpMinor, &cred->name);
177
178     tmpBuffer.value = nai;
179     tmpBuffer.length = strlen(nai);
180
181     major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME,
182                              nameMech, &cred->name);
183     if (GSS_ERROR(major))
184         goto cleanup;
185
186     tmpBuffer.value = password;
187     tmpBuffer.length = strlen(password);
188
189     major = gssEapSetCredPassword(minor, cred, &tmpBuffer);
190     if (GSS_ERROR(major))
191         goto cleanup;
192
193     gss_release_buffer(&tmpMinor, &cred->caCertificate);
194     gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint);
195     gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint);
196
197     if (serverCertificateHash != NULL) {
198         size_t len = strlen(serverCertificateHash);
199
200         #define HASH_PREFIX             "hash://server/sha256/"
201         #define HASH_PREFIX_LEN         (sizeof(HASH_PREFIX) - 1)
202
203         cred->caCertificate.value = GSSEAP_MALLOC(HASH_PREFIX_LEN + len + 1);
204         if (cred->caCertificate.value == NULL) {
205             major = GSS_S_FAILURE;
206             *minor = ENOMEM;
207             goto cleanup;
208         }
209
210         memcpy(cred->caCertificate.value, HASH_PREFIX, HASH_PREFIX_LEN);
211         memcpy((char *)cred->caCertificate.value + HASH_PREFIX_LEN, serverCertificateHash, len);
212
213         ((char *)cred->caCertificate.value)[HASH_PREFIX_LEN + len] = '\0';
214
215         cred->caCertificate.length = HASH_PREFIX_LEN + len;
216     } else if (caCertificate != NULL) {
217         makeStringBufferOrCleanup(caCertificate, &cred->caCertificate);
218     }
219
220     if (subjectNameConstraint != NULL)
221         makeStringBufferOrCleanup(subjectNameConstraint, &cred->subjectNameConstraint);
222     if (subjectAltNameConstraint != NULL)
223         makeStringBufferOrCleanup(subjectAltNameConstraint, &cred->subjectAltNameConstraint);
224
225 cleanup:
226     moonshot_free(nai);
227     moonshot_free(password);
228     moonshot_free(serverCertificateHash);
229     moonshot_free(caCertificate);
230     moonshot_free(subjectNameConstraint);
231     moonshot_free(subjectAltNameConstraint);
232
233     gss_release_buffer(&tmpMinor, &initiator);
234     gss_release_buffer(&tmpMinor, &target);
235
236     return major;
237 }
238 #endif /* HAVE_MOONSHOT_GET_IDENTITY */