]> andersk Git - gssapi-openssh.git/blob - openssh/gss-serv-gsi.c
merging OPENSSH_5_2P1_SIMON_20090726_HPN13V6 to trunk:
[gssapi-openssh.git] / openssh / gss-serv-gsi.c
1 /*
2  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "includes.h"
26
27 #ifdef GSSAPI
28 #ifdef GSI
29
30 #include <sys/types.h>
31
32 #include <stdarg.h>
33 #include <string.h>
34
35 #include "xmalloc.h"
36 #include "key.h"
37 #include "hostfile.h"
38 #include "auth.h"
39 #include "log.h"
40 #include "servconf.h"
41
42 #include "buffer.h"
43 #include "ssh-gss.h"
44
45 extern ServerOptions options;
46
47 #include <globus_gss_assist.h>
48
49 static int ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name);
50 static int ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user);
51 static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client);
52
53 ssh_gssapi_mech gssapi_gsi_mech = {
54         "dZuIebMjgUqaxvbF7hDbAw==",
55         "GSI",
56         {9, "\x2B\x06\x01\x04\x01\x9B\x50\x01\x01"},
57         NULL,
58         &ssh_gssapi_gsi_userok,
59         &ssh_gssapi_gsi_localname,
60         &ssh_gssapi_gsi_storecreds,
61     NULL
62 };
63
64 /*
65  * Check if this user is OK to login under GSI. User has been authenticated
66  * as identity in global 'client_name.value' and is trying to log in as passed
67  * username in 'name'.
68  *
69  * Returns non-zero if user is authorized, 0 otherwise.
70  */
71 static int
72 ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name)
73 {
74     int authorized = 0;
75     globus_result_t res;
76 #ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
77     char lname[256] = "";
78 #endif
79     
80 #ifdef GLOBUS_GSI_GSS_ASSIST_MODULE
81     if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) {
82         return 0;
83     }
84 #endif
85
86 /* use new globus_gss_assist_map_and_authorize() interface if available */
87 #ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
88     debug("calling globus_gss_assist_map_and_authorize()");
89     if (GLOBUS_SUCCESS !=
90         (res = globus_gss_assist_map_and_authorize(client->context, "ssh",
91                                                    name, lname, 256))) {
92         debug("%s", globus_error_print_chain(globus_error_get(res)));
93     } else if (lname && lname[0] && strcmp(name, lname) != 0) {
94         debug("GSI user maps to %s, not %s", lname, name);
95     } else {
96         authorized = 1;
97     }
98 #else
99     debug("calling globus_gss_assist_userok()");
100     if (GLOBUS_SUCCESS !=
101         (res = (globus_gss_assist_userok(client->displayname.value,
102                                          name)))) {
103         debug("%s", globus_error_print_chain(globus_error_get(res)));
104     } else {
105         authorized = 1;
106     }
107 #endif
108     
109     logit("GSI user %s is%s authorized as target user %s",
110         (char *) client->displayname.value, (authorized ? "" : " not"), name);
111     
112     return authorized;
113 }
114
115 /*
116  * Return the local username associated with the GSI credentials.
117  */
118 int
119 ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user)
120 {
121     globus_result_t res;
122 #ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
123     char lname[256] = "";
124 #endif
125
126 #ifdef GLOBUS_GSI_GSS_ASSIST_MODULE
127     if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) {
128         return 0;
129     }
130 #endif
131
132 /* use new globus_gss_assist_map_and_authorize() interface if available */
133 #ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
134     debug("calling globus_gss_assist_map_and_authorize()");
135     if (GLOBUS_SUCCESS !=
136         (res = globus_gss_assist_map_and_authorize(client->context, "ssh",
137                                                    NULL, lname, 256))) {
138         debug("%s", globus_error_print_chain(globus_error_get(res)));
139         logit("failed to map GSI user %s", (char *)client->displayname.value);
140         return 0;
141     }
142     *user = strdup(lname);
143 #else
144     debug("calling globus_gss_assist_gridmap()");
145     if (GLOBUS_SUCCESS !=
146         (res = globus_gss_assist_gridmap(client->displayname.value, user))) {
147         debug("%s", globus_error_print_chain(globus_error_get(res)));
148         logit("failed to map GSI user %s", (char *)client->displayname.value);
149         return 0;
150     }
151 #endif
152
153     logit("GSI user %s mapped to target user %s",
154           (char *) client->displayname.value, *user);
155
156     return 1;
157 }
158
159 /*
160  * Export GSI credentials to disk.
161  */
162 static void
163 ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client)
164 {
165         OM_uint32       major_status;
166         OM_uint32       minor_status;
167         gss_buffer_desc export_cred = GSS_C_EMPTY_BUFFER;
168         char *          p;
169         
170         if (!client || !client->creds) {
171             return;
172         }
173
174         major_status = gss_export_cred(&minor_status,
175                                        client->creds,
176                                        GSS_C_NO_OID,
177                                        1,
178                                        &export_cred);
179         if (GSS_ERROR(major_status) && major_status != GSS_S_UNAVAILABLE) {
180             Gssctxt *ctx;
181             ssh_gssapi_build_ctx(&ctx);
182             ctx->major = major_status;
183             ctx->minor = minor_status;
184             ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid);
185             ssh_gssapi_error(ctx);
186             ssh_gssapi_delete_ctx(&ctx);
187             return;
188         }
189         
190         p = strchr((char *) export_cred.value, '=');
191         if (p == NULL) {
192             logit("Failed to parse exported credentials string '%.100s'",
193                 (char *)export_cred.value);
194             gss_release_buffer(&minor_status, &export_cred);
195             return;
196         }
197         *p++ = '\0';
198         if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) {
199             client->store.envvar = strdup("X509_USER_PROXY");
200         } else {
201             client->store.envvar = strdup((char *)export_cred.value);
202         }
203         if (access(p, R_OK) == 0) {
204         if (client->store.filename) {
205             if (rename(p, client->store.filename) < 0) {
206                 logit("Failed to rename %s to %s: %s", p,
207                       client->store.filename, strerror(errno));
208                 xfree(client->store.filename);
209                 client->store.filename = strdup(p);
210             } else {
211                 p = client->store.filename;
212             }
213         } else {
214             client->store.filename = strdup(p);
215         }
216         }
217         client->store.envval = strdup(p);
218 #ifdef USE_PAM
219         if (options.use_pam)
220             do_pam_putenv(client->store.envvar, client->store.envval);
221 #endif
222         gss_release_buffer(&minor_status, &export_cred);
223 }
224
225 #endif /* GSI */
226 #endif /* GSSAPI */
This page took 0.086569 seconds and 5 git commands to generate.