View | Details | Raw Unified | Return to bug 2121
Collapse All | Expand All

(-)Makefile.in (-1 / +1 lines)
Lines 77-83 Link Here
77
77
78
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
78
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
79
	sshconnect.o sshconnect1.o sshconnect2.o mux.o \
79
	sshconnect.o sshconnect1.o sshconnect2.o mux.o \
80
	roaming_common.o roaming_client.o
80
	roaming_common.o roaming_client.o gss_wrap.o
81
81
82
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
82
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
83
	audit.o audit-bsm.o audit-linux.o platform.o \
83
	audit.o audit-bsm.o audit-linux.o platform.o \
(-)configure.ac (+11 lines)
Lines 3812-3817 Link Here
3812
AC_SUBST([GSSLIBS])
3812
AC_SUBST([GSSLIBS])
3813
AC_SUBST([K5LIBS])
3813
AC_SUBST([K5LIBS])
3814
3814
3815
# Use runtime loading of gss libraries
3816
AC_ARG_WITH([gss-wrap],
3817
    [  --with-gss-wrap         Enable runtime GSSAPI loading],
3818
    [ if test "x$withval" != "xno" ; then
3819
        AC_DEFINE([USE_GSS_WRAP], [1],
3820
            [Use GSSAPI wrapper for dynamic loading of GSSAPI libraries])
3821
        GSSLIBS=""
3822
    fi
3823
    ]
3824
)
3825
3815
# Looking for programs, paths and files
3826
# Looking for programs, paths and files
3816
3827
3817
PRIVSEP_PATH=/var/empty
3828
PRIVSEP_PATH=/var/empty
(-)gss_wrap.c (+235 lines)
Added Link Here
1
/*
2
 * Copyright 2013 Aaron Sowry for Cendio AB
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
 */
