Commit 505022c1 505022c18d888442b129d1c4f84ce854ddfb3eb9 by Sergey Poznyakoff

Support for GSS. Submitted by Simon Josefsson.

1 parent 84c33414
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3 3
4 GNU Mailutils is free software; you can redistribute it and/or modify 4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 5 it under the terms of the GNU General Public License as published by
...@@ -23,9 +23,21 @@ ...@@ -23,9 +23,21 @@
23 23
24 #include <netinet/in.h> 24 #include <netinet/in.h>
25 25
26 #include <krb5.h> 26 #ifdef WITH_GSS
27 #include <gssapi/gssapi.h> 27 # include <gss.h>
28 #include <gssapi/gssapi_generic.h> 28 #else
29 # include <krb5.h>
30 # ifdef HAVE_GSSAPI_H
31 # include <gssapi.h>
32 # else
33 # ifdef HAVE_GSSAPI_GSSAPI_H
34 # include <gssapi/gssapi.h>
35 # endif
36 # ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
37 # include <gssapi/gssapi_generic.h>
38 # endif
39 # endif
40 #endif
29 41
30 #define GSS_AUTH_P_NONE 1 42 #define GSS_AUTH_P_NONE 1
31 #define GSS_AUTH_P_INTEGRITY 2 43 #define GSS_AUTH_P_INTEGRITY 2
...@@ -47,11 +59,23 @@ display_status_1 (char *m, OM_uint32 code, int type) ...@@ -47,11 +59,23 @@ display_status_1 (char *m, OM_uint32 code, int type)
47 do 59 do
48 { 60 {
49 maj_stat = gss_display_status (&min_stat, code, 61 maj_stat = gss_display_status (&min_stat, code,
50 type, GSS_C_NULL_OID, &msg_ctx, &msg); 62 type, GSS_C_NO_OID, &msg_ctx, &msg);
51 syslog (LOG_ERR, _("GSS-API error %s: %s"), m, (char *) msg.value); 63 if (GSS_ERROR (maj_stat))
52 gss_release_buffer (&min_stat, &msg); 64 {
65 asprintf ((char**)&msg.value, "code %d", code);
66 msg.length = strlen (msg.value);
67 }
68
69 syslog (LOG_ERR, _("GSS-API error %s (%s): %.*s"),
70 m, type == GSS_C_GSS_CODE ? _("major") : _("minor"),
71 (int) msg.length, (char *) msg.value);
72
73 if (GSS_ERROR (maj_stat))
74 free (msg.value);
75 else
76 gss_release_buffer (&min_stat, &msg);
53 } 77 }
54 while (msg_ctx); 78 while (!GSS_ERROR (maj_stat) && msg_ctx);
55 } 79 }
56 80
57 static void 81 static void
...@@ -61,6 +85,7 @@ display_status (char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) ...@@ -61,6 +85,7 @@ display_status (char *msg, OM_uint32 maj_stat, OM_uint32 min_stat)
61 display_status_1 (msg, min_stat, GSS_C_MECH_CODE); 85 display_status_1 (msg, min_stat, GSS_C_MECH_CODE);
62 } 86 }
63 87
88 #ifndef WITH_GSS
64 static int 89 static int
65 imap4d_gss_userok (gss_buffer_t client_name, char *name) 90 imap4d_gss_userok (gss_buffer_t client_name, char *name)
66 { 91 {
...@@ -79,6 +104,7 @@ imap4d_gss_userok (gss_buffer_t client_name, char *name) ...@@ -79,6 +104,7 @@ imap4d_gss_userok (gss_buffer_t client_name, char *name)
79 krb5_free_principal (kcontext, p); 104 krb5_free_principal (kcontext, p);
80 return rc; 105 return rc;
81 } 106 }
107 #endif
82 108
83 static int 109 static int
84 auth_gssapi (struct imap4d_command *command, 110 auth_gssapi (struct imap4d_command *command,
...@@ -98,6 +124,7 @@ auth_gssapi (struct imap4d_command *command, ...@@ -98,6 +124,7 @@ auth_gssapi (struct imap4d_command *command,
98 gss_qop_t quality; 124 gss_qop_t quality;
99 gss_name_t client; 125 gss_name_t client;
100 gss_buffer_desc client_name; 126 gss_buffer_desc client_name;
127 int baduser;
101 128
102 /* Obtain server credentials. RFC 1732 states, that 129 /* Obtain server credentials. RFC 1732 states, that
103 "The server must issue a ready response with no data and pass the 130 "The server must issue a ready response with no data and pass the
...@@ -112,7 +139,7 @@ auth_gssapi (struct imap4d_command *command, ...@@ -112,7 +139,7 @@ auth_gssapi (struct imap4d_command *command,
112 tokbuf.value = tmp; 139 tokbuf.value = tmp;
113 tokbuf.length = strlen (tokbuf.value) + 1; 140 tokbuf.length = strlen (tokbuf.value) + 1;
114 maj_stat = gss_import_name (&min_stat, &tokbuf, 141 maj_stat = gss_import_name (&min_stat, &tokbuf,
115 gss_nt_service_name, &server_name); 142 GSS_C_NT_HOSTBASED_SERVICE, &server_name);
116 if (maj_stat != GSS_S_COMPLETE) 143 if (maj_stat != GSS_S_COMPLETE)
117 { 144 {
118 display_status ("import name", maj_stat, min_stat); 145 display_status ("import name", maj_stat, min_stat);
...@@ -257,7 +284,13 @@ auth_gssapi (struct imap4d_command *command, ...@@ -257,7 +284,13 @@ auth_gssapi (struct imap4d_command *command,
257 return RESP_NO; 284 return RESP_NO;
258 } 285 }
259 286
260 if (imap4d_gss_userok (&client_name, *username)) 287 #ifdef WITH_GSS
288 baduser = !gss_userok (client, *username);
289 #else
290 baduser = imap4d_gss_userok (&client_name, *username);
291 #endif
292
293 if (baduser)
261 { 294 {
262 syslog (LOG_NOTICE, _("GSSAPI user %s is NOT authorized as %s"), 295 syslog (LOG_NOTICE, _("GSSAPI user %s is NOT authorized as %s"),
263 (char *) client_name.value, *username); 296 (char *) client_name.value, *username);
......
...@@ -4,7 +4,9 @@ dnl MU_CHECK_GSSAPI(PREFIX) ...@@ -4,7 +4,9 @@ dnl MU_CHECK_GSSAPI(PREFIX)
4 dnl Search for a GSSAPI implementation in the standard locations plus PREFIX, 4 dnl Search for a GSSAPI implementation in the standard locations plus PREFIX,
5 dnl if it is set and not "yes". 5 dnl if it is set and not "yes".
6 dnl Defines GSSAPI_CFLAGS and GSSAPI_LIBS if found. 6 dnl Defines GSSAPI_CFLAGS and GSSAPI_LIBS if found.
7 dnl Defines GSSAPI_IMPL to "Heimdal", "MIT", or "OldMIT", or "none" if not found 7 dnl Defines GSSAPI_IMPL to "GSS", "Heimdal", "MIT", or "OldMIT", or
8 dnl "none" if not found
9
8 AC_DEFUN([MU_CHECK_GSSAPI], 10 AC_DEFUN([MU_CHECK_GSSAPI],
9 [ 11 [
10 if test "x$mu_cv_lib_gssapi_libs" = x; then 12 if test "x$mu_cv_lib_gssapi_libs" = x; then
...@@ -18,7 +20,25 @@ AC_DEFUN([MU_CHECK_GSSAPI], ...@@ -18,7 +20,25 @@ AC_DEFUN([MU_CHECK_GSSAPI],
18 krb5_path="$PATH" 20 krb5_path="$PATH"
19 fi 21 fi
20 AC_PATH_PROG(KRB5CFGPATH, krb5-config, none, $krb5_path) 22 AC_PATH_PROG(KRB5CFGPATH, krb5-config, none, $krb5_path)
21 if test "$KRB5CFGPATH" != "none"; then 23 AC_CHECK_HEADER(gss.h, [wantgss=yes], [wantgss=no])
24 if test $wantgss != no; then
25 save_LIBS=$LIBS
26 AC_CHECK_LIB(gss, gss_check_version, [GSSAPI_LIBS=-lgss], [wantgss=no])
27 if test $wantgss != no; then
28 LIBS="$LIBS $GSSAPI_LIBS"
29 AC_TRY_RUN([
30 #include <gss.h>
31 int main() { return gss_check_version ("0.0.9") == (char*) 0; }],
32 [:],
33 [wantgss=no],
34 [wantgss=no])
35 fi
36 LIBS=$save_LIBS
37 fi
38 if test $wantgss != no; then
39 GSSAPI_IMPL="GSS"
40 AC_DEFINE(WITH_GSS,1,[Define if mailutils is using GSS library for GSSAPI])
41 elif test "$KRB5CFGPATH" != "none"; then
22 GSSAPI_CFLAGS="$CPPFLAGS `$KRB5CFGPATH --cflags gssapi`" 42 GSSAPI_CFLAGS="$CPPFLAGS `$KRB5CFGPATH --cflags gssapi`"
23 GSSAPI_LIBS="`$KRB5CFGPATH --libs gssapi`" 43 GSSAPI_LIBS="`$KRB5CFGPATH --libs gssapi`"
24 GSSAPI_IMPL="Heimdal" 44 GSSAPI_IMPL="Heimdal"
...@@ -67,6 +87,30 @@ AC_DEFUN([MU_CHECK_GSSAPI], ...@@ -67,6 +87,30 @@ AC_DEFUN([MU_CHECK_GSSAPI],
67 LIBS="$saved_LIBS" 87 LIBS="$saved_LIBS"
68 fi 88 fi
69 89
90 saved_CPPFLAGS="$CPPFLAGS"
91 CPPFLAGS="$CPPFLAGS $GSSAPI_CFLAGS"
92 AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h)
93 AC_CHECK_DECL(GSS_C_NT_HOSTBASED_SERVICE,, [
94 AC_DEFINE(GSS_C_NT_HOSTBASED_SERVICE,
95 gss_nt_service_name,
96 [Work around buggy MIT library])],[
97 #ifdef WITH_GSS
98 # include <gss.h>
99 #else
100 # ifdef HAVE_GSSAPI_H
101 # include <gssapi.h>
102 # else
103 # ifdef HAVE_GSSAPI_GSSAPI_H
104 # include <gssapi/gssapi.h>
105 # endif
106 # ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
107 # include <gssapi/gssapi_generic.h>
108 # endif
109 # endif
110 #endif
111 ])
112 CPPFLAGS="$saved_CPPFLAGS"
113
70 mu_cv_lib_gssapi_cflags="$GSSAPI_CFLAGS" 114 mu_cv_lib_gssapi_cflags="$GSSAPI_CFLAGS"
71 mu_cv_lib_gssapi_libs="$GSSAPI_LIBS" 115 mu_cv_lib_gssapi_libs="$GSSAPI_LIBS"
72 mu_cv_lib_gssapi_impl="$GSSAPI_IMPL" 116 mu_cv_lib_gssapi_impl="$GSSAPI_IMPL"
......