Gets a bit closer, still not working..
authorKen Raeburn <raeburn@mit.edu>
Sat, 13 Dec 2003 18:16:57 +0000 (18:16 +0000)
committerKen Raeburn <raeburn@mit.edu>
Sat, 13 Dec 2003 18:16:57 +0000 (18:16 +0000)
* ftpcmd.y (getline): Allow "AUTH" as an unprotected command.
* ftpd.c (login): Fix checks for accept_sec_context status.  Only send back one
message in the CONTINUE_NEEDED case.
(with_gss_error_text): New function, split out from reply_gss_error.
(reply_gss_error): Call it.
(reply_gss_error_1): New function.
(log_gss_error, log_gss_error_1): New functions.
(login): Call log_gss_error instead of syslog on error from gss_display_name.

ticket: 2062
status: open

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15917 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/gssftp/ftpd/ChangeLog
src/appl/gssftp/ftpd/ftpcmd.y
src/appl/gssftp/ftpd/ftpd.c

index 73814761b6ff6bc745061bd4d4b0ad3bacb330ad..d378f73921484e573bbd875437a1e592aaffe1c6 100644 (file)
@@ -1,3 +1,16 @@
+2003-12-13  Ken Raeburn  <raeburn@mit.edu>
+
+       * ftpcmd.y (getline): Allow "AUTH" as an unprotected command.
+       * ftpd.c (login): Fix checks for accept_sec_context status.  Only
+       send back one message in the CONTINUE_NEEDED case.
+       (with_gss_error_text): New function, split out from
+       reply_gss_error.
+       (reply_gss_error): Call it.
+       (reply_gss_error_1): New function.
+       (log_gss_error, log_gss_error_1): New functions.
+       (login): Call log_gss_error instead of syslog on error from
+       gss_display_name.
+
 2003-06-05  Sam Hartman  <hartmans@mit.edu>
 
        * popen.c (ftpd_popen): Use fork not vfork
index bb5b7130e9d5c9fbfebc82cfb3837d77ff02c307..db50d5bfbd58a10aad83a37195893897a543ce11 100644 (file)
@@ -1040,6 +1040,7 @@ getline(s, n, iop)
 
            /* Check to see if we have a protected command. */
            if (!((mic = strncmp(s, "ENC", 3)) && strncmp(s, "MIC", 3)
+               && strncmp(s, "AUTH", 4)
 #ifndef NOCONFIDENTIAL
                && strncmp(s, "CONF", 4)
 #endif
index 2a09bf3d08031f2c8c167070186787886d79cee2..73b36673e74d6bdde8de1a5a833e01c1efff0b2d 100644 (file)
@@ -154,6 +154,8 @@ krb5_ccache ccache;
 static void ftpd_gss_convert_creds(char *name, gss_cred_id_t);
 static int ftpd_gss_userok(gss_buffer_t, char *name);
 
+static void log_gss_error(int, OM_uint32, OM_uint32, const char *);
+
 #endif /* GSSAPI */
 
 char *auth_type;       /* Authentication succeeded?  If so, what type? */
@@ -2502,18 +2504,18 @@ char *adata;
                                                                &deleg_creds);
                                return(0);
                        }
-                       if (stat_maj == GSS_S_COMPLETE) {
+                       if (accept_maj == GSS_S_COMPLETE) {
                                reply(235, "ADAT=%s", gbuf);
-                               replied = 1;
                        } else {
                                /* If the server accepts the security data, and
                                   requires additional data, it should respond
                                   with reply code 335. */
                                reply(335, "ADAT=%s", gbuf);
                        }
+                       replied = 1;
                        (void) gss_release_buffer(&stat_min, &out_tok);
                }
