9 static Ssh_gss_stat
ssh_gssapi_indicate_mech(struct ssh_gss_library
*lib
,
12 /* Copy constant into mech */
13 mech
->length
= GSS_MECH_KRB5
->length
;
14 mech
->value
= GSS_MECH_KRB5
->elements
;
18 static Ssh_gss_stat
ssh_gssapi_import_name(struct ssh_gss_library
*lib
,
20 Ssh_gss_name
*srv_name
)
22 struct gssapi_functions
*gss
= &lib
->u
.gssapi
;
23 OM_uint32 min_stat
,maj_stat
;
24 gss_buffer_desc host_buf
;
27 pStr
= dupcat("host@", host
, NULL
);
29 host_buf
.value
= pStr
;
30 host_buf
.length
= strlen(pStr
);
32 maj_stat
= gss
->import_name(&min_stat
, &host_buf
,
33 GSS_C_NT_HOSTBASED_SERVICE
, srv_name
);
36 if (maj_stat
== GSS_S_COMPLETE
) return SSH_GSS_OK
;
37 return SSH_GSS_FAILURE
;
40 static Ssh_gss_stat
ssh_gssapi_acquire_cred(struct ssh_gss_library
*lib
,
43 gssapi_ssh_gss_ctx
*gssctx
= snew(gssapi_ssh_gss_ctx
);
45 gssctx
->maj_stat
= gssctx
->min_stat
= GSS_S_COMPLETE
;
46 gssctx
->ctx
= GSS_C_NO_CONTEXT
;
47 *ctx
= (Ssh_gss_ctx
) gssctx
;
52 static Ssh_gss_stat
ssh_gssapi_init_sec_context(struct ssh_gss_library
*lib
,
54 Ssh_gss_name srv_name
,
56 Ssh_gss_buf
*recv_tok
,
57 Ssh_gss_buf
*send_tok
)
59 struct gssapi_functions
*gss
= &lib
->u
.gssapi
;
60 gssapi_ssh_gss_ctx
*gssctx
= (gssapi_ssh_gss_ctx
*) *ctx
;
63 if (to_deleg
) to_deleg
= GSS_C_DELEG_FLAG
;
64 gssctx
->maj_stat
= gss
->init_sec_context(&gssctx
->min_stat
,
68 (gss_OID
) GSS_MECH_KRB5
,
70 GSS_C_INTEG_FLAG
| to_deleg
,
72 GSS_C_NO_CHANNEL_BINDINGS
,
74 NULL
, /* ignore mech type */
77 NULL
); /* ignore time_rec */
79 if (gssctx
->maj_stat
== GSS_S_COMPLETE
) return SSH_GSS_S_COMPLETE
;
80 if (gssctx
->maj_stat
== GSS_S_CONTINUE_NEEDED
) return SSH_GSS_S_CONTINUE_NEEDED
;
81 return SSH_GSS_FAILURE
;
84 static Ssh_gss_stat
ssh_gssapi_display_status(struct ssh_gss_library
*lib
,
88 struct gssapi_functions
*gss
= &lib
->u
.gssapi
;
89 gssapi_ssh_gss_ctx
*gssctx
= (gssapi_ssh_gss_ctx
*) ctx
;
92 gss_buffer_desc msg_maj
=GSS_C_EMPTY_BUFFER
;
93 gss_buffer_desc msg_min
=GSS_C_EMPTY_BUFFER
;
95 /* Return empty buffer in case of failure */
96 SSH_GSS_CLEAR_BUF(buf
);
98 /* get first mesg from GSS */
100 lmax
=gss
->display_status(&lmin
,gssctx
->maj_stat
,GSS_C_GSS_CODE
,(gss_OID
) GSS_MECH_KRB5
,&ccc
,&msg_maj
);
102 if (lmax
!= GSS_S_COMPLETE
) return SSH_GSS_FAILURE
;
104 /* get first mesg from Kerberos */
106 lmax
=gss
->display_status(&lmin
,gssctx
->min_stat
,GSS_C_MECH_CODE
,(gss_OID
) GSS_MECH_KRB5
,&ccc
,&msg_min
);
108 if (lmax
!= GSS_S_COMPLETE
) {
109 gss
->release_buffer(&lmin
, &msg_maj
);
110 return SSH_GSS_FAILURE
;
113 /* copy data into buffer */
114 buf
->length
= msg_maj
.length
+ msg_min
.length
+ 1;
115 buf
->value
= snewn(buf
->length
+ 1, char);
118 memcpy((char *)buf
->value
, msg_maj
.value
, msg_maj
.length
);
119 ((char *)buf
->value
)[msg_maj
.length
] = ' ';
120 memcpy((char *)buf
->value
+ msg_maj
.length
+ 1, msg_min
.value
, msg_min
.length
);
121 ((char *)buf
->value
)[buf
->length
] = 0;
122 /* free mem & exit */
123 gss
->release_buffer(&lmin
, &msg_maj
);
124 gss
->release_buffer(&lmin
, &msg_min
);
128 static Ssh_gss_stat
ssh_gssapi_free_tok(struct ssh_gss_library
*lib
,
129 Ssh_gss_buf
*send_tok
)
131 struct gssapi_functions
*gss
= &lib
->u
.gssapi
;
132 OM_uint32 min_stat
,maj_stat
;
133 maj_stat
= gss
->release_buffer(&min_stat
, send_tok
);
135 if (maj_stat
== GSS_S_COMPLETE
) return SSH_GSS_OK
;
136 return SSH_GSS_FAILURE
;
139 static Ssh_gss_stat
ssh_gssapi_release_cred(struct ssh_gss_library
*lib
,
142 struct gssapi_functions
*gss
= &lib
->u
.gssapi
;
143 gssapi_ssh_gss_ctx
*gssctx
= (gssapi_ssh_gss_ctx
*) *ctx
;
145 OM_uint32 maj_stat
=GSS_S_COMPLETE
;
147 if (gssctx
== NULL
) return SSH_GSS_FAILURE
;
148 if (gssctx
->ctx
!= GSS_C_NO_CONTEXT
)
149 maj_stat
= gss
->delete_sec_context(&min_stat
,&gssctx
->ctx
,GSS_C_NO_BUFFER
);
152 if (maj_stat
== GSS_S_COMPLETE
) return SSH_GSS_OK
;
153 return SSH_GSS_FAILURE
;
157 static Ssh_gss_stat
ssh_gssapi_release_name(struct ssh_gss_library
*lib
,
158 Ssh_gss_name
*srv_name
)
160 struct gssapi_functions
*gss
= &lib
->u
.gssapi
;
161 OM_uint32 min_stat
,maj_stat
;
162 maj_stat
= gss
->release_name(&min_stat
, srv_name
);
164 if (maj_stat
== GSS_S_COMPLETE
) return SSH_GSS_OK
;
165 return SSH_GSS_FAILURE
;
168 static Ssh_gss_stat
ssh_gssapi_get_mic(struct ssh_gss_library
*lib
,
169 Ssh_gss_ctx ctx
, Ssh_gss_buf
*buf
,
172 struct gssapi_functions
*gss
= &lib
->u
.gssapi
;
173 gssapi_ssh_gss_ctx
*gssctx
= (gssapi_ssh_gss_ctx
*) ctx
;
174 if (gssctx
== NULL
) return SSH_GSS_FAILURE
;
175 return gss
->get_mic(&(gssctx
->min_stat
), gssctx
->ctx
, 0, buf
, hash
);
178 static Ssh_gss_stat
ssh_gssapi_free_mic(struct ssh_gss_library
*lib
,
181 /* On Unix this is the same freeing process as ssh_gssapi_free_tok. */
182 return ssh_gssapi_free_tok(lib
, hash
);
185 void ssh_gssapi_bind_fns(struct ssh_gss_library
*lib
)
187 lib
->indicate_mech
= ssh_gssapi_indicate_mech
;
188 lib
->import_name
= ssh_gssapi_import_name
;
189 lib
->release_name
= ssh_gssapi_release_name
;
190 lib
->init_sec_context
= ssh_gssapi_init_sec_context
;
191 lib
->free_tok
= ssh_gssapi_free_tok
;
192 lib
->acquire_cred
= ssh_gssapi_acquire_cred
;
193 lib
->release_cred
= ssh_gssapi_release_cred
;
194 lib
->get_mic
= ssh_gssapi_get_mic
;
195 lib
->free_mic
= ssh_gssapi_free_mic
;
196 lib
->display_status
= ssh_gssapi_display_status
;
201 /* Dummy function so this source file defines something if NO_GSSAPI
204 int ssh_gssapi_init(void)