aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Andree <matthias.andree@gmx.de>2010-08-20 10:46:10 +0200
committerMatthias Andree <matthias.andree@gmx.de>2010-08-20 10:55:07 +0200
commite5510f67f15d893bb476a0db5b2de702129e122c (patch)
treef10e8c21e141cf914be79dc6a9eabcbf8fcb8a01
parent19dc52bcc681165a99e50c6b4d68af2f88d1645c (diff)
downloadfetchmail-e5510f67f15d893bb476a0db5b2de702129e122c.tar.gz
fetchmail-e5510f67f15d893bb476a0db5b2de702129e122c.tar.bz2
fetchmail-e5510f67f15d893bb476a0db5b2de702129e122c.zip
Decode and report GSSAPI errors in more detail.
-rw-r--r--NEWS1
-rw-r--r--gssapi.c34
2 files changed, 34 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 0dc73a93..46658db7 100644
--- a/NEWS
+++ b/NEWS
@@ -78,6 +78,7 @@ fetchmail-6.3.18 (not yet released):
# CHANGES
* When encountering incorrect headers, fetchmail will refer to the bad-header
option in the manpage. BerliOS Bug #17272, change suggested by Björn Voigt.
+* Fetchmail now decodes and reports GSSAPI status codes upon errors.
# KNOWN BUGS AND WORKAROUNDS:
(this section floats upwards through the NEWS file so it stays with the
diff --git a/gssapi.c b/gssapi.c
index 1784de55..7fc78629 100644
--- a/gssapi.c
+++ b/gssapi.c
@@ -38,6 +38,33 @@
# endif
# endif
+static void decode_subr(const char *m, uint32_t code, int type)
+{
+ uint32_t maj, min, context;
+ gss_buffer_desc msg = GSS_C_EMPTY_BUFFER;
+
+ context = 0;
+ do {
+ maj = gss_display_status(&min, code, type, GSS_C_NO_OID,
+ &context, &msg);
+
+ if (maj != GSS_S_COMPLETE) {
+ report(stderr, GT_("GSSAPI error in gss_display_status called from <%s>\n"), m);
+ break;
+ }
+ report(stderr, GT_("GSSAPI error %s: %s\n"), m,
+ msg.value ? (char *)msg.value : GT_("(null)"));
+ if (msg.length)
+ (void)gss_release_buffer(&min, &msg);
+ } while(context);
+}
+
+static void decode_status(const char *m, uint32_t major, uint32_t minor)
+{
+ decode_subr(m, major, GSS_C_GSS_CODE);
+ decode_subr(m, minor, GSS_C_MECH_CODE);
+}
+
#define GSSAUTH_P_NONE 1
#define GSSAUTH_P_INTEGRITY 2
#define GSSAUTH_P_PRIVACY 4
@@ -64,6 +91,7 @@ int do_gssauth(int sock, const char *command, const char *service,
maj_stat = gss_import_name(&min_stat, &request_buf, GSS_C_NT_HOSTBASED_SERVICE,
&target_name);
if (maj_stat != GSS_S_COMPLETE) {
+ decode_status("gss_import_name", maj_stat, min_stat);
report(stderr, GT_("Couldn't get service name for [%s]\n"), buf1);
return PS_AUTHFAIL;
}
@@ -104,8 +132,10 @@ int do_gssauth(int sock, const char *command, const char *service,
NULL,
NULL);
if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) {
- report(stderr, GT_("Error exchanging credentials\n"));
+ decode_status("gss_init_sec_context", maj_stat, min_stat);
gss_release_name(&min_stat, &target_name);
+ report(stderr, GT_("Error exchanging credentials\n"));
+
/* wake up server and await NO response */
SockWrite(sock, "\r\n", 2);
result = gen_recv(sock, buf1, sizeof buf1);
@@ -149,6 +179,7 @@ int do_gssauth(int sock, const char *command, const char *service,
maj_stat = gss_unwrap(&min_stat, context,
&request_buf, &send_token, &cflags, &quality);
if (maj_stat != GSS_S_COMPLETE) {
+ decode_status("gss_unwrap", maj_stat, min_stat);
report(stderr, GT_("Couldn't unwrap security level data\n"));
gss_release_buffer(&min_stat, &send_token);
return PS_AUTHFAIL;
@@ -198,6 +229,7 @@ int do_gssauth(int sock, const char *command, const char *service,
report(stdout, GT_("Releasing GSS credentials\n"));
maj_stat = gss_delete_sec_context(&min_stat, &context, &send_token);
if (maj_stat != GSS_S_COMPLETE) {
+ decode_status("gss_delete_sec_context", maj_stat, min_stat);
report(stderr, GT_("Error releasing credentials\n"));
return PS_AUTHFAIL;
}