16
17
#include "includes.h"
18
19
#if defined(GSSAPI) && defined(USE_GSS_WRAP)
20
#include <stdio.h>
21
#include <stdbool.h>
22
#include <dlfcn.h>
23
24
#include "ssh-gss.h"
25
26
void *gss_handle = NULL;
27
28
static gss_OID_desc _GSS_C_NT_HOSTBASED_SERVICE = {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"};
29
gss_OID GSS_C_NT_HOSTBASED_SERVICE = &_GSS_C_NT_HOSTBASED_SERVICE;
30
31
/* Function pointer definitions
32
 * Taken from RFC 2744 (http://tools.ietf.org/html/rfc2744.html) */
33
OM_uint32 (*_gss_release_buffer)    (OM_uint32*,         gss_buffer_t);
34
OM_uint32 (*_gss_release_cred)      (OM_uint32*,         gss_cred_id_t*);
35
OM_uint32 (*_gss_release_name)      (OM_uint32*,         gss_name_t*);
36
OM_uint32 (*_gss_import_name)       (OM_uint32*,         const gss_buffer_t,
37
                                     const gss_OID,      gss_name_t*);
38
OM_uint32 (*_gss_display_status)    (OM_uint32*,         OM_uint32,
39
                                     int,                const gss_OID,
40
                                     OM_uint32*,         gss_buffer_t);
41
OM_uint32 (*_gss_indicate_mechs)    (OM_uint32*,         gss_OID_set*);
42
OM_uint32 (*_gss_get_mic)           (OM_uint32*,         const gss_ctx_id_t,
43
                                     gss_qop_t,          const gss_buffer_t,
44
                                     gss_buffer_t);
45
OM_uint32 (*_gss_delete_sec_context)(OM_uint32*,         gss_ctx_id_t*,
46
                                     gss_buffer_t);
47
OM_uint32 (*_gss_init_sec_context)  (OM_uint32*,         gss_cred_id_t,
48
                                     gss_ctx_id_t*,      gss_name_t,
49
                                     gss_OID,            OM_uint32,
50
                                     OM_uint32,          gss_channel_bindings_t,
51
                                     gss_buffer_t,       gss_OID*,
52
                                     gss_buffer_t,       OM_uint32*,
53
                                     OM_uint32*);
54
55
typedef struct fn_ptr_map_def {
56
	void **fn_ptr;
57
	const char *fn_name;
58
} fn_ptr_map;
59
60
/* Create a mapping of function names to the actual library functions */
61
const fn_ptr_map gss_fn_map[] = {
62
	{(void**)&_gss_release_buffer,     "gss_release_buffer"},
63
	{(void**)&_gss_release_cred,       "gss_release_cred"},
64
	{(void**)&_gss_release_name,       "gss_release_name"},
65
	{(void**)&_gss_import_name,        "gss_import_name"},
66
	{(void**)&_gss_display_status,     "gss_display_status"},
67
	{(void**)&_gss_indicate_mechs,     "gss_indicate_mechs"},
68
	{(void**)&_gss_get_mic,            "gss_get_mic"},
69
	{(void**)&_gss_delete_sec_context, "gss_delete_sec_context"},
70
	{(void**)&_gss_init_sec_context,   "gss_init_sec_context"}
71
};
72
73
static bool do_dlopen() {
74
	char *gss_lib = "libgssapi_krb5.so.2";    
75
76
	if (gss_handle != NULL)
77
		return true;
78
79
	/* Open GSSAPI library */
80
	gss_handle = dlopen(gss_lib, RTLD_NOW);
81
82
	if (gss_handle == NULL) {
83
		fprintf(stderr, "Error loading GSSAPI library: %s\n", dlerror());
84
		return false;
85
	}
86
87
	/* Assign function pointers */
88
	int n = sizeof(gss_fn_map) / sizeof(gss_fn_map[0]);
89
90
	int i;
91
	for (i = 0; i < n; i++) {
92
		*gss_fn_map[i].fn_ptr = dlsym(gss_handle, gss_fn_map[i].fn_name);
93
		if (! *gss_fn_map[i].fn_ptr) {
94
			fprintf(stderr, "Error loading GSSAPI library: %s\n", dlerror());
95
			return false;
96
		}
97
	}
98
99
	return true;
100
}
101
102
OM_uint32 gss_release_buffer (
103
        OM_uint32    *minor_status,
104
        gss_buffer_t buffer)
105
{
106
	if (!do_dlopen())
107
		return GSS_S_FAILURE;
108
109
	return _gss_release_buffer(minor_status, buffer);
110
};
111
112
OM_uint32 gss_release_cred (
113
        OM_uint32     *minor_status,
114
        gss_cred_id_t *cred_handle)
115
{
116
	if (!do_dlopen())
117
		return GSS_S_FAILURE;
118
119
	return _gss_release_cred(minor_status, cred_handle);
120
};
121
122
OM_uint32 gss_release_name (
123
        OM_uint32  *minor_status,
124
        gss_name_t *name)
125
{
126
	if (!do_dlopen())
127
		return GSS_S_FAILURE;
128
129
	return _gss_release_name(minor_status, name);
130
};
131
132
OM_uint32 gss_import_name (
133
        OM_uint32          *minor_status,
134
        const gss_buffer_t input_name_buffer,
135
        const gss_OID      input_name_type,
136
        gss_name_t         *output_name)
137
{
138
	if (!do_dlopen())
139
		return GSS_S_FAILURE;
140
141
	return _gss_import_name(minor_status,    input_name_buffer,
142
	                        input_name_type, output_name);
143
};
144
145
OM_uint32 gss_display_status (
146
        OM_uint32      *minor_status,
147
        OM_uint32      status_value,
148
        int            status_type,
149
        const gss_OID  mech_type,
150
        OM_uint32      *message_context,
151
        gss_buffer_t   status_string)
152
{
153
	if(!do_dlopen())
154
		return GSS_S_FAILURE;
155
156
	return _gss_display_status(minor_status,    status_value,
157
	                           status_type,     mech_type,
158
	                           message_context, status_string);
159
};
160
161
/* OpenSSH expects gss_indicate_mechs to assign some valid pointer 
162
 * to mech_set, even if the call fails. Define an empty set which
163
 * we can pass back in this case. */
164
gss_OID_set_desc empty_set = {
165
	.count = 0,
166
	.elements = NULL
167
};
168
169
OM_uint32 gss_indicate_mechs (
170
        OM_uint32   *minor_status,
171
        gss_OID_set *mech_set)
172
{
173
	if (!do_dlopen()) {
174
		*mech_set = &empty_set;
175
		return GSS_S_FAILURE;
176
	}
177
178
	return _gss_indicate_mechs(minor_status, mech_set);
179
};
180
181
OM_uint32 gss_get_mic (
182
        OM_uint32          *minor_status,
183
        const gss_ctx_id_t context_handle,
184
        gss_qop_t          qop_req,
185
        const gss_buffer_t message_buffer,
186
        gss_buffer_t       msg_token)
187
{
188
	if (!do_dlopen())
189
		return GSS_S_FAILURE;
190
191
	return _gss_get_mic(minor_status, context_handle,
192
	                    qop_req,      message_buffer,
193
	                    msg_token);
194
};
195
196
OM_uint32 gss_delete_sec_context (
197
        OM_uint32    *minor_status,
198
        gss_ctx_id_t *context_handle,
199
        gss_buffer_t output_token)
200
{
201
	if (!do_dlopen())
202
		return GSS_S_FAILURE;
203
204
	return _gss_delete_sec_context(minor_status, context_handle,
205
	                               output_token);
206
};
207
208
OM_uint32 gss_init_sec_context (
209
        OM_uint32              *minor_status,
210
        gss_cred_id_t          initiator_cred_handle,
211
        gss_ctx_id_t           *context_handle,
212
        gss_name_t             target_name,
213
        gss_OID                mech_type,
214
        OM_uint32              req_flags,
215
        OM_uint32              time_req,
216
        gss_channel_bindings_t input_chan_bindings,
217
        gss_buffer_t           input_token,
218
        gss_OID                *actual_mech_type,
219
        gss_buffer_t           output_token,
220
        OM_uint32              *ret_flags,
221
        OM_uint32              *time_rec)
222
{
223
	if (!do_dlopen())
224
		return GSS_S_FAILURE;
225
226
	return _gss_init_sec_context(minor_status,   initiator_cred_handle,
227
	                             context_handle, target_name,
228
	                             mech_type,      req_flags,
229
	                             time_req,       input_chan_bindings,
230
	                             input_token,    actual_mech_type,
231
	                             output_token,   ret_flags,
232
	                             time_rec);
233
};
234
235
#endif /* GSSAPI && USE_GSS_WRAP */

Return to bug 2121