summaryrefslogtreecommitdiffstats
path: root/src/appl/gssftp/ftp/ftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/appl/gssftp/ftp/ftp.c')
-rw-r--r--src/appl/gssftp/ftp/ftp.c91
1 files changed, 66 insertions, 25 deletions
diff --git a/src/appl/gssftp/ftp/ftp.c b/src/appl/gssftp/ftp/ftp.c
index f6fb15677..d19d62c20 100644
--- a/src/appl/gssftp/ftp/ftp.c
+++ b/src/appl/gssftp/ftp/ftp.c
@@ -31,6 +31,32 @@
* SUCH DAMAGE.
*/
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
#ifndef lint
static char sccsid[] = "@(#)ftp.c 5.38 (Berkeley) 4/22/91";
#endif /* not lint */
@@ -95,11 +121,13 @@ MSG_DAT msg_data;
#endif /* KRB5_KRB4_COMPAT */
#ifdef GSSAPI
#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_generic.h>
+/* need to include the krb5 file, because we're doing manual fallback
+ from the v2 mech to the v2 mech. Once there's real negotiation,
+ we can be generic again. */
+#include <gssapi/gssapi_krb5.h>
gss_ctx_id_t gcontext;
#endif /* GSSAPI */
-
static int kerror; /* XXX needed for all auth types */
char *auth_type; /* Authentication succeeded? If so, what type? */
@@ -308,7 +336,8 @@ login(host)
if (pass == NULL)
pass = mygetpass("Password:");
#ifndef NOENCRYPTION
- if ((oldclevel = clevel) == PROT_S) clevel = PROT_P;
+ oldclevel = clevel;
+ clevel = PROT_P;
#endif
n = command("PASS %s", pass);
#ifndef NOENCRYPTION
@@ -1843,8 +1872,16 @@ char realm[REALM_SZ + 1];
#endif /* KRB5_KRB4_COMPAT */
#ifdef GSSAPI
-/* for testing, we don't have an ftp key yet */
-char* gss_services[] = { "ftp", "host", 0 };
+struct {
+ const gss_OID_desc * const * mech_type;
+ char *service_name;
+} gss_trials[] = {
+ { &gss_mech_krb5_v2, "ftp" },
+ { &gss_mech_krb5, "ftp" },
+ { &gss_mech_krb5_v2, "host" },
+ { &gss_mech_krb5, "host" },
+};
+int n_gss_trials = sizeof(gss_trials)/sizeof(gss_trials[0]);
#endif /* GSSAPI */
do_auth()
@@ -1870,8 +1907,7 @@ do_auth()
gss_name_t target_name;
gss_buffer_desc send_tok, recv_tok, *token_ptr;
char stbuf[FTP_BUFSIZ];
- char **service_name, **end_service_name;
- int comcode;
+ int comcode, trial;
struct gss_channel_bindings_struct chan;
chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */
chan.initiator_address.length = 4;
@@ -1882,21 +1918,15 @@ do_auth()
chan.application_data.length = 0;
chan.application_data.value = 0;
- for (end_service_name = gss_services; *end_service_name; )
- end_service_name++;
- end_service_name--;
-
if (verbose)
- printf("%s accepted as authentication type\n", "GSSAPI");
+ printf("GSSAPI accepted as authentication type\n");
/* blob from gss-client */
-
- for (service_name = gss_services; *service_name; service_name++) {
-
+ for (trial = 0; trial < n_gss_trials; trial++) {
/* ftp@hostname first, the host@hostname */
/* the V5 GSSAPI binding canonicalizes this for us... */
- sprintf(stbuf, "%s@%s", *service_name, hostname);
+ sprintf(stbuf, "%s@%s", gss_trials[trial].service_name, hostname);
if (debug)
fprintf(stderr, "Trying to authenticate to <%s>\n", stbuf);
@@ -1922,7 +1952,7 @@ do_auth()
GSS_C_NO_CREDENTIAL,
&gcontext,
target_name,
- GSS_C_NULL_OID,
+ *gss_trials[trial].mech_type,
GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
(forward ? GSS_C_DELEG_FLAG : 0),
0,
@@ -1935,7 +1965,7 @@ do_auth()
if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED){
- if (service_name == end_service_name)
+ if (trial == n_gss_trials-1)
user_gss_error(maj_stat, min_stat, "initializing context");
(void) gss_release_name(&min_stat, &target_name);
/* could just be that we missed on the service name */
@@ -1946,16 +1976,28 @@ do_auth()
int len = send_tok.length;
reply_parse = "ADAT="; /* for command() later */
oldverbose = verbose;
- verbose = 0;
+ verbose = (trial == n_gss_trials-1)?0:-1;
kerror = radix_encode(send_tok.value, out_buf, &len, 0);
if (kerror) {
fprintf(stderr, "Base 64 encoding failed: %s\n",
radix_error(kerror));
} else if ((comcode = command("ADAT %s", out_buf))!=COMPLETE
/* && comcode != 3 (335)*/) {
- fprintf(stderr, "GSSAPI ADAT failed\n");
- /* force out of loop */
- maj_stat = GSS_S_FAILURE;
+ if (trial == n_gss_trials-1) {
+ fprintf(stderr, "GSSAPI ADAT failed\n");
+ /* force out of loop */
+ maj_stat = GSS_S_FAILURE;
+ }
+ /* backoff to the v1 gssapi is still possible. Send
+ a new AUTH command. If that fails, terminate the
+ loop */
+ if (command("AUTH %s", "GSSAPI") != CONTINUE) {
+ fprintf(stderr,
+ "GSSAPI ADAT failed, AUTH restart failed\n");
+ /* force out of loop */
+ maj_stat = GSS_S_FAILURE;
+ }
+ goto outer_loop;
} else if (!reply_parse) {
fprintf(stderr,
"No authentication data received from server\n");
@@ -1979,7 +2021,7 @@ do_auth()
/* get out of loop clean */
gss_complete_loop:
- service_name = end_service_name;
+ trial = n_gss_trials-1;
gss_release_buffer(&min_stat, &send_tok);
gss_release_name(&min_stat, &target_name);
goto outer_loop;
@@ -1991,8 +2033,7 @@ do_auth()
}
verbose = oldverbose;
if (maj_stat == GSS_S_COMPLETE) {
- if (verbose)
- printf("GSSAPI authentication succeeded\n");
+ printf("GSSAPI authentication succeeded\n");
reply_parse = NULL;
auth_type = "GSSAPI";
return(1);