uxgss.c 4.5 KB

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