/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "ftp_var.h"
/*
* WRITE() returns:
* >0 no error
* -1 error, errorno is set
* -2 security error (secure_write() only)
*/
static int abrtflag = 0;
static int ptflag = 0;
int connected;
static int ptabflg;
/*
*
* Perform EPSV if passivemode is set and ipv6rem is TRUE.
*/
static int initconn(void);
static int secure_command(char *);
static int fdio_fillbuf(int fd);
static int fdio_error(int fd);
((unsigned char)*bufp++))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
static void
{
bufcnt = 0;
buferr = 0;
}
static int
{
if (bufcnt < 0)
if (bufcnt <= 0)
return (EOF);
bufcnt--;
return ((unsigned char)*bufp++);
}
/*
* fdio_error - used on a file descriptor instead of ferror()
*/
/*ARGSUSED*/
static int
{
return (buferr);
}
/*
* timedread - read buffer (like "read"), but with timeout (in seconds)
*/
static ssize_t
{
int err;
if (!timeout)
if (err == 0)
if (err <= 0)
return (-1);
}
char *
{
int s;
int error_num;
/*
* There appears to be a bug in getaddrinfo() where, if the
* ai_family is set to AF_INET6, and the host is a v4-only
* host, getaddrinfo() returns an error instead of returning
* an v4-mapped ipv6 address. Therefore the ai_family is
* set to AF_UNSPEC and any returned v4 addresses are
* explicitly mapped within ftp.
*/
if (error_num != 0) {
(void) printf(
"%s: unknown host or invalid literal address "
"(try again later)\n", host);
} else {
(void) printf(
"%s: unknown host or invalid literal address\n",
host);
}
code = -1;
return ((char *)0);
}
/*
* If ai_canonname is a IPv4-mapped IPv6 literal, we'll convert it to
* IPv4 literal address.
*/
hostnamebuf[0] = '\0';
sizeof (hostnamebuf));
/*
* It can even be the case that the "host" supplied by the user
* can be a IPv4-mapped IPv6 literal. So, let's fix that too.
*/
}
} else {
reset_timer();
(void) strlcpy(hostnamebuf,
sizeof (hostnamebuf));
}
for (;;) {
int oerrno;
}
if (s < 0) {
perror("ftp: socket");
code = -1;
return (0);
}
perror("ftp: setsockopt (TCP_ABORT_THRESHOLD)");
reset_timer();
sizeof (remctladdr));
if (error_num >= 0)
break;
/*
* Maintain message behavior: only include the address in
* our error message if we have another one to try; if this
* is the last address on our list, just print the error.
*/
perror((char *)0);
} else {
perror("ftp: connect");
code = -1;
goto bad;
}
(void) close(s);
}
/* Set ipv6rem to TRUE if control connection is a native IPv6 address */
else
/*
* Set passive mode flag on by default only if a native IPv6 address
* is being used -and- the use_eprt is not set.
*/
passivemode = 1;
perror("ftp: getsockname");
code = -1;
goto bad;
}
if (ctrl_in)
if (ctrl_out)
code = -1;
goto bad;
}
if (verbose)
if (ctrl_in)
if (ctrl_out)
code = -1;
goto bad;
}
perror("ftp: setsockopt (SO_OOBINLINE)");
return (hostname);
bad:
(void) close(s);
return ((char *)0);
}
int
{
int n, aflag = 0;
disconnect(0, NULL);
code = -1;
return (0);
}
}
stop_timer();
*tmp = '\0';
if (*tmp != '\0')
else
return (0);
}
if (n == CONTINUE) {
int oldclevel;
/* level may have changed */
}
if (n == CONTINUE) {
aflag++;
}
if (n != COMPLETE) {
return (0);
}
if (proxy)
return (1);
for (n = 0; n < macnum; ++n) {
makeargv();
break;
}
}
return (1);
}
/*ARGSUSED*/
static void
{
(void) printf("\n");
abrtflag++;
if (ptflag)
}
int
{
int r;
void (*oldintr)();
abrtflag = 0;
if (debug) {
(void) printf("---> ");
(void) printf("PASS XXXX");
(void) printf("ACCT XXXX");
else
(void) printf("\n");
}
perror("No control connection for command");
code = -1;
return (0);
}
return (0);
cpend = 1;
"retrying under MIC...\n");
goto again;
}
(*oldintr)();
return (r);
}
/* Need to save reply reponse from server for use in EPSV mode */
int
{
/*
* 'code' is the 3 digit reply code, form xyz
* 'dig' counts the number of digits we are along in the code
* 'n' is the first digit of 'code'
* 4yz: resource unavailable
* 5yz: an error occurred, failure
* 6yz: protected reply (is_base64 == TRUE)
* 631 - base 64 encoded safe message
* 632 - base 64 encoded private message
* 633 - base 64 encoded confidential message
* 'c' is a wide char type, for international char sets
*/
wint_t c;
int i, n;
int dig;
void (*oldintr)();
int pflag = 0;
/*
* this is the input and output buffers needed for
* radix_encode()
*/
int len;
char *cp;
if (!ctrl_in)
return (0);
ibuf[0] = '\0';
if (reply_parse)
for (;;) {
obuf[0] = '\0';
i = is_base64 = 0;
cp = reply_string;
reset_timer(); /* once per line */
while ((c = ibuf[0] ?
if (i >= FTPBUFSIZ)
break;
if (c == IAC) { /* handle telnet commands */
case WILL:
case WONT:
WONT, c);
break;
case DO:
case DONT:
DONT, c);
break;
default:
break;
}
continue;
}
dig++;
if (c == EOF) {
if (expecteof) {
code = 221;
return (0);
}
lostpeer(0);
if (verbose) {
(void) printf(
"421 Service not available, remote"
" server has closed connection\n");
} else
(void) printf("Lost connection\n");
code = 421;
return (4);
}
if (n == 0)
n = c;
if (n == '6')
is_base64 = 1;
(is_base64 || continuation)) {
/* start storing chars in obuf */
obuf[i++] = (char)c;
} else {
(void) printf("Unauthenticated reply received "
"from server:\n");
if (reply_parse)
*reply_ptr++ = (char)c;
if (c != '\r' && (verbose > 0 ||
if (proxflag &&
(void) putwchar(c);
}
} /* endif auth_type && !ibuf[0] ... */
continue;
/* we are still extracting the 3 digit code */
/* starting passive mode */
pflag = 1;
/* start to store characters, when dig > 4 */
pflag = 2;
if (pflag == 2) {
if (c != '\r' && c != ')') {
/* the mb array is to deal with the wchar_t */
int avail;
/*
* space available in pasv[], accounting
* for trailing NULL
*/
*pt++ = (unsigned char)c;
} else {
/*
* no room in pasv[];
* close connection
*/
(void) printf("\nReply too long - "
"closing connection\n");
lostpeer(0);
return (4);
}
} else {
*pt = '\0';
pflag = 3;
}
} /* endif pflag == 2 */
if (continuation)
code = 0;
continuation++;
}
*cp++ = c;
} /* end while */
if (again)
continue;
} else
(void) putwchar(c);
}
if (originalcode == 0)
originalcode = code;
continue;
}
*cp = '\0';
if (n != '1')
cpend = 0;
lostpeer(0);
(*oldintr)();
if (reply_parse) {
*reply_ptr = '\0';
*reply_ptr = '\0';
} else
}
return (n - '0');
} /* end for */
}
static int
{
struct timeval t;
reset_timer();
t.tv_usec = 0;
}
/*ARGSUSED*/
static void
{
mflag = 0;
abrtflag = 0;
(void) printf("\nsend aborted\n");
}
void
{
int (*closefunc)();
int c;
/*
* d >= 0 if there is no error
* -1 if there was a normal file i/o error
* -2 if there was a security error
*/
int d;
char *dmode;
if (proxy) {
return;
}
dmode = "w";
while (cpend) {
(void) getreply(0);
}
if (data >= 0) {
data = -1;
}
if (oldintr)
if (oldintp)
code = -1;
restart_point = 0;
return;
}
code = -1;
restart_point = 0;
return;
}
} else {
code = -1;
restart_point = 0;
return;
}
"%s: not a plain file.\n", local);
code = -1;
restart_point = 0;
return;
}
}
if (initconn()) {
if (oldintp)
code = -1;
restart_point = 0;
return;
}
goto abort;
if ((restart_point > 0) &&
restart_point = 0;
return;
}
!= CONTINUE) {
restart_point = 0;
return;
}
dmode = "r+w";
}
restart_point = 0;
if (remote) {
if (oldintp)
if (data >= 0) {
data = -1;
}
return;
}
} else
if (oldintp)
if (data >= 0) {
data = -1;
}
return;
}
goto abort;
stop_timer();
switch (type) {
case TYPE_I:
case TYPE_L:
errno = d = 0;
break;
bytes += c;
if (hash) {
(void) putchar('#');
}
}
}
(void) putchar('#');
(void) putchar('\n');
}
if (c < 0)
if (d >= 0)
if (d < 0) {
perror("netout");
bytes = -1;
}
break;
case TYPE_A:
if (c == '\n') {
(void) putchar('#');
}
break;
bytes++;
}
break;
bytes++;
#ifdef notdef
if (c == '\r') {
/* this violates rfc */
bytes++;
}
#endif
}
(void) putchar('#');
(void) putchar('\n');
}
if (d == 0)
if (d < 0) {
perror("netout");
bytes = -1;
}
break;
}
reset_timer();
/*
* There could be data not yet written to dout,
* in the stdio buffer; so, before a shutdown()
* on further sends, do fflush(dout)
*/
/* sending over; shutdown sending on dfn */
/*
* Wait for remote end to either close data socket
* or ack that we've closed our end; it doesn't
* matter which happens first.
*/
}
(void) getreply(0);
if (oldintp)
/*
* Only print the transfer successful message if the code returned
* from remote is 226 or 250. All other codes are error codes.
*/
if (!ctrl_in)
(void) printf("Lost connection\n");
return;
if (oldintp)
if (!cpend) {
code = -1;
return;
}
if (data >= 0) {
data = -1;
}
if (dout) {
data = -1;
}
(void) getreply(0);
code = -1;
/*
* Only print the transfer successful message if the code returned
* from remote is 226 or 250. All other codes are error codes.
*/
if (!ctrl_in)
(void) printf("Lost connection\n");
restart_point = 0;
}
/*ARGSUSED*/
static void
{
mflag = 0;
abrtflag = 0;
(void) printf("\n");
}
void
{
int (*closefunc)();
char msg;
int c, d, n;
int errflg = 0;
int infd;
int nfds;
int retrcmd;
return;
}
while (cpend) {
(void) getreply(0);
}
if (data >= 0) {
data = -1;
}
if (oldintr)
code = -1;
return;
}
code = -1;
return;
}
*dir = 0;
else
*dir = '/';
if (d < 0) {
code = -1;
return;
}
errno = file_errno;
code = -1;
return;
}
code = -1;
return;
}
code = -1;
return;
}
}
if (initconn()) {
code = -1;
return;
}
goto abort;
if (!debug)
verbose = 0;
}
if ((restart_point > 0) && retrcmd &&
return;
}
if (remote) {
if (oldtype) {
if (!debug)
verbose = 0;
switch (oldtype) {
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
}
return;
}
} else {
if (oldtype) {
if (!debug)
verbose = 0;
switch (oldtype) {
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
}
return;
}
}
goto abort;
goto abort;
}
} else {
goto abort;
}
}
stop_timer();
switch (type) {
case TYPE_I:
case TYPE_L:
if ((restart_point > 0) && retrcmd &&
goto abort;
}
errno = d = 0;
for (n = 0; n < c; n += d) {
if (d == -1)
goto writeerr;
}
bytes += c;
if (hash) {
(void) putchar('#');
}
}
}
(void) putchar('#');
(void) putchar('\n');
}
if (c < 0) {
errflg = 1;
perror("netin");
}
errflg = 1;
}
break;
case TYPE_A:
if ((restart_point > 0) && retrcmd) {
int c;
off_t i = 0;
goto abort;
}
while (i++ < restart_point) {
else
"%s: Unexpected end of file\n",
local);
goto abort;
}
if (c == '\n')
i++;
}
goto abort;
}
}
while (c == '\r') {
(void) putchar('#');
}
bytes++;
break;
goto writer_ascii_err;
}
#ifdef notdef
if (c == '\0') {
bytes++;
continue;
}
#endif
if (c == EOF)
goto endread;
}
goto writer_ascii_err;
bytes++;
}
(void) putchar('#');
(void) putchar('\n');
}
if (fdio_error(infd)) {
errflg = 1;
perror("netin");
}
errflg = 1;
}
break;
}
reset_timer();
if (oldintp)
(void) getreply(0);
if (!ctrl_in)
(void) printf("Lost connection\n");
if (oldtype) {
if (!debug)
verbose = 0;
switch (oldtype) {
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
}
return;
/* abort using RFC959 recommended IP, SYNC sequence */
if (oldintp)
if (!cpend) {
code = -1;
return;
}
/*
* send IAC in urgent mode instead of DM because UNIX places oob
* mark after urgent byte rather than before as now is protocol
*/
perror("abort");
}
if (din) {
}
if (nfnd < 0) {
perror("abort");
}
code = -1;
lostpeer(0);
}
do {
reset_timer();
}
/* needed for nic style abort */
if (data >= 0) {
data = -1;
}
(void) getreply(0);
}
if (oldtype) {
if (!debug)
verbose = 0;
switch (oldtype) {
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
}
(void) getreply(0);
code = -1;
if (data >= 0) {
data = -1;
}
if (din) {
data = -1;
}
if (!ctrl_in)
(void) printf("Lost connection\n");
}
/*
* Need to start a listen on the data channel
* before we send the command, otherwise the
* server's connect may fail.
*/
static int
initconn(void)
{
unsigned char *p, *a;
int v4_addr;
if (passivemode) {
if (data < 0) {
perror("socket");
return (1);
}
TCP_ABORT_THRESHOLD, (char *)&timeoutms,
perror("ftp: setsockopt (TCP_ABORT_THRESHOLD)");
sizeof (on)) < 0)
perror("setsockopt (ignored)");
/*
* Use the system wide default send and receive buffer sizes
* unless one has been specified.
*/
if (tcpwindowsize) {
(char *)&tcpwindowsize, sizeof (tcpwindowsize)) < 0)
perror("ftp: setsockopt (SO_SNDBUF - ignored)");
(char *)&tcpwindowsize, sizeof (tcpwindowsize)) < 0)
perror("ftp: setsockopt (SO_RCVBUF - ignored)");
}
"Passive mode refused. Try EPRT\n");
goto noport;
}
/*
* Get the data port from reply string from the
* server. The format of the reply string is:
* 229 Entering Extended Passive Mode (|||port|)
* where | is the delimiter being used.
*/
"parsing failure.\n");
goto bad;
}
/* Delimiter is the next char in the reply string */
delm = *(++c);
while (*c == delm) {
if (!*(c++)) {
"Extended passive mode"
"parsing failure.\n");
goto bad;
}
}
/* assign the port for data connection */
} else {
"Passive mode refused. Try PORT\n");
goto noport;
}
/*
* Get the data port from reply string from the
* server. The format of the reply string is:
* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)
*/
"Passive mode parsing failure.\n");
goto bad;
}
/*
* Set the supplied address and port in an
* IPv4-mapped IPv6 address.
*/
sizeof (struct in6_addr) -
sizeof (struct in_addr);
}
sizeof (data_addr)) < 0) {
perror("connect");
goto bad;
}
return (0);
}
if (sendport)
if (data != -1)
if (data < 0) {
perror("ftp: socket");
if (tmpno)
sendport = 1;
return (1);
}
if (!sendport)
perror("ftp: setsockopt (SO_REUSEADDR)");
goto bad;
}
perror("ftp: bind");
goto bad;
}
perror("ftp: setsockopt (TCP_ABORT_THRESHOLD)");
perror("ftp: setsockopt (SO_DEBUG - ignored)");
/*
* Use the system wide default send and receive buffer sizes unless
* one has been specified.
*/
if (tcpwindowsize) {
(char *)&tcpwindowsize, sizeof (tcpwindowsize)) < 0)
perror("ftp: setsockopt (SO_SNDBUF - ignored)");
(char *)&tcpwindowsize, sizeof (tcpwindowsize)) < 0)
perror("ftp: setsockopt (SO_RCVBUF - ignored)");
}
perror("ftp: getsockname");
goto bad;
}
perror("ftp: listen");
if (sendport) {
if (v4_addr) {
result =
command("PORT %d,%d,%d,%d,%d,%d",
} else {
/*
* if on previous try to server, it was
* determined that the server doesn't support
* EPRT, don't bother trying again. Just try
* LPRT.
*/
if (eport_supported == B_TRUE) {
}
}
/* Try LPRT */
"LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
6, 16,
}
}
sendport = 0;
tmpno = 1;
goto noport;
}
}
if (tmpno)
sendport = 1;
return (0);
bad:
if (tmpno)
sendport = 1;
return (1);
}
static FILE *
{
int s;
reset_timer();
if (passivemode && !pasv_refused)
if (s < 0) {
perror("ftp: accept");
return (NULL);
}
data = s;
}
static void
{
double s, bs;
if (remote)
(void) printf("%lld bytes %s in %.2g seconds (%.2f Kbytes/s)\n",
}
/*ARGSUSED*/
static void
{
abrtflag++;
}
void
{
void (*oldintr)();
static struct comvars {
int connect;
int tpe;
int cpnd;
int sunqe;
int runqe;
int mcse;
int ntflg;
int mapflg;
int authtype;
int clvl;
int dlvl;
abrtflag = 0;
if (flag) {
if (proxy)
return;
op = &proxstruct;
proxy++;
} else {
if (!proxy)
return;
ip = &proxstruct;
proxy = 0;
}
if (hostname)
else
if (!type)
type = 1;
if (!clevel)
if (!dlevel)
if (abrtflag) {
abrtflag = 0;
(*oldintr)();
}
}
/*ARGSUSED*/
static void
{
(void) printf("\n");
ptabflg++;
mflag = 0;
abrtflag = 0;
}
static void
{
void (*oldintr)();
char *cmd2;
cmd2 = "RETR";
else
(void) printf(
"proxy server does not support third part transfers.\n");
return;
}
pswitch(0);
if (!connected) {
(void) printf("No primary connection\n");
pswitch(1);
code = -1;
return;
}
switch (tmptype) {
case TYPE_A:
break;
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
}
switch (oldtype) {
case 0:
break;
case TYPE_A:
break;
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
pswitch(1);
return;
}
goto abort;
switch (oldtype) {
case 0:
break;
case TYPE_A:
break;
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
pswitch(1);
return;
}
(void) sleep(2);
pswitch(1);
secndflag++;
goto abort;
ptflag++;
(void) getreply(0);
pswitch(0);
(void) getreply(0);
switch (oldtype) {
case 0:
break;
case TYPE_A:
break;
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
pswitch(1);
ptflag = 0;
return;
ptflag = 0;
pswitch(1);
pswitch(0);
pswitch(0);
switch (oldtype) {
case 0:
break;
case TYPE_A:
break;
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
if (cpend) {
!= 2)
perror("abort");
if (nfnd < 0) {
perror("abort");
}
if (ptabflg)
code = -1;
lostpeer(0);
}
(void) getreply(0);
(void) getreply(0);
}
}
pswitch(1);
if (ptabflg)
code = -1;
return;
}
if (cpend) {
perror("abort");
if (nfnd < 0) {
perror("abort");
}
if (ptabflg)
code = -1;
lostpeer(0);
}
(void) getreply(0);
(void) getreply(0);
}
pswitch(0);
switch (oldtype) {
case 0:
break;
case TYPE_A:
break;
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
if (cpend) {
!= 2)
perror("abort");
if (nfnd < 0) {
perror("abort");
}
if (ptabflg)
code = -1;
lostpeer(0);
}
(void) getreply(0);
(void) getreply(0);
}
pswitch(1);
if (ptabflg)
code = -1;
return;
}
}
if (cpend) {
perror("abort");
if (nfnd < 0) {
perror("abort");
}
if (ptabflg)
code = -1;
lostpeer(0);
}
(void) getreply(0);
(void) getreply(0);
}
if (cpend) {
if (nfnd < 0) {
perror("abort");
}
if (ptabflg)
code = -1;
lostpeer(0);
}
(void) getreply(0);
(void) getreply(0);
}
if (proxy)
pswitch(0);
switch (oldtype) {
case 0:
break;
case TYPE_A:
break;
case TYPE_I:
break;
case TYPE_E:
break;
case TYPE_L:
break;
}
pswitch(1);
if (ptabflg)
code = -1;
}
/*ARGSUSED*/
void
{
while (nfnd > 0) {
perror("reset");
code = -1;
lostpeer(0);
} else if (nfnd > 0) {
(void) getreply(0);
}
}
}
static char *
{
int d, count = 0;
if (cp)
*cp = '\0';
if (cp)
*cp = '/';
if (d < 0) {
return ((char *)0);
}
(void) printf("gunique: too long: local %s, %d, new %d\n",
*cp++ = '.';
while (!d) {
if (++count == 100) {
(void) printf(
"runique: can't find unique file name.\n");
return ((char *)0);
}
*cp = '\0';
if (ext == '9')
ext = '0';
else
ext++;
break;
if (ext != '0')
cp--;
else {
cp--;
}
}
return (new);
}
/*
* This is a wrap-around function for inet_ntop(). In case the af is AF_INET6
* and the address pointed by src is a IPv4-mapped IPv6 address, it
* returns printable IPv4 address, not IPv4-mapped IPv6 address. In other cases
* it behaves just like inet_ntop().
*/
const char *
{
const char *result;
} else {
}
} else {
}
return (result);
}
int
{
int length = 0;
/* secure_command (based on level) */
if (auth_type == AUTHTYPE_GSSAPI) {
int conf_state;
/* clevel = PROT_P; */
&expire_time);
"gss context has expired");
fatal("Your gss credentials have expired. "
"Good-bye!");
}
&in_buf, &conf_state,
&out_buf);
if (maj_stat != GSS_S_COMPLETE) {
/* generally need to deal */
"gss_seal ENC didn't complete":
"gss_seal MIC didn't complete");
"GSSAPI didn't encrypt message");
} else {
if (debug)
"sealed (%s) %d bytes\n",
}
}
/* Other auth types go here ... */
fatal("Memory error allocating space for response.");
}
"Couldn't base 64 encode command (%s)\n",
return (0);
}
if (debug)
"secure_command(%s)\nencoding %d bytes %s %s\n",
} else {
/*
* auth_type = AUTHTYPE_NONE or
* command channel is not protected
*/
}
return (1);
}
unsigned int maxbuf;
unsigned char *ucbuf;
void
{
unsigned int actualbuf;
int oldverbose;
if (ucbuf)
if (actualbuf)
actualbuf >>= 2;
else {
perror("Error while trying to malloc PROT buffer:");
exit(1);
}
}
verbose = 0;
reply_parse = "PBSZ=";
fatal("Cannot set PROT buffer size");
if (reply_parse) {
} else
reply_parse = NULL;
}
/*
* Do the base 64 decoding of the raw input buffer, b64_buf.
* Also do the verification and decryption, if required.
* retval contains the current error code number
*
* returns:
* (RFC 2228: error returns are 3 digit numbers of the form 5xy)
* 5 if an error occurred
*/
static int
int ilen,
int retval,
{
int len;
int safe = 0;
*again = 0;
if (!b64_buf[0]) /* if there is no string, no problem */
return (retval);
if ((auth_type == AUTHTYPE_NONE)) {
return ('5');
}
switch (code) {
case 631: /* 'safe' */
safe = 1;
break;
case 632: /* 'private' */
break;
case 633: /* 'confidential' */
break;
default:
return ('5');
}
/* decode the base64 encoded message */
if (auth_error) {
(void) printf("Can't base 64 decode reply %d (%s)\n\"%s\"\n",
return ('5');
}
if (auth_type == AUTHTYPE_GSSAPI) {
if (maj_stat != GSS_S_COMPLETE) {
"failed unsealing reply");
return ('5');
}
*again = 1;
} else {
"reply was too long");
return ('5');
}
} /* end if GSSAPI */
/* Other auth types go here... */
return (retval);
}