Files
inetutils/libinetutils/kcmd.c
Alfred M. Szmidt 08307d8dac Don't protect <config.h> with HAVE_CONFIG_H.
* cfg.mk (local-checks-to-skip): Removed sc_prohibit_have_config_h
from list.

* ftp/cmdtab.c: Include <config.h> uncondtionally.
* ftp/domacro.c: Likewise.
* ftp/ftp.c: Likewise.
* ftp/main.c: Likewise.
* ftp/ruserpass.c: Likewise.
* ftpd/auth.c: Likewise.
* ftpd/conf.c: Likewise.
* ftpd/ftpcmd.y: Likewise.
* ftpd/ftpd.c: Likewise.
* ftpd/logwtmp.c: Likewise.
* ftpd/pam.c: Likewise.
* ftpd/popen.c: Likewise.
* ftpd/server_mode.c: Likewise.
* ifconfig/changeif.c: Likewise.
* ifconfig/flags.c: Likewise.
* ifconfig/if_index.c: Likewise.
* ifconfig/ifconfig.c: Likewise.
* ifconfig/options.c: Likewise.
* ifconfig/printif.c: Likewise.
* ifconfig/system/generic.c: Likewise.
* ifconfig/system/hpux.c: Likewise.
* ifconfig/system/linux.c: Likewise.
* ifconfig/system/osf.c: Likewise.
* ifconfig/system/qnx.c: Likewise.
* ifconfig/system/solaris.c: Likewise.
* libicmp/icmp_address.c: Likewise.
* libicmp/icmp_cksum.c: Likewise.
* libicmp/icmp_echo.c: Likewise.
* libicmp/icmp_timestamp.c: Likewise.
* libinetutils/cleansess.c: Likewise.
* libinetutils/des_rw.c: Likewise.
* libinetutils/kcmd.c: Likewise.
* libinetutils/krcmd.c: Likewise.
* libinetutils/localhost.c: Likewise.
* libinetutils/logwtmp.c: Likewise.
* libinetutils/setsig.c: Likewise.
* libinetutils/shishi.c: Likewise.
* libinetutils/tftpsubs.c: Likewise.
* libinetutils/ttymsg.c: Likewise.
* libinetutils/utmp_init.c: Likewise.
* libinetutils/utmp_logout.c: Likewise.
* libls/cmp.c: Likewise.
* libls/fts.c: Likewise.
* libls/ls.c: Likewise.
* libls/print.c: Likewise.
* libls/stat_flags.c: Likewise.
* libls/util.c: Likewise.
* libtelnet/auth.c: Likewise.
* libtelnet/enc_des.c: Likewise.
* libtelnet/encrypt.c: Likewise.
* libtelnet/genget.c: Likewise.
* libtelnet/getent.c: Likewise.
* libtelnet/kerberos.c: Likewise.
* libtelnet/kerberos5.c: Likewise.
* libtelnet/misc.c: Likewise.
* libtelnet/read_passwd.c: Likewise.
* libtelnet/shishi.c: Likewise.
* ping/libping.c: Likewise.
* ping/ping.c: Likewise.
* ping/ping6.c: Likewise.
* ping/ping_address.c: Likewise.
* ping/ping_common.c: Likewise.
* ping/ping_echo.c: Likewise.
* ping/ping_router.c: Likewise.
* ping/ping_timestamp.c: Likewise.
* src/inetd.c: Likewise.
* src/logger.c: Likewise.
* src/rcp.c: Likewise.
* src/rexec.c: Likewise.
* src/rexecd.c: Likewise.
* src/rlogin.c: Likewise.
* src/rlogind.c: Likewise.
* src/rsh.c: Likewise.
* src/rshd.c: Likewise.
* src/syslogd.c: Likewise.
* src/tftp.c: Likewise.
* src/tftpd.c: Likewise.
* src/traceroute.c: Likewise.
* src/uucpd.c: Likewise.
* talk/ctl.c: Likewise.
* talk/ctl_transact.c: Likewise.
* talk/display.c: Likewise.
* talk/get_addrs.c: Likewise.
* talk/get_names.c: Likewise.
* talk/invite.c: Likewise.
* talk/io.c: Likewise.
* talk/look_up.c: Likewise.
* talk/msgs.c: Likewise.
* talk/talk.c: Likewise.
* talkd/talkd.c: Likewise.
* telnet/authenc.c: Likewise.
* telnet/commands.c: Likewise.
* telnet/main.c: Likewise.
* telnet/network.c: Likewise.
* telnet/sys_bsd.c: Likewise.
* telnet/telnet.c: Likewise.
* telnet/terminal.c: Likewise.
* telnet/tn3270.c: Likewise.
* telnet/utilities.c: Likewise.
* telnetd/telnetd.h: Likewise.
* whois/whois.c: Likewise.
* ftp/cmds.c: Likewise.
2010-08-19 19:13:31 +02:00

