gss.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "putty.h"
  2. #ifndef NO_GSSAPI
  3. #include "ssh/pgssapi.h"
  4. #include "ssh/gss.h"
  5. #include "ssh/gssc.h"
  6. /* Unix code to set up the GSSAPI library list. */
  7. #if !defined NO_LIBDL && !defined STATIC_GSSAPI && !defined NO_GSSAPI
  8. const int ngsslibs = 4;
  9. const char *const gsslibnames[4] = {
  10. "libgssapi (Heimdal)",
  11. "libgssapi_krb5 (MIT Kerberos)",
  12. "libgss (Sun)",
  13. "User-specified GSSAPI library",
  14. };
  15. const struct keyvalwhere gsslibkeywords[] = {
  16. { "libgssapi", 0, -1, -1 },
  17. { "libgssapi_krb5", 1, -1, -1 },
  18. { "libgss", 2, -1, -1 },
  19. { "custom", 3, -1, -1 },
  20. };
  21. /*
  22. * Run-time binding against a choice of GSSAPI implementations. We
  23. * try loading several libraries, and produce an entry in
  24. * ssh_gss_libraries[] for each one.
  25. */
  26. static void gss_init(struct ssh_gss_library *lib, void *dlhandle,
  27. int id, const char *msg)
  28. {
  29. lib->id = id;
  30. lib->gsslogmsg = msg;
  31. lib->handle = dlhandle;
  32. #define BIND_GSS_FN(name) \
  33. lib->u.gssapi.name = (t_gss_##name) dlsym(dlhandle, "gss_" #name)
  34. BIND_GSS_FN(delete_sec_context);
  35. BIND_GSS_FN(display_status);
  36. BIND_GSS_FN(get_mic);
  37. BIND_GSS_FN(verify_mic);
  38. BIND_GSS_FN(import_name);
  39. BIND_GSS_FN(init_sec_context);
  40. BIND_GSS_FN(release_buffer);
  41. BIND_GSS_FN(release_cred);
  42. BIND_GSS_FN(release_name);
  43. BIND_GSS_FN(acquire_cred);
  44. BIND_GSS_FN(inquire_cred_by_mech);
  45. #undef BIND_GSS_FN
  46. ssh_gssapi_bind_fns(lib);
  47. }
  48. /* Dynamically load gssapi libs. */
  49. struct ssh_gss_liblist *ssh_gss_setup(Conf *conf)
  50. {
  51. void *gsslib;
  52. char *gsspath;
  53. struct ssh_gss_liblist *list = snew(struct ssh_gss_liblist);
  54. list->libraries = snewn(4, struct ssh_gss_library);
  55. list->nlibraries = 0;
  56. /* Heimdal's GSSAPI Library */
  57. if ((gsslib = dlopen("libgssapi.so.2", RTLD_LAZY)) != NULL)
  58. gss_init(&list->libraries[list->nlibraries++], gsslib,
  59. 0, "Using GSSAPI from libgssapi.so.2");
  60. /* MIT Kerberos's GSSAPI Library */
  61. if ((gsslib = dlopen("libgssapi_krb5.so.2", RTLD_LAZY)) != NULL)
  62. gss_init(&list->libraries[list->nlibraries++], gsslib,
  63. 1, "Using GSSAPI from libgssapi_krb5.so.2");
  64. /* Sun's GSSAPI Library */
  65. if ((gsslib = dlopen("libgss.so.1", RTLD_LAZY)) != NULL)
  66. gss_init(&list->libraries[list->nlibraries++], gsslib,
  67. 2, "Using GSSAPI from libgss.so.1");
  68. /* User-specified GSSAPI library */
  69. gsspath = conf_get_filename(conf, CONF_ssh_gss_custom)->path;
  70. if (*gsspath && (gsslib = dlopen(gsspath, RTLD_LAZY)) != NULL)
  71. gss_init(&list->libraries[list->nlibraries++], gsslib,
  72. 3, dupprintf("Using GSSAPI from user-specified"
  73. " library '%s'", gsspath));
  74. return list;
  75. }
  76. void ssh_gss_cleanup(struct ssh_gss_liblist *list)
  77. {
  78. int i;
  79. /*
  80. * dlopen and dlclose are defined to employ reference counting
  81. * in the case where the same library is repeatedly dlopened, so
  82. * even in a multiple-sessions-per-process context it's safe to
  83. * naively dlclose everything here without worrying about
  84. * destroying it under the feet of another SSH instance still
  85. * using it.
  86. */
  87. for (i = 0; i < list->nlibraries; i++) {
  88. dlclose(list->libraries[i].handle);
  89. if (list->libraries[i].id == 3) {
  90. /* The 'custom' id involves a dynamically allocated message.
  91. * Note that we must cast away the 'const' to free it. */
  92. sfree((char *)list->libraries[i].gsslogmsg);
  93. }
  94. }
  95. sfree(list->libraries);
  96. sfree(list);
  97. }
  98. #elif !defined NO_GSSAPI
  99. const int ngsslibs = 1;
  100. const char *const gsslibnames[1] = {
  101. "static",
  102. };
  103. const struct keyvalwhere gsslibkeywords[] = {
  104. { "static", 0, -1, -1 },
  105. };
  106. /*
  107. * Link-time binding against GSSAPI. Here we just construct a single
  108. * library structure containing pointers to the functions we linked
  109. * against.
  110. */
  111. #include <gssapi/gssapi.h>
  112. /* Dynamically load gssapi libs. */
  113. struct ssh_gss_liblist *ssh_gss_setup(Conf *conf)
  114. {
  115. struct ssh_gss_liblist *list = snew(struct ssh_gss_liblist);
  116. list->libraries = snew(struct ssh_gss_library);
  117. list->nlibraries = 1;
  118. list->libraries[0].id = 0;
  119. list->libraries[0].gsslogmsg = "Using statically linked GSSAPI";
  120. #define BIND_GSS_FN(name) \
  121. list->libraries[0].u.gssapi.name = (t_gss_##name) gss_##name
  122. BIND_GSS_FN(delete_sec_context);
  123. BIND_GSS_FN(display_status);
  124. BIND_GSS_FN(get_mic);
  125. BIND_GSS_FN(verify_mic);
  126. BIND_GSS_FN(import_name);
  127. BIND_GSS_FN(init_sec_context);
  128. BIND_GSS_FN(release_buffer);
  129. BIND_GSS_FN(release_cred);
  130. BIND_GSS_FN(release_name);
  131. BIND_GSS_FN(acquire_cred);
  132. BIND_GSS_FN(inquire_cred_by_mech);
  133. #undef BIND_GSS_FN
  134. ssh_gssapi_bind_fns(&list->libraries[0]);
  135. return list;
  136. }
  137. void ssh_gss_cleanup(struct ssh_gss_liblist *list)
  138. {
  139. sfree(list->libraries);
  140. sfree(list);
  141. }
  142. #endif /* NO_LIBDL */
  143. #endif /* NO_GSSAPI */