/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 1985, 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "ftp_var.h"
#include <gssapi/gssapi_ext.h>
char *radix_error(int);
static char *radixN =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
* authenticate the user, if auth_type is AUTHTYPE_NONE
*
* Returns: 0 if there is no auth type
* 1 if success
* 2 if failure
*/
/* the number of elements in gss_trials array */
char *reply_parse;
int
do_auth(void)
{
int i;
if (auth_type != AUTHTYPE_NONE)
return (1); /* auth already succeeded */
/* Other auth types go here ... */
int req_flags;
if (verbose)
(void) printf("GSSAPI accepted as authentication type\n");
/* set the forward flag */
if (fflag)
/* blob from gss-client */
/* ftp@hostname first, then host@hostname */
/* the V5 GSSAPI binding canonicalizes this for us... */
if (debug)
"Trying to authenticate to <%s>\n", stbuf);
if (maj_stat != GSS_S_COMPLETE) {
continue;
}
do {
if (debug)
"calling gss_init_sec_context\n");
(void) printf("do_auth: %s: not a valid "
"security mechanism\n", mechstr);
if (!mechoid)
&gcontext,
0,
&chan, /* channel bindings */
NULL, /* ignore mech type */
&send_tok,
NULL, /* ignore ret_flags */
NULL); /* ignore time_rec */
if (maj_stat != GSS_S_COMPLETE &&
/* return an error if this is NOT the ftp ticket */
"initializing context");
/* could just be that we missed on the service name */
goto outer_loop;
}
"auth buffer\n");
goto outer_loop;
}
if (auth_error) {
!= COMPLETE /* && comcode != 3 (335)*/) {
comcode);
/* force out of loop */
}
/*
* backoff to the v1 gssapi is still possible.
* Send a new AUTH command. If that fails,
* terminate the loop
*/
"GSSAPI ADAT failed, AUTH restart failed\n");
/* force out of loop */
}
goto outer_loop;
} else if (!reply_parse) {
"No authentication data received from server\n");
if (maj_stat == GSS_S_COMPLETE) {
"...but no more was needed\n");
goto gss_complete_loop;
} else {
goto gss_complete_loop;
}
"Base 64 decoding failed: %s\n",
} else {
/* everything worked */
continue;
} /* end if (auth_error) */
/* get out of loop clean */
goto outer_loop;
} /* end if (send_tok.length != 0) */
} while (maj_stat == GSS_S_CONTINUE_NEEDED);
if (maj_stat == GSS_S_COMPLETE)
break;
} /* end for loop */
if (maj_stat == GSS_S_COMPLETE) {
(void) printf("GSSAPI authentication succeeded\n");
reply_parse = NULL;
return (1);
} else {
reply_parse = NULL;
}
} /* end if (command...) */
/* Other auth types go here ... */
return (0);
}
/*
* Get the information for the channel structure.
*/
void
{
char *value;
return;
}
/* get the initiator address.value and address.length */
(struct sockaddr_in6 *)in_ipaddr;
&in_ipv4addr);
} else {
length);
}
} else {
length);
}
}
int
{
int i, j, D;
char *p;
uchar_t c;
if (decode) {
for (i = j = 0;
i++) {
return (1);
D = p - radixN;
switch (i&3) {
case 0:
outbuf[j] = D<<2;
break;
case 1:
outbuf[j++] |= D>>4;
break;
case 2:
outbuf[j++] |= D>>2;
break;
case 3:
outbuf[j++] |= D;
}
}
return (4);
}
switch (i&3) {
case 1: return (3);
case 2: if (D&15)
return (3);
return (2);
break;
case 3: if (D&3)
return (3);
return (2);
}
*outlen = j;
} else {
switch (i%3) {
case 0:
break;
case 1:
break;
case 2:
c = 0;
}
return (4);
}
if (i%3)
switch (i%3) {
case 1:
/* FALLTHROUGH */
case 2:
break;
}
}
return (0);
}
char *
radix_error(int e)
{
switch (e) {
case 0: return ("Success");
case 1: return ("Bad character in encoding");
case 2: return ("Encoding not properly padded");
case 3: return ("Decoded # of bits not a multiple of 8");
case 4: return ("Buffer size error");
default: return ("Unknown error");
}
}