376 lines
9.1 KiB
C

/*
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Inetutils.
GNU Inetutils is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Inetutils is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see `http://www.gnu.org/licenses/'. */
/*
* Copyright (c) 1983, 1993
* The 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
* documentation and/or other materials provided with the distribution.
* 3. 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 <config.h>
#if defined(KERBEROS) || defined(SHISHI)
# include <sys/param.h>
# include <sys/file.h>
# include <sys/socket.h>
# include <sys/stat.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# if defined(KERBEROS)
# include <kerberosIV/des.h>
# include <kerberosIV/krb.h>
# elif defined(SHISHI)
# include <shishi.h>
# include "shishi_def.h"
# endif
# include <ctype.h>
# include <errno.h>
# include <netdb.h>
# include <pwd.h>
# include <signal.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# ifndef MAXHOSTNAMELEN
# define MAXHOSTNAMELEN 64
# endif
# define START_PORT 5120 /* arbitrary */
int getport (int *);
# if defined (KERBEROS)
int
kcmd (int *sock, char **ahost, u_short rport, char *locuser,
char *remuser, char *cmd, int *fd2p, KTEXT ticket,
char *service, char *realm,
CREDENTIALS * cred, Key_schedule schedule, MSG_DAT * msg_data,
struct sockaddr_in *laddr, struct sockaddr_in *faddr, long authopts)
# elif defined(SHISHI)
int
kcmd (Shishi ** h, int *sock, char **ahost, u_short rport, char *locuser,
char **remuser, char *cmd, int *fd2p, char *service, char *realm,
Shishi_key ** key,
struct sockaddr_in *laddr, struct sockaddr_in *faddr, long authopts)
# endif
{
int s, timo = 1, pid;
long oldmask;
struct sockaddr_in sin, from;
char c;
# ifdef ATHENA_COMPAT
int lport = IPPORT_RESERVED - 1;
# else
int lport = START_PORT;
# endif
struct hostent *hp;
int rc;
char *host_save;
int status;
# if defined(SHISHI)
int zero = 0;
# endif
pid = getpid ();
hp = gethostbyname (*ahost);
if (hp == NULL)
{
/* fprintf(stderr, "%s: unknown host\n", *ahost); */
return (-1);
}
host_save = malloc (strlen (hp->h_name) + 1);
strcpy (host_save, hp->h_name);
*ahost = host_save;
# ifdef KERBEROS
/* If realm is null, look up from table */
if (realm == NULL || realm[0] == '\0')
realm = krb_realmofhost (host_save);
# endif /* KERBEROS */
oldmask = sigblock (sigmask (SIGURG));
for (;;)
{
s = getport (&lport);
if (s < 0)
{
if (errno == EAGAIN)
fprintf (stderr, "kcmd(socket): All ports in use\n");
else
perror ("kcmd: socket");
sigsetmask (oldmask);
return (-1);
}
fcntl (s, F_SETOWN, pid);
sin.sin_family = hp->h_addrtype;
memcpy (&sin.sin_addr, hp->h_addr, hp->h_length);
sin.sin_port = rport;
if (connect (s, (struct sockaddr *) &sin, sizeof (sin)) >= 0)
break;
close (s);
if (errno == EADDRINUSE)
{
lport--;
continue;
}
/*
* don't wait very long for Kerberos rcmd.
*/
if (errno == ECONNREFUSED && timo <= 4)
{
/* sleep(timo); don't wait at all here */
timo *= 2;
continue;
}
# if !(defined(ultrix) || defined(sun))
if (hp->h_addr_list[1] != NULL)
{
int oerrno = errno;
fprintf (stderr,
"kcmd: connect to address %s: ", inet_ntoa (sin.sin_addr));
errno = oerrno;
perror (NULL);
hp->h_addr_list++;
memcpy (& sin.sin_addr, hp->h_addr_list, hp->h_length);
fprintf (stderr, "Trying %s...\n", inet_ntoa (sin.sin_addr));
continue;
}
# endif /* !(defined(ultrix) || defined(sun)) */
if (errno != ECONNREFUSED)
perror (hp->h_name);
sigsetmask (oldmask);
return (-1);
}
lport--;
if (fd2p == 0)
{
write (s, "", 1);
lport = 0;
}
else
{
char num[8];
int s2 = getport (&lport), s3;
int len = sizeof (from);
if (s2 < 0)
{
status = -1;
goto bad;
}
listen (s2, 1);
sprintf (num, "%d", lport);
if (write (s, num, strlen (num) + 1) != strlen (num) + 1)
{
perror ("kcmd(write): setting up stderr");
close (s2);
status = -1;
goto bad;
}
s3 = accept (s2, (struct sockaddr *) &from, &len);
close (s2);
if (s3 < 0)
{
perror ("kcmd:accept");
lport = 0;
status = -1;
goto bad;
}
*fd2p = s3;
from.sin_port = ntohs ((u_short) from.sin_port);
if (from.sin_family != AF_INET || from.sin_port >= IPPORT_RESERVED)
{
fprintf (stderr,
"kcmd(socket): protocol failure in circuit setup.\n");
status = -1;
goto bad2;
}
}
/*
* Kerberos-authenticated service. Don't have to send locuser,
* since its already in the ticket, and we'll extract it on
* the other side.
*/
/* write(s, locuser, strlen(locuser)+1); */
/* set up the needed stuff for mutual auth, but only if necessary */
# ifdef KERBEROS
if (authopts & KOPT_DO_MUTUAL)
{
int sin_len;
*faddr = sin;
sin_len = sizeof (struct sockaddr_in);
if (getsockname (s, (struct sockaddr *) laddr, &sin_len) < 0)
{
perror ("kcmd(getsockname)");
status = -1;
goto bad2;
}
}
if ((status = krb_sendauth (authopts, s, ticket, service, *ahost,
realm, (unsigned long) getpid (), msg_data,
cred, schedule,
laddr, faddr, "KCMDV0.1")) != KSUCCESS)
goto bad2;
write (s, remuser, strlen (remuser) + 1);
# elif defined(SHISHI)
if (authopts & SHISHI_APOPTIONS_MUTUAL_REQUIRED)
{
int sin_len;
*faddr = sin;
sin_len = sizeof (struct sockaddr_in);
if (getsockname (s, (struct sockaddr *) laddr, &sin_len) < 0)
{
perror ("kcmd(getsockname)");
status = -1;
goto bad2;
}
}
if ((status =
shishi_auth (h, 0, remuser, *ahost, s, cmd, rport, key,
realm)) != SHISHI_OK)
goto bad2;
write (s, *remuser, strlen (*remuser) + 1);
# endif /* SHISHI */
write (s, cmd, strlen (cmd) + 1);
# ifdef SHISHI
write (s, *remuser, strlen (*remuser) + 1);
write (s, &zero, sizeof (int));
# endif
if ((rc = read (s, &c, 1)) != 1)
{
if (rc == -1)
perror (*ahost);
else
fprintf (stderr, "kcmd: bad connection with remote host\n");
status = -1;
goto bad2;
}
if (c != '\0')
{
while (read (s, &c, 1) == 1)
{
write (2, &c, 1);
if (c == '\n')
break;
}
status = -1;
goto bad2;
}
sigsetmask (oldmask);
*sock = s;
# if defined(KERBEROS)
return (KSUCCESS);
# elif defined(SHISHI)
return (SHISHI_OK);
# endif
bad2:
if (lport)
close (*fd2p);
bad:
close (s);
sigsetmask (oldmask);
return (status);
}
int
getport (int *alport)
{
struct sockaddr_in sin;
int s;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
s = socket (AF_INET, SOCK_STREAM, 0);
if (s < 0)
return (-1);
for (;;)
{
sin.sin_port = htons ((u_short) * alport);
if (bind (s, (struct sockaddr *) &sin, sizeof (sin)) >= 0)
return (s);
if (errno != EADDRINUSE)
{
close (s);
return (-1);
}
(*alport)--;
# ifdef ATHENA_COMPAT
if (*alport == IPPORT_RESERVED / 2)
{
# else
if (*alport == IPPORT_RESERVED)
{
# endif
close (s);
errno = EAGAIN; /* close */
return (-1);
}
}
}
#endif /* KERBEROS */