-               if (stat_maj == GSS_S_COMPLETE) {
+               if (accept_maj == GSS_S_COMPLETE) {
                        /* GSSAPI authentication succeeded */
                        stat_maj = gss_display_name(&stat_min, client,
                                                    &client_name, &mechid);
@@ -2523,7 +2525,8 @@ char *adata;
                                   respond with reply code 535." */
                                reply_gss_error(535, stat_maj, stat_min,
                                                "extracting GSSAPI identity name");
-                               syslog(LOG_ERR, "gssapi error extracting identity");
+                               log_gss_error(LOG_ERR, stat_maj, stat_min,
+                                             "gssapi error extracting identity");
                                (void) gss_release_cred(&stat_min, &server_creds);
                                if (ret_flags & GSS_C_DELEG_FLAG)
                                        (void) gss_release_cred(&stat_min,
@@ -2554,11 +2557,12 @@ char *adata;
                          }
                                
                        return(1);
-               } else if (stat_maj == GSS_S_CONTINUE_NEEDED) {
+               } else if (accept_maj == GSS_S_CONTINUE_NEEDED) {
                        /* If the server accepts the security data, and
                           requires additional data, it should respond with
                           reply code 335. */
-                       reply(335, "more data needed");
+                       if (!replied)
+                           reply(335, "more data needed");
                        (void) gss_release_cred(&stat_min, &server_creds);
                        if (ret_flags & GSS_C_DELEG_FLAG)
                          (void) gss_release_cred(&stat_min, &deleg_creds);
@@ -2806,11 +2810,44 @@ char *buf;
 #endif /* SETPROCTITLE */
 
 #ifdef GSSAPI
+/* A more general callback would probably use a void*, but currently I
+   only need an int in both cases.  */
+static void with_gss_error_text(void (*cb)(const char *, int, int),
+                               OM_uint32 maj_stat, OM_uint32 min_stat,
+                               int misc);
+
+static void
+log_gss_error_1(const char *msg, int severity, int is_major)
+{
+    syslog(severity, "... GSSAPI error %s: %s",
+          is_major ? "major" : "minor", msg);
+}
+
+static void
+log_gss_error(int severity, OM_uint32 maj_stat, OM_uint32 min_stat,
+             const char *s)
+{
+    syslog(severity, s);
+    with_gss_error_text(log_gss_error_1, maj_stat, min_stat, severity);
+}
+
+static void
+reply_gss_error_1(const char *msg, int code, int is_major)
+{
+    lreply(code, "GSSAPI error %s: %s",
+          is_major ? "major" : "minor", msg);
+}
+
 void
-reply_gss_error(code, maj_stat, min_stat, s)
-int code;
-OM_uint32 maj_stat, min_stat;
-char *s;
+reply_gss_error(int code, OM_uint32 maj_stat, OM_uint32 min_stat, char *s)
+{
+    with_gss_error_text(reply_gss_error_1, maj_stat, min_stat, code);
+    reply(code, "GSSAPI error: %s", s);
+}
+
+static void with_gss_error_text(void (*cb)(const char *, int, int),
+                               OM_uint32 maj_stat, OM_uint32 min_stat,
+                               int misc)
 {
        /* a lot of work just to report the error */
        OM_uint32 gmaj_stat, gmin_stat;
@@ -2824,8 +2861,7 @@ char *s;
                                               &msg_ctx, &msg);
                if ((gmaj_stat == GSS_S_COMPLETE)||
                    (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
-                       lreply(code, "GSSAPI error major: %s", 
-                              (char*)msg.value);
+                       (*cb)((char*)msg.value, misc, 1);
                        (void) gss_release_buffer(&gmin_stat, &msg);
                }
                if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
@@ -2839,14 +2875,12 @@ char *s;
                                               &msg_ctx, &msg);
                if ((gmaj_stat == GSS_S_COMPLETE)||
                    (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
-                       lreply(code, "GSSAPI error minor: %s",
-                              (char*)msg.value);
+                       (*cb)((char*)msg.value, misc, 0);
                        (void) gss_release_buffer(&gmin_stat, &msg);
                }
                if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
                        break;
        }
-       reply(code, "GSSAPI error: %s", s);
 }
 
 void