123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- #include "putty.h"
- #ifndef NO_GSSAPI
- #include "ssh/pgssapi.h"
- #include "ssh/gss.h"
- #include "ssh/gssc.h"
- /* Unix code to set up the GSSAPI library list. */
- #if !defined NO_LIBDL && !defined STATIC_GSSAPI && !defined NO_GSSAPI
- const int ngsslibs = 4;
- const char *const gsslibnames[4] = {
- "libgssapi (Heimdal)",
- "libgssapi_krb5 (MIT Kerberos)",
- "libgss (Sun)",
- "User-specified GSSAPI library",
- };
- const struct keyvalwhere gsslibkeywords[] = {
- { "libgssapi", 0, -1, -1 },
- { "libgssapi_krb5", 1, -1, -1 },
- { "libgss", 2, -1, -1 },
- { "custom", 3, -1, -1 },
- };
- /*
- * Run-time binding against a choice of GSSAPI implementations. We
- * try loading several libraries, and produce an entry in
- * ssh_gss_libraries[] for each one.
- */
- static void gss_init(struct ssh_gss_library *lib, void *dlhandle,
- int id, const char *msg)
- {
- lib->id = id;
- lib->gsslogmsg = msg;
- lib->handle = dlhandle;
- #define BIND_GSS_FN(name) \
- lib->u.gssapi.name = (t_gss_##name) dlsym(dlhandle, "gss_" #name)
- BIND_GSS_FN(delete_sec_context);
- BIND_GSS_FN(display_status);
- BIND_GSS_FN(get_mic);
- BIND_GSS_FN(verify_mic);
- BIND_GSS_FN(import_name);
- BIND_GSS_FN(init_sec_context);
- BIND_GSS_FN(release_buffer);
- BIND_GSS_FN(release_cred);
- BIND_GSS_FN(release_name);
- BIND_GSS_FN(acquire_cred);
- BIND_GSS_FN(inquire_cred_by_mech);
- #undef BIND_GSS_FN
- ssh_gssapi_bind_fns(lib);
- }
- /* Dynamically load gssapi libs. */
- struct ssh_gss_liblist *ssh_gss_setup(Conf *conf)
- {
- void *gsslib;
- char *gsspath;
- struct ssh_gss_liblist *list = snew(struct ssh_gss_liblist);
- list->libraries = snewn(4, struct ssh_gss_library);
- list->nlibraries = 0;
- /* Heimdal's GSSAPI Library */
- if ((gsslib = dlopen("libgssapi.so.2", RTLD_LAZY)) != NULL)
- gss_init(&list->libraries[list->nlibraries++], gsslib,
- 0, "Using GSSAPI from libgssapi.so.2");
- /* MIT Kerberos's GSSAPI Library */
- if ((gsslib = dlopen("libgssapi_krb5.so.2", RTLD_LAZY)) != NULL)
- gss_init(&list->libraries[list->nlibraries++], gsslib,
- 1, "Using GSSAPI from libgssapi_krb5.so.2");
- /* Sun's GSSAPI Library */
- if ((gsslib = dlopen("libgss.so.1", RTLD_LAZY)) != NULL)
- gss_init(&list->libraries[list->nlibraries++], gsslib,
- 2, "Using GSSAPI from libgss.so.1");
- /* User-specified GSSAPI library */
- gsspath = conf_get_filename(conf, CONF_ssh_gss_custom)->path;
- if (*gsspath && (gsslib = dlopen(gsspath, RTLD_LAZY)) != NULL)
- gss_init(&list->libraries[list->nlibraries++], gsslib,
- 3, dupprintf("Using GSSAPI from user-specified"
- " library '%s'", gsspath));
- return list;
- }
- void ssh_gss_cleanup(struct ssh_gss_liblist *list)
- {
- int i;
- /*
- * dlopen and dlclose are defined to employ reference counting
- * in the case where the same library is repeatedly dlopened, so
- * even in a multiple-sessions-per-process context it's safe to
- * naively dlclose everything here without worrying about
- * destroying it under the feet of another SSH instance still
- * using it.
- */
- for (i = 0; i < list->nlibraries; i++) {
- dlclose(list->libraries[i].handle);
- if (list->libraries[i].id == 3) {
- /* The 'custom' id involves a dynamically allocated message.
- * Note that we must cast away the 'const' to free it. */
- sfree((char *)list->libraries[i].gsslogmsg);
- }
- }
- sfree(list->libraries);
- sfree(list);
- }
- #elif !defined NO_GSSAPI
- const int ngsslibs = 1;
- const char *const gsslibnames[1] = {
- "static",
- };
- const struct keyvalwhere gsslibkeywords[] = {
- { "static", 0, -1, -1 },
- };
- /*
- * Link-time binding against GSSAPI. Here we just construct a single
- * library structure containing pointers to the functions we linked
- * against.
- */
- #include <gssapi/gssapi.h>
- /* Dynamically load gssapi libs. */
- struct ssh_gss_liblist *ssh_gss_setup(Conf *conf)
- {
- struct ssh_gss_liblist *list = snew(struct ssh_gss_liblist);
- list->libraries = snew(struct ssh_gss_library);
- list->nlibraries = 1;
- list->libraries[0].id = 0;
- list->libraries[0].gsslogmsg = "Using statically linked GSSAPI";
- #define BIND_GSS_FN(name) \
- list->libraries[0].u.gssapi.name = (t_gss_##name) gss_##name
- BIND_GSS_FN(delete_sec_context);
- BIND_GSS_FN(display_status);
- BIND_GSS_FN(get_mic);
- BIND_GSS_FN(verify_mic);
- BIND_GSS_FN(import_name);
- BIND_GSS_FN(init_sec_context);
- BIND_GSS_FN(release_buffer);
- BIND_GSS_FN(release_cred);
- BIND_GSS_FN(release_name);
- BIND_GSS_FN(acquire_cred);
- BIND_GSS_FN(inquire_cred_by_mech);
- #undef BIND_GSS_FN
- ssh_gssapi_bind_fns(&list->libraries[0]);
- return list;
- }
- void ssh_gss_cleanup(struct ssh_gss_liblist *list)
- {
- sfree(list->libraries);
- sfree(list);
- }
- #endif /* NO_LIBDL */
- #endif /* NO_GSSAPI */
|