diff options
Diffstat (limited to 'src/appl/gssftp/ftp/ftp.c')
-rw-r--r-- | src/appl/gssftp/ftp/ftp.c | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/src/appl/gssftp/ftp/ftp.c b/src/appl/gssftp/ftp/ftp.c index f6fb156773..d19d62c206 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); |