Goodbye FTP
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -92,12 +92,6 @@ asn1_*.[cx]
|
|||||||
/appl/afsutil/afslog
|
/appl/afsutil/afslog
|
||||||
/appl/afsutil/pagsh
|
/appl/afsutil/pagsh
|
||||||
/appl/dbutils/bsearch
|
/appl/dbutils/bsearch
|
||||||
/appl/ftp/ftp/ftp
|
|
||||||
/appl/ftp/ftpd/ftpcmd.c
|
|
||||||
/appl/ftp/ftpd/ftpd
|
|
||||||
/appl/ftp/ftpd/gssapi.c
|
|
||||||
/appl/ftp/ftpd/security.c
|
|
||||||
/appl/ftp/ftpd/security.h
|
|
||||||
/appl/gssmask/gssmaestro
|
/appl/gssmask/gssmaestro
|
||||||
/appl/gssmask/gssmask
|
/appl/gssmask/gssmask
|
||||||
/appl/kf/kf
|
/appl/kf/kf
|
||||||
|
@@ -14,7 +14,6 @@ endif
|
|||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
$(dir_afsutil) \
|
$(dir_afsutil) \
|
||||||
dbutils \
|
dbutils \
|
||||||
ftp \
|
|
||||||
login \
|
login \
|
||||||
$(dir_otp) \
|
$(dir_otp) \
|
||||||
gssmask \
|
gssmask \
|
||||||
|
1038
appl/ftp/ChangeLog
1038
appl/ftp/ChangeLog
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
# $Id$
|
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.am.common
|
|
||||||
|
|
||||||
SUBDIRS = common ftp ftpd
|
|
||||||
|
|
||||||
EXTRA_DIST = NTMakefile
|
|
@@ -1,35 +0,0 @@
|
|||||||
########################################################################
|
|
||||||
#
|
|
||||||
# Copyright (c) 2009, Secure Endpoints Inc.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions
|
|
||||||
# are met:
|
|
||||||
#
|
|
||||||
# - Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# - 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.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
|
|
||||||
# COPYRIGHT HOLDER 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
RELDIR=appl\ftp
|
|
||||||
|
|
||||||
!include ../../windows/NTMakefile.w32
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# $Id$
|
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.am.common
|
|
||||||
|
|
||||||
noinst_LIBRARIES = libcommon.a
|
|
||||||
|
|
||||||
libcommon_a_SOURCES = \
|
|
||||||
sockbuf.c \
|
|
||||||
buffer.c \
|
|
||||||
common.h
|
|
||||||
|
|
||||||
EXTRA_DIST = NTMakefile
|
|
@@ -1,35 +0,0 @@
|
|||||||
########################################################################
|
|
||||||
#
|
|
||||||
# Copyright (c) 2009, Secure Endpoints Inc.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions
|
|
||||||
# are met:
|
|
||||||
#
|
|
||||||
# - Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# - 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.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
|
|
||||||
# COPYRIGHT HOLDER 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
RELDIR=appl\ftp\common
|
|
||||||
|
|
||||||
!include ../../../windows/NTMakefile.w32
|
|
||||||
|
|
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995-2000 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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 "common.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <err.h>
|
|
||||||
#include "roken.h"
|
|
||||||
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a buffer enough to handle st->st_blksize, if
|
|
||||||
* there is such a field, otherwise BUFSIZ.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *
|
|
||||||
alloc_buffer (void *oldbuf, size_t *sz, struct stat *st)
|
|
||||||
{
|
|
||||||
size_t new_sz;
|
|
||||||
|
|
||||||
new_sz = BUFSIZ;
|
|
||||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
|
||||||
if (st)
|
|
||||||
new_sz = max(BUFSIZ, st->st_blksize);
|
|
||||||
#endif
|
|
||||||
if(new_sz > *sz) {
|
|
||||||
if (oldbuf)
|
|
||||||
free (oldbuf);
|
|
||||||
oldbuf = malloc (new_sz);
|
|
||||||
if (oldbuf == NULL) {
|
|
||||||
warn ("malloc");
|
|
||||||
*sz = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
*sz = new_sz;
|
|
||||||
}
|
|
||||||
return oldbuf;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __COMMON_H__
|
|
||||||
#define __COMMON_H__
|
|
||||||
|
|
||||||
#include "base64.h"
|
|
||||||
|
|
||||||
void set_buffer_size(int, int);
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *alloc_buffer (void *oldbuf, size_t *sz, struct stat *st);
|
|
||||||
|
|
||||||
#endif /* __COMMON_H__ */
|
|
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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 "common.h"
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
void
|
|
||||||
set_buffer_size(int fd, int read)
|
|
||||||
{
|
|
||||||
#if defined(SO_RCVBUF) && defined(SO_SNDBUF) && defined(HAVE_SETSOCKOPT)
|
|
||||||
int size = 4194304;
|
|
||||||
int optname = read ? SO_RCVBUF : SO_SNDBUF;
|
|
||||||
|
|
||||||
#ifdef HAVE_GETSOCKOPT
|
|
||||||
int curr=0;
|
|
||||||
socklen_t optlen;
|
|
||||||
|
|
||||||
optlen = sizeof(curr);
|
|
||||||
if(getsockopt(fd, SOL_SOCKET, optname, (void *)&curr, &optlen) == 0) {
|
|
||||||
if(curr >= size) {
|
|
||||||
/* Already large enough */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* HAVE_GETSOCKOPT */
|
|
||||||
|
|
||||||
while(size >= 131072 &&
|
|
||||||
setsockopt(fd, SOL_SOCKET, optname, (void *)&size, sizeof(size)) < 0)
|
|
||||||
size /= 2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@@ -1,46 +0,0 @@
|
|||||||
# $Id$
|
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.am.common
|
|
||||||
|
|
||||||
WFLAGS += $(WFLAGS_LITE)
|
|
||||||
|
|
||||||
AM_CPPFLAGS += -I$(srcdir)/../common $(INCLUDE_readline)
|
|
||||||
|
|
||||||
bin_PROGRAMS = ftp
|
|
||||||
|
|
||||||
CHECK_LOCAL =
|
|
||||||
|
|
||||||
if KRB5
|
|
||||||
krb5_sources = gssapi.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ftp_SOURCES = \
|
|
||||||
cmds.c \
|
|
||||||
cmdtab.c \
|
|
||||||
extern.h \
|
|
||||||
ftp.c \
|
|
||||||
ftp_locl.h \
|
|
||||||
ftp_var.h \
|
|
||||||
main.c \
|
|
||||||
pathnames.h \
|
|
||||||
ruserpass.c \
|
|
||||||
domacro.c \
|
|
||||||
globals.c \
|
|
||||||
security.c \
|
|
||||||
security.h \
|
|
||||||
kauth.c \
|
|
||||||
$(krb5_sources)
|
|
||||||
|
|
||||||
EXTRA_ftp_SOURCES = gssapi.c
|
|
||||||
|
|
||||||
man_MANS = ftp.1
|
|
||||||
|
|
||||||
LDADD = \
|
|
||||||
../common/libcommon.a \
|
|
||||||
$(LIB_gssapi) \
|
|
||||||
$(LIB_krb5) \
|
|
||||||
$(LIB_hcrypto) \
|
|
||||||
$(LIB_roken) \
|
|
||||||
$(LIB_readline)
|
|
||||||
|
|
||||||
EXTRA_DIST = NTMakefile $(man_MANS)
|
|
@@ -1,35 +0,0 @@
|
|||||||
########################################################################
|
|
||||||
#
|
|
||||||
# Copyright (c) 2009, Secure Endpoints Inc.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions
|
|
||||||
# are met:
|
|
||||||
#
|
|
||||||
# - Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# - 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.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
|
|
||||||
# COPYRIGHT HOLDER 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
RELDIR=appl\ftp\ftp
|
|
||||||
|
|
||||||
!include ../../../windows/NTMakefile.w32
|
|
||||||
|
|
2161
appl/ftp/ftp/cmds.c
2161
appl/ftp/ftp/cmds.c
File diff suppressed because it is too large
Load Diff
@@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1985, 1989, 1993, 1994
|
|
||||||
* 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. 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_locl.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User FTP -- Command Tables.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char accounthelp[] = "send account command to remote server";
|
|
||||||
char appendhelp[] = "append to a file";
|
|
||||||
char asciihelp[] = "set ascii transfer type";
|
|
||||||
char beephelp[] = "beep when command completed";
|
|
||||||
char binaryhelp[] = "set binary transfer type";
|
|
||||||
char casehelp[] = "toggle mget upper/lower case id mapping";
|
|
||||||
char cdhelp[] = "change remote working directory";
|
|
||||||
char cduphelp[] = "change remote working directory to parent directory";
|
|
||||||
char chmodhelp[] = "change file permissions of remote file";
|
|
||||||
char connecthelp[] = "connect to remote tftp";
|
|
||||||
char crhelp[] = "toggle carriage return stripping on ascii gets";
|
|
||||||
char deletehelp[] = "delete remote file";
|
|
||||||
char debughelp[] = "toggle/set debugging mode";
|
|
||||||
char dirhelp[] = "list contents of remote directory";
|
|
||||||
char disconhelp[] = "terminate ftp session";
|
|
||||||
char domachelp[] = "execute macro";
|
|
||||||
char formhelp[] = "set file transfer format";
|
|
||||||
char globhelp[] = "toggle metacharacter expansion of local file names";
|
|
||||||
char hashhelp[] = "toggle printing `#' for each buffer transferred";
|
|
||||||
char helphelp[] = "print local help information";
|
|
||||||
char idlehelp[] = "get (set) idle timer on remote side";
|
|
||||||
char lcdhelp[] = "change local working directory";
|
|
||||||
char lshelp[] = "list contents of remote directory";
|
|
||||||
char macdefhelp[] = "define a macro";
|
|
||||||
char mdeletehelp[] = "delete multiple files";
|
|
||||||
char mdirhelp[] = "list contents of multiple remote directories";
|
|
||||||
char mgethelp[] = "get multiple files";
|
|
||||||
char mkdirhelp[] = "make directory on the remote machine";
|
|
||||||
char mlshelp[] = "list contents of multiple remote directories";
|
|
||||||
char modtimehelp[] = "show last modification time of remote file";
|
|
||||||
char modehelp[] = "set file transfer mode";
|
|
||||||
char mputhelp[] = "send multiple files";
|
|
||||||
char newerhelp[] = "get file if remote file is newer than local file ";
|
|
||||||
char nlisthelp[] = "nlist contents of remote directory";
|
|
||||||
char nmaphelp[] = "set templates for default file name mapping";
|
|
||||||
char ntranshelp[] = "set translation table for default file name mapping";
|
|
||||||
char porthelp[] = "toggle use of PORT cmd for each data connection";
|
|
||||||
char prompthelp[] = "force interactive prompting on multiple commands";
|
|
||||||
char proxyhelp[] = "issue command on alternate connection";
|
|
||||||
char pwdhelp[] = "print working directory on remote machine";
|
|
||||||
char quithelp[] = "terminate ftp session and exit";
|
|
||||||
char quotehelp[] = "send arbitrary ftp command";
|
|
||||||
char receivehelp[] = "receive file";
|
|
||||||
char regethelp[] = "get file restarting at end of local file";
|
|
||||||
char remotehelp[] = "get help from remote server";
|
|
||||||
char renamehelp[] = "rename file";
|
|
||||||
char restarthelp[]= "restart file transfer at bytecount";
|
|
||||||
char rmdirhelp[] = "remove directory on the remote machine";
|
|
||||||
char rmtstatushelp[]="show status of remote machine";
|
|
||||||
char runiquehelp[] = "toggle store unique for local files";
|
|
||||||
char resethelp[] = "clear queued command replies";
|
|
||||||
char sendhelp[] = "send one file";
|
|
||||||
char passivehelp[] = "enter passive transfer mode";
|
|
||||||
char sitehelp[] = "send site specific command to remote server\n\t\tTry \"rhelp site\" or \"site help\" for more information";
|
|
||||||
char shellhelp[] = "escape to the shell";
|
|
||||||
char sizecmdhelp[] = "show size of remote file";
|
|
||||||
char statushelp[] = "show current status";
|
|
||||||
char structhelp[] = "set file transfer structure";
|
|
||||||
char suniquehelp[] = "toggle store unique on remote machine";
|
|
||||||
char systemhelp[] = "show remote system type";
|
|
||||||
char tenexhelp[] = "set tenex file transfer type";
|
|
||||||
char tracehelp[] = "toggle packet tracing";
|
|
||||||
char typehelp[] = "set file transfer type";
|
|
||||||
char umaskhelp[] = "get (set) umask on remote side";
|
|
||||||
char userhelp[] = "send new user information";
|
|
||||||
char verbosehelp[] = "toggle verbose mode";
|
|
||||||
|
|
||||||
char prothelp[] = "set protection level";
|
|
||||||
char prothelp_c[] = "set command protection level";
|
|
||||||
#if defined(KRB5)
|
|
||||||
char klisthelp[] = "show remote tickets";
|
|
||||||
#endif
|
|
||||||
#if defined(KRB5)
|
|
||||||
char afsloghelp[] = "obtain remote AFS tokens";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct cmd cmdtab[] = {
|
|
||||||
{ "!", shellhelp, 0, 0, 0, shell },
|
|
||||||
{ "$", domachelp, 1, 0, 0, domacro },
|
|
||||||
{ "account", accounthelp, 0, 1, 1, account},
|
|
||||||
{ "append", appendhelp, 1, 1, 1, put },
|
|
||||||
{ "ascii", asciihelp, 0, 1, 1, setascii },
|
|
||||||
{ "bell", beephelp, 0, 0, 0, setbell },
|
|
||||||
{ "binary", binaryhelp, 0, 1, 1, setbinary },
|
|
||||||
{ "bye", quithelp, 0, 0, 0, quit },
|
|
||||||
{ "case", casehelp, 0, 0, 1, setcase },
|
|
||||||
{ "cd", cdhelp, 0, 1, 1, cd },
|
|
||||||
{ "cdup", cduphelp, 0, 1, 1, cdup },
|
|
||||||
{ "chmod", chmodhelp, 0, 1, 1, do_chmod },
|
|
||||||
{ "close", disconhelp, 0, 1, 1, disconnect },
|
|
||||||
{ "cr", crhelp, 0, 0, 0, setcr },
|
|
||||||
{ "delete", deletehelp, 0, 1, 1, delete },
|
|
||||||
{ "debug", debughelp, 0, 0, 0, setdebug },
|
|
||||||
{ "dir", dirhelp, 1, 1, 1, ls },
|
|
||||||
{ "disconnect", disconhelp, 0, 1, 1, disconnect },
|
|
||||||
{ "form", formhelp, 0, 1, 1, setform },
|
|
||||||
{ "get", receivehelp, 1, 1, 1, get },
|
|
||||||
{ "glob", globhelp, 0, 0, 0, setglob },
|
|
||||||
{ "hash", hashhelp, 0, 0, 0, sethash },
|
|
||||||
{ "help", helphelp, 0, 0, 1, help },
|
|
||||||
{ "idle", idlehelp, 0, 1, 1, ftp_idle },
|
|
||||||
{ "image", binaryhelp, 0, 1, 1, setbinary },
|
|
||||||
{ "lcd", lcdhelp, 0, 0, 0, lcd },
|
|
||||||
{ "ls", lshelp, 1, 1, 1, ls },
|
|
||||||
{ "macdef", macdefhelp, 0, 0, 0, macdef },
|
|
||||||
{ "mdelete", mdeletehelp, 1, 1, 1, mdelete },
|
|
||||||
{ "mdir", mdirhelp, 1, 1, 1, mls },
|
|
||||||
{ "mget", mgethelp, 1, 1, 1, mget },
|
|
||||||
{ "mkdir", mkdirhelp, 0, 1, 1, makedir },
|
|
||||||
{ "mls", mlshelp, 1, 1, 1, mls },
|
|
||||||
{ "mode", modehelp, 0, 1, 1, setftmode },
|
|
||||||
{ "modtime", modtimehelp, 0, 1, 1, modtime },
|
|
||||||
{ "mput", mputhelp, 1, 1, 1, mput },
|
|
||||||
{ "newer", newerhelp, 1, 1, 1, newer },
|
|
||||||
{ "nmap", nmaphelp, 0, 0, 1, setnmap },
|
|
||||||
{ "nlist", nlisthelp, 1, 1, 1, ls },
|
|
||||||
{ "ntrans", ntranshelp, 0, 0, 1, setntrans },
|
|
||||||
{ "open", connecthelp, 0, 0, 1, setpeer },
|
|
||||||
{ "passive", passivehelp, 0, 0, 0, setpassive },
|
|
||||||
{ "prompt", prompthelp, 0, 0, 0, setprompt },
|
|
||||||
{ "proxy", proxyhelp, 0, 0, 1, doproxy },
|
|
||||||
{ "sendport", porthelp, 0, 0, 0, setport },
|
|
||||||
{ "put", sendhelp, 1, 1, 1, put },
|
|
||||||
{ "pwd", pwdhelp, 0, 1, 1, pwd },
|
|
||||||
{ "quit", quithelp, 0, 0, 0, quit },
|
|
||||||
{ "quote", quotehelp, 1, 1, 1, quote },
|
|
||||||
{ "recv", receivehelp, 1, 1, 1, get },
|
|
||||||
{ "reget", regethelp, 1, 1, 1, reget },
|
|
||||||
{ "rstatus", rmtstatushelp, 0, 1, 1, rmtstatus },
|
|
||||||
{ "rhelp", remotehelp, 0, 1, 1, rmthelp },
|
|
||||||
{ "rename", renamehelp, 0, 1, 1, renamefile },
|
|
||||||
{ "reset", resethelp, 0, 1, 1, reset },
|
|
||||||
{ "restart", restarthelp, 1, 1, 1, restart },
|
|
||||||
{ "rmdir", rmdirhelp, 0, 1, 1, removedir },
|
|
||||||
{ "runique", runiquehelp, 0, 0, 1, setrunique },
|
|
||||||
{ "send", sendhelp, 1, 1, 1, put },
|
|
||||||
{ "site", sitehelp, 0, 1, 1, site },
|
|
||||||
{ "size", sizecmdhelp, 1, 1, 1, sizecmd },
|
|
||||||
{ "status", statushelp, 0, 0, 1, status },
|
|
||||||
{ "struct", structhelp, 0, 1, 1, setstruct },
|
|
||||||
{ "system", systemhelp, 0, 1, 1, syst },
|
|
||||||
{ "sunique", suniquehelp, 0, 0, 1, setsunique },
|
|
||||||
{ "tenex", tenexhelp, 0, 1, 1, settenex },
|
|
||||||
{ "trace", tracehelp, 0, 0, 0, settrace },
|
|
||||||
{ "type", typehelp, 0, 1, 1, settype },
|
|
||||||
{ "user", userhelp, 0, 1, 1, user },
|
|
||||||
{ "umask", umaskhelp, 0, 1, 1, do_umask },
|
|
||||||
{ "verbose", verbosehelp, 0, 0, 0, setverbose },
|
|
||||||
{ "?", helphelp, 0, 0, 1, help },
|
|
||||||
|
|
||||||
{ "protect", prothelp, 0, 1, 0, sec_prot },
|
|
||||||
/* what MIT uses */
|
|
||||||
{ "cprotect", prothelp_c, 0, 1, 1, sec_prot_command },
|
|
||||||
#if defined(KRB5)
|
|
||||||
{ "klist", klisthelp, 0, 1, 0, klist },
|
|
||||||
#endif
|
|
||||||
#if defined(KRB5)
|
|
||||||
{ "afslog", afsloghelp, 0, 1, 0, afslog },
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{ NULL, NULL, 0, 0, 0, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
int NCMDS = (sizeof (cmdtab) / sizeof (cmdtab[0])) - 1;
|
|
@@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1985, 1993, 1994
|
|
||||||
* 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. 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_locl.h"
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
void
|
|
||||||
domacro(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i, j, count = 2, loopflg = 0;
|
|
||||||
char *cp1, *cp2, line2[200];
|
|
||||||
struct cmd *c;
|
|
||||||
|
|
||||||
if (argc < 2 && !another(&argc, &argv, "macro name")) {
|
|
||||||
printf("Usage: %s macro_name.\n", argv[0]);
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (i = 0; i < macnum; ++i) {
|
|
||||||
if (!strncmp(argv[1], macros[i].mac_name, 9)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == macnum) {
|
|
||||||
printf("'%s' macro not found.\n", argv[1]);
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
strlcpy(line2, line, sizeof(line2));
|
|
||||||
TOP:
|
|
||||||
cp1 = macros[i].mac_start;
|
|
||||||
while (cp1 != macros[i].mac_end) {
|
|
||||||
while (isspace((unsigned char)*cp1)) {
|
|
||||||
cp1++;
|
|
||||||
}
|
|
||||||
cp2 = line;
|
|
||||||
while (*cp1 != '\0') {
|
|
||||||
size_t len;
|
|
||||||
switch(*cp1) {
|
|
||||||
case '\\':
|
|
||||||
if (line + sizeof(line) - 2 < cp2)
|
|
||||||
goto out;
|
|
||||||
*cp2++ = *++cp1;
|
|
||||||
break;
|
|
||||||
case '$':
|
|
||||||
if (isdigit((unsigned char)*(cp1+1))) {
|
|
||||||
j = 0;
|
|
||||||
while (isdigit((unsigned char)*++cp1)) {
|
|
||||||
j = 10*j + *cp1 - '0';
|
|
||||||
}
|
|
||||||
cp1--;
|
|
||||||
if (argc - 2 >= j) {
|
|
||||||
len = sizeof(line) - (cp2 - line) - 1;
|
|
||||||
if (strlcpy(cp2, argv[j+1], len) >= len)
|
|
||||||
goto out;
|
|
||||||
cp2 += strlen(argv[j+1]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*(cp1+1) == 'i') {
|
|
||||||
loopflg = 1;
|
|
||||||
cp1++;
|
|
||||||
if (count < argc) {
|
|
||||||
len = sizeof(line) - (cp2 - line) - 1;
|
|
||||||
if (strlcpy(cp2, argv[count], len) >= len)
|
|
||||||
goto out;
|
|
||||||
cp2 += strlen(argv[count]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* intentional drop through */
|
|
||||||
default:
|
|
||||||
if (line + sizeof(line) - 2 < cp2)
|
|
||||||
goto out;
|
|
||||||
*cp2++ = *cp1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*cp1 != '\0') {
|
|
||||||
cp1++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
*cp2 = '\0';
|
|
||||||
makeargv();
|
|
||||||
c = getcmd(margv[0]);
|
|
||||||
if (c == (struct cmd *)-1) {
|
|
||||||
printf("?Ambiguous command\n");
|
|
||||||
code = -1;
|
|
||||||
}
|
|
||||||
else if (c == 0) {
|
|
||||||
printf("?Invalid command\n");
|
|
||||||
code = -1;
|
|
||||||
}
|
|
||||||
else if (c->c_conn && !connected) {
|
|
||||||
printf("Not connected.\n");
|
|
||||||
code = -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (verbose) {
|
|
||||||
printf("%s\n",line);
|
|
||||||
}
|
|
||||||
(*c->c_handler)(margc, margv);
|
|
||||||
if (bell && c->c_bell) {
|
|
||||||
putchar('\007');
|
|
||||||
}
|
|
||||||
strlcpy(line, line2, sizeof(line));
|
|
||||||
makeargv();
|
|
||||||
argc = margc;
|
|
||||||
argv = margv;
|
|
||||||
}
|
|
||||||
if (cp1 != macros[i].mac_end) {
|
|
||||||
cp1++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (loopflg && ++count < argc) {
|
|
||||||
goto TOP;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,174 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 1994 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. 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.
|
|
||||||
*
|
|
||||||
* @(#)extern.h 8.3 (Berkeley) 10/9/94
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#include <setjmp.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#ifdef TIME_WITH_SYS_TIME
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
#elif defined(HAVE_SYS_TIME_H)
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void abort_remote (FILE *);
|
|
||||||
void abortpt (int);
|
|
||||||
void abortrecv (int);
|
|
||||||
void account (int, char **);
|
|
||||||
int another (int *, char ***, char *);
|
|
||||||
void blkfree (char **);
|
|
||||||
void cd (int, char **);
|
|
||||||
void cdup (int, char **);
|
|
||||||
void changetype (int, int);
|
|
||||||
void cmdabort (int);
|
|
||||||
void cmdscanner (int);
|
|
||||||
int command (char *fmt, ...)
|
|
||||||
__attribute__ ((format (printf, 1,2)));
|
|
||||||
int confirm (char *, char *);
|
|
||||||
FILE *dataconn (const char *);
|
|
||||||
void delete (int, char **);
|
|
||||||
void disconnect (int, char **);
|
|
||||||
void do_chmod (int, char **);
|
|
||||||
void do_umask (int, char **);
|
|
||||||
void domacro (int, char **);
|
|
||||||
char *domap (char *);
|
|
||||||
void doproxy (int, char **);
|
|
||||||
char *dotrans (char *);
|
|
||||||
int empty (fd_set *, int);
|
|
||||||
void fatal (char *);
|
|
||||||
void get (int, char **);
|
|
||||||
struct cmd *getcmd (char *);
|
|
||||||
int getit (int, char **, int, char *);
|
|
||||||
int getreply (int);
|
|
||||||
int globulize (char **);
|
|
||||||
char *gunique (char *);
|
|
||||||
void help (int, char **);
|
|
||||||
char *hookup (const char *, int);
|
|
||||||
void ftp_idle (int, char **);
|
|
||||||
int initconn (void);
|
|
||||||
void intr (int);
|
|
||||||
void lcd (int, char **);
|
|
||||||
int login (char *);
|
|
||||||
RETSIGTYPE lostpeer (int);
|
|
||||||
void ls (int, char **);
|
|
||||||
void macdef (int, char **);
|
|
||||||
void makeargv (void);
|
|
||||||
void makedir (int, char **);
|
|
||||||
void mdelete (int, char **);
|
|
||||||
void mget (int, char **);
|
|
||||||
void mls (int, char **);
|
|
||||||
void modtime (int, char **);
|
|
||||||
void mput (int, char **);
|
|
||||||
char *onoff (int);
|
|
||||||
void newer (int, char **);
|
|
||||||
void proxtrans (char *, char *, char *);
|
|
||||||
void psabort (int);
|
|
||||||
void pswitch (int);
|
|
||||||
void ptransfer (char *, long, struct timeval *, struct timeval *);
|
|
||||||
void put (int, char **);
|
|
||||||
void pwd (int, char **);
|
|
||||||
void quit (int, char **);
|
|
||||||
void quote (int, char **);
|
|
||||||
void quote1 (char *, int, char **);
|
|
||||||
void recvrequest (char *, char *, char *, char *, int, int);
|
|
||||||
void reget (int, char **);
|
|
||||||
char *remglob (char **, int);
|
|
||||||
void removedir (int, char **);
|
|
||||||
void renamefile (int, char **);
|
|
||||||
void reset (int, char **);
|
|
||||||
void restart (int, char **);
|
|
||||||
void rmthelp (int, char **);
|
|
||||||
void rmtstatus (int, char **);
|
|
||||||
int ruserpassword (char *, char **, char **, char **);
|
|
||||||
void sendrequest (char *, char *, char *, char *, int);
|
|
||||||
void setascii (int, char **);
|
|
||||||
void setbell (int, char **);
|
|
||||||
void setbinary (int, char **);
|
|
||||||
void setcase (int, char **);
|
|
||||||
void setcr (int, char **);
|
|
||||||
void setdebug (int, char **);
|
|
||||||
void setform (int, char **);
|
|
||||||
void setftmode (int, char **);
|
|
||||||
void setglob (int, char **);
|
|
||||||
void sethash (int, char **);
|
|
||||||
void setnmap (int, char **);
|
|
||||||
void setntrans (int, char **);
|
|
||||||
void setpassive (int, char **);
|
|
||||||
void setpeer (int, char **);
|
|
||||||
void setport (int, char **);
|
|
||||||
void setprompt (int, char **);
|
|
||||||
void setrunique (int, char **);
|
|
||||||
void setstruct (int, char **);
|
|
||||||
void setsunique (int, char **);
|
|
||||||
void settenex (int, char **);
|
|
||||||
void settrace (int, char **);
|
|
||||||
void settype (int, char **);
|
|
||||||
void setverbose (int, char **);
|
|
||||||
void shell (int, char **);
|
|
||||||
void site (int, char **);
|
|
||||||
void sizecmd (int, char **);
|
|
||||||
char *slurpstring (void);
|
|
||||||
void status (int, char **);
|
|
||||||
void syst (int, char **);
|
|
||||||
void tvsub (struct timeval *, struct timeval *, struct timeval *);
|
|
||||||
void user (int, char **);
|
|
||||||
|
|
||||||
extern jmp_buf abortprox;
|
|
||||||
extern int abrtflag;
|
|
||||||
extern struct cmd cmdtab[];
|
|
||||||
extern FILE *cout;
|
|
||||||
extern int data;
|
|
||||||
extern char *home;
|
|
||||||
extern jmp_buf jabort;
|
|
||||||
extern int proxy;
|
|
||||||
extern char reply_string[];
|
|
||||||
extern off_t restart_point;
|
|
||||||
extern int NCMDS;
|
|
||||||
|
|
||||||
extern char username[32];
|
|
||||||
extern char myhostname[];
|
|
||||||
extern char *mydomain;
|
|
||||||
|
|
||||||
void afslog (int, char **);
|
|
||||||
void kauth (int, char **);
|
|
||||||
void kdestroy (int, char **);
|
|
||||||
void klist (int, char **);
|
|
||||||
void krbtkfile (int, char **);
|
|
1211
appl/ftp/ftp/ftp.1
1211
appl/ftp/ftp/ftp.1
File diff suppressed because it is too large
Load Diff
1818
appl/ftp/ftp/ftp.c
1818
appl/ftp/ftp/ftp.c
File diff suppressed because it is too large
Load Diff
@@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#ifndef __FTP_LOCL_H__
|
|
||||||
#define __FTP_LOCL_H__
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_PWD_H
|
|
||||||
#include <pwd.h>
|
|
||||||
#endif
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#ifdef TIME_WITH_SYS_TIME
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
#elif defined(HAVE_SYS_TIME_H)
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_RESOURCE_H
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_WAIT_H
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
|
||||||
#include <netinet/in_systm.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IP_H
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_ARPA_FTP_H
|
|
||||||
#include <arpa/ftp.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ARPA_TELNET_H
|
|
||||||
#include <arpa/telnet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <glob.h>
|
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
#include <netdb.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_MMAN_H
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <err.h>
|
|
||||||
|
|
||||||
#ifdef SOCKS
|
|
||||||
#include <socks.h>
|
|
||||||
extern int LIBPREFIX(fclose) (FILE *);
|
|
||||||
|
|
||||||
/* This doesn't belong here. */
|
|
||||||
struct tm *localtime(const time_t *);
|
|
||||||
struct hostent *gethostbyname(const char *);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "ftp_var.h"
|
|
||||||
#include "extern.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "pathnames.h"
|
|
||||||
|
|
||||||
#include "roken.h"
|
|
||||||
#include "security.h"
|
|
||||||
|
|
||||||
/* des_read_pw_string */
|
|
||||||
#include "crypto-headers.h"
|
|
||||||
|
|
||||||
#if defined(__sun__) && !defined(__svr4)
|
|
||||||
int fclose(FILE*);
|
|
||||||
int pclose(FILE*);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __FTP_LOCL_H__ */
|
|
@@ -1,130 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1985, 1989, 1993, 1994
|
|
||||||
* 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. 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.
|
|
||||||
*
|
|
||||||
* @(#)ftp_var.h 8.4 (Berkeley) 10/9/94
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FTP global variables.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Options and other state info.
|
|
||||||
*/
|
|
||||||
extern int trace; /* trace packets exchanged */
|
|
||||||
extern int hash; /* print # for each buffer transferred */
|
|
||||||
extern int sendport; /* use PORT cmd for each data connection */
|
|
||||||
extern int verbose; /* print messages coming back from server */
|
|
||||||
extern int connected; /* connected to server */
|
|
||||||
extern int fromatty; /* input is from a terminal */
|
|
||||||
extern int interactive; /* interactively prompt on m* cmds */
|
|
||||||
extern int lineedit; /* use line-editing */
|
|
||||||
extern int debug; /* debugging level */
|
|
||||||
extern int bell; /* ring bell on cmd completion */
|
|
||||||
extern int doglob; /* glob local file names */
|
|
||||||
extern int autologin; /* establish user account on connection */
|
|
||||||
extern int doencrypt;
|
|
||||||
extern int proxy; /* proxy server connection active */
|
|
||||||
extern int proxflag; /* proxy connection exists */
|
|
||||||
extern int sunique; /* store files on server with unique name */
|
|
||||||
extern int runique; /* store local files with unique name */
|
|
||||||
extern int mcase; /* map upper to lower case for mget names */
|
|
||||||
extern int ntflag; /* use ntin ntout tables for name translation */
|
|
||||||
extern int mapflag; /* use mapin mapout templates on file names */
|
|
||||||
extern int code; /* return/reply code for ftp command */
|
|
||||||
extern int crflag; /* if 1, strip car. rets. on ascii gets */
|
|
||||||
extern char pasv[64]; /* passive port for proxy data connection */
|
|
||||||
extern int passivemode; /* passive mode enabled */
|
|
||||||
extern char *altarg; /* argv[1] with no shell-like preprocessing */
|
|
||||||
extern char ntin[17]; /* input translation table */
|
|
||||||
extern char ntout[17]; /* output translation table */
|
|
||||||
extern char mapin[MaxPathLen]; /* input map template */
|
|
||||||
extern char mapout[MaxPathLen]; /* output map template */
|
|
||||||
extern char typename[32]; /* name of file transfer type */
|
|
||||||
extern int type; /* requested file transfer type */
|
|
||||||
extern int curtype; /* current file transfer type */
|
|
||||||
extern char structname[32]; /* name of file transfer structure */
|
|
||||||
extern int stru; /* file transfer structure */
|
|
||||||
extern char formname[32]; /* name of file transfer format */
|
|
||||||
extern int form; /* file transfer format */
|
|
||||||
extern char modename[32]; /* name of file transfer mode */
|
|
||||||
extern int mode; /* file transfer mode */
|
|
||||||
extern char bytename[32]; /* local byte size in ascii */
|
|
||||||
extern int bytesize; /* local byte size in binary */
|
|
||||||
|
|
||||||
extern char *hostname; /* name of host connected to */
|
|
||||||
extern int unix_server; /* server is unix, can use binary for ascii */
|
|
||||||
extern int unix_proxy; /* proxy is unix, can use binary for ascii */
|
|
||||||
|
|
||||||
extern jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
|
|
||||||
|
|
||||||
extern char line[200]; /* input line buffer */
|
|
||||||
extern char *stringbase; /* current scan point in line buffer */
|
|
||||||
extern char argbuf[200]; /* argument storage buffer */
|
|
||||||
extern char *argbase; /* current storage point in arg buffer */
|
|
||||||
extern int margc; /* count of arguments on input line */
|
|
||||||
extern char **margv; /* args parsed from input line */
|
|
||||||
extern int margvlen; /* how large margv is currently */
|
|
||||||
extern int cpend; /* flag: if != 0, then pending server reply */
|
|
||||||
extern int mflag; /* flag: if != 0, then active multi command */
|
|
||||||
|
|
||||||
extern int options; /* used during socket creation */
|
|
||||||
extern int use_kerberos; /* use Kerberos authentication */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Format of command table.
|
|
||||||
*/
|
|
||||||
struct cmd {
|
|
||||||
char *c_name; /* name of command */
|
|
||||||
char *c_help; /* help string */
|
|
||||||
char c_bell; /* give bell when command completes */
|
|
||||||
char c_conn; /* must be connected to use command */
|
|
||||||
char c_proxy; /* proxy server may execute */
|
|
||||||
void (*c_handler) (int, char **); /* function to call */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct macel {
|
|
||||||
char mac_name[9]; /* macro name */
|
|
||||||
char *mac_start; /* start of macro in macbuf */
|
|
||||||
char *mac_end; /* end of macro in macbuf */
|
|
||||||
};
|
|
||||||
|
|
||||||
extern int macnum; /* number of defined macros */
|
|
||||||
extern struct macel macros[16];
|
|
||||||
extern char macbuf[4096];
|
|
||||||
|
|
||||||
|
|
@@ -1,79 +0,0 @@
|
|||||||
#include "ftp_locl.h"
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Options and other state info.
|
|
||||||
*/
|
|
||||||
int trace; /* trace packets exchanged */
|
|
||||||
int hash; /* print # for each buffer transferred */
|
|
||||||
int sendport; /* use PORT cmd for each data connection */
|
|
||||||
int verbose; /* print messages coming back from server */
|
|
||||||
int connected; /* connected to server */
|
|
||||||
int fromatty; /* input is from a terminal */
|
|
||||||
int interactive; /* interactively prompt on m* cmds */
|
|
||||||
int lineedit; /* use line-editing */
|
|
||||||
int debug; /* debugging level */
|
|
||||||
int bell; /* ring bell on cmd completion */
|
|
||||||
int doglob; /* glob local file names */
|
|
||||||
int doencrypt; /* try to use encryption */
|
|
||||||
int autologin; /* establish user account on connection */
|
|
||||||
int proxy; /* proxy server connection active */
|
|
||||||
int proxflag; /* proxy connection exists */
|
|
||||||
int sunique; /* store files on server with unique name */
|
|
||||||
int runique; /* store local files with unique name */
|
|
||||||
int mcase; /* map upper to lower case for mget names */
|
|
||||||
int ntflag; /* use ntin ntout tables for name translation */
|
|
||||||
int mapflag; /* use mapin mapout templates on file names */
|
|
||||||
int code; /* return/reply code for ftp command */
|
|
||||||
int crflag; /* if 1, strip car. rets. on ascii gets */
|
|
||||||
char pasv[64]; /* passive port for proxy data connection */
|
|
||||||
int passivemode; /* passive mode enabled */
|
|
||||||
char *altarg; /* argv[1] with no shell-like preprocessing */
|
|
||||||
char ntin[17]; /* input translation table */
|
|
||||||
char ntout[17]; /* output translation table */
|
|
||||||
char mapin[MaxPathLen]; /* input map template */
|
|
||||||
char mapout[MaxPathLen]; /* output map template */
|
|
||||||
char typename[32]; /* name of file transfer type */
|
|
||||||
int type; /* requested file transfer type */
|
|
||||||
int curtype; /* current file transfer type */
|
|
||||||
char structname[32]; /* name of file transfer structure */
|
|
||||||
int stru; /* file transfer structure */
|
|
||||||
char formname[32]; /* name of file transfer format */
|
|
||||||
int form; /* file transfer format */
|
|
||||||
char modename[32]; /* name of file transfer mode */
|
|
||||||
int mode; /* file transfer mode */
|
|
||||||
char bytename[32]; /* local byte size in ascii */
|
|
||||||
int bytesize; /* local byte size in binary */
|
|
||||||
|
|
||||||
char *hostname; /* name of host connected to */
|
|
||||||
int unix_server; /* server is unix, can use binary for ascii */
|
|
||||||
int unix_proxy; /* proxy is unix, can use binary for ascii */
|
|
||||||
|
|
||||||
jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
|
|
||||||
|
|
||||||
char line[200]; /* input line buffer */
|
|
||||||
char *stringbase; /* current scan point in line buffer */
|
|
||||||
char argbuf[200]; /* argument storage buffer */
|
|
||||||
char *argbase; /* current storage point in arg buffer */
|
|
||||||
int margc; /* count of arguments on input line */
|
|
||||||
char **margv; /* args parsed from input line */
|
|
||||||
int margvlen; /* how large margv is currently */
|
|
||||||
int cpend; /* flag: if != 0, then pending server reply */
|
|
||||||
int mflag; /* flag: if != 0, then active multi command */
|
|
||||||
|
|
||||||
int options; /* used during socket creation */
|
|
||||||
int use_kerberos; /* use Kerberos authentication */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Format of command table.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int macnum; /* number of defined macros */
|
|
||||||
struct macel macros[16];
|
|
||||||
char macbuf[4096];
|
|
||||||
|
|
||||||
char username[32];
|
|
||||||
|
|
||||||
/* these are set in ruserpassword */
|
|
||||||
char myhostname[MaxHostNameLen];
|
|
||||||
char *mydomain;
|
|
@@ -1,512 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
#include "ftpd_locl.h"
|
|
||||||
#else
|
|
||||||
#include "ftp_locl.h"
|
|
||||||
#endif
|
|
||||||
#include <gssapi/gssapi.h>
|
|
||||||
#include <gssapi/gssapi_krb5.h>
|
|
||||||
#include <krb5_err.h>
|
|
||||||
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
int ftp_do_gss_bindings = 0;
|
|
||||||
int ftp_do_gss_delegate = 1;
|
|
||||||
|
|
||||||
struct gssapi_data {
|
|
||||||
gss_ctx_id_t context_hdl;
|
|
||||||
gss_name_t client_name;
|
|
||||||
gss_cred_id_t delegated_cred_handle;
|
|
||||||
void *mech_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
gss_init(void *app_data)
|
|
||||||
{
|
|
||||||
struct gssapi_data *d = app_data;
|
|
||||||
d->context_hdl = GSS_C_NO_CONTEXT;
|
|
||||||
d->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
|
|
||||||
#if defined(FTP_SERVER)
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
/* XXX Check the gss mechanism; with gss_indicate_mechs() ? */
|
|
||||||
#ifdef KRB5
|
|
||||||
return !use_kerberos;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif /* KRB5 */
|
|
||||||
#endif /* FTP_SERVER */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
gss_check_prot(void *app_data, int level)
|
|
||||||
{
|
|
||||||
if(level == prot_confidential)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
gss_decode(void *app_data, void *buf, int len, int level)
|
|
||||||
{
|
|
||||||
OM_uint32 maj_stat, min_stat;
|
|
||||||
gss_buffer_desc input, output;
|
|
||||||
gss_qop_t qop_state;
|
|
||||||
int conf_state;
|
|
||||||
struct gssapi_data *d = app_data;
|
|
||||||
size_t ret_len;
|
|
||||||
|
|
||||||
input.length = len;
|
|
||||||
input.value = buf;
|
|
||||||
maj_stat = gss_unwrap (&min_stat,
|
|
||||||
d->context_hdl,
|
|
||||||
&input,
|
|
||||||
&output,
|
|
||||||
&conf_state,
|
|
||||||
&qop_state);
|
|
||||||
if(GSS_ERROR(maj_stat))
|
|
||||||
return -1;
|
|
||||||
memmove(buf, output.value, output.length);
|
|
||||||
ret_len = output.length;
|
|
||||||
gss_release_buffer(&min_stat, &output);
|
|
||||||
return ret_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
gss_overhead(void *app_data, int level, int len)
|
|
||||||
{
|
|
||||||
return 100; /* dunno? */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
gss_encode(void *app_data, void *from, int length, int level, void **to)
|
|
||||||
{
|
|
||||||
OM_uint32 min_stat;
|
|
||||||
gss_buffer_desc input, output;
|
|
||||||
int conf_state;
|
|
||||||
struct gssapi_data *d = app_data;
|
|
||||||
|
|
||||||
input.length = length;
|
|
||||||
input.value = from;
|
|
||||||
/* XXX We should really display the major status... */
|
|
||||||
(void) gss_wrap(&min_stat,
|
|
||||||
d->context_hdl,
|
|
||||||
level == prot_private,
|
|
||||||
GSS_C_QOP_DEFAULT,
|
|
||||||
&input,
|
|
||||||
&conf_state,
|
|
||||||
&output);
|
|
||||||
*to = output.value;
|
|
||||||
return output.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
sockaddr_to_gss_address (struct sockaddr *sa,
|
|
||||||
OM_uint32 *addr_type,
|
|
||||||
gss_buffer_desc *gss_addr)
|
|
||||||
{
|
|
||||||
switch (sa->sa_family) {
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
case AF_INET6 : {
|
|
||||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
|
||||||
|
|
||||||
gss_addr->length = 16;
|
|
||||||
gss_addr->value = &sin6->sin6_addr;
|
|
||||||
*addr_type = GSS_C_AF_INET6;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case AF_INET : {
|
|
||||||
struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
|
|
||||||
|
|
||||||
gss_addr->length = 4;
|
|
||||||
gss_addr->value = &sin4->sin_addr;
|
|
||||||
*addr_type = GSS_C_AF_INET;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default :
|
|
||||||
errx (1, "unknown address family %d", sa->sa_family);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end common stuff */
|
|
||||||
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
|
|
||||||
static int
|
|
||||||
gss_adat(void *app_data, void *buf, size_t len)
|
|
||||||
{
|
|
||||||
char *p = NULL;
|
|
||||||
gss_buffer_desc input_token, output_token;
|
|
||||||
OM_uint32 maj_stat, min_stat;
|
|
||||||
gss_name_t client_name;
|
|
||||||
struct gssapi_data *d = app_data;
|
|
||||||
gss_channel_bindings_t bindings;
|
|
||||||
|
|
||||||
if (ftp_do_gss_bindings) {
|
|
||||||
bindings = malloc(sizeof(*bindings));
|
|
||||||
if (bindings == NULL)
|
|
||||||
errx(1, "out of memory");
|
|
||||||
|
|
||||||
sockaddr_to_gss_address (his_addr,
|
|
||||||
&bindings->initiator_addrtype,
|
|
||||||
&bindings->initiator_address);
|
|
||||||
sockaddr_to_gss_address (ctrl_addr,
|
|
||||||
&bindings->acceptor_addrtype,
|
|
||||||
&bindings->acceptor_address);
|
|
||||||
|
|
||||||
bindings->application_data.length = 0;
|
|
||||||
bindings->application_data.value = NULL;
|
|
||||||
} else
|
|
||||||
bindings = GSS_C_NO_CHANNEL_BINDINGS;
|
|
||||||
|
|
||||||
input_token.value = buf;
|
|
||||||
input_token.length = len;
|
|
||||||
|
|
||||||
maj_stat = gss_accept_sec_context (&min_stat,
|
|
||||||
&d->context_hdl,
|
|
||||||
GSS_C_NO_CREDENTIAL,
|
|
||||||
&input_token,
|
|
||||||
bindings,
|
|
||||||
&client_name,
|
|
||||||
NULL,
|
|
||||||
&output_token,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&d->delegated_cred_handle);
|
|
||||||
|
|
||||||
if (bindings != GSS_C_NO_CHANNEL_BINDINGS)
|
|
||||||
free(bindings);
|
|
||||||
|
|
||||||
if(output_token.length) {
|
|
||||||
if(rk_base64_encode(output_token.value, output_token.length, &p) < 0) {
|
|
||||||
reply(535, "Out of memory base64-encoding.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
gss_release_buffer(&min_stat, &output_token);
|
|
||||||
}
|
|
||||||
if(maj_stat == GSS_S_COMPLETE){
|
|
||||||
d->client_name = client_name;
|
|
||||||
client_name = GSS_C_NO_NAME;
|
|
||||||
if(p)
|
|
||||||
reply(235, "ADAT=%s", p);
|
|
||||||
else
|
|
||||||
reply(235, "ADAT Complete");
|
|
||||||
sec_complete = 1;
|
|
||||||
|
|
||||||
} else if(maj_stat == GSS_S_CONTINUE_NEEDED) {
|
|
||||||
if(p)
|
|
||||||
reply(335, "ADAT=%s", p);
|
|
||||||
else
|
|
||||||
reply(335, "OK, need more data");
|
|
||||||
} else {
|
|
||||||
OM_uint32 new_stat;
|
|
||||||
OM_uint32 msg_ctx = 0;
|
|
||||||
gss_buffer_desc status_string;
|
|
||||||
gss_display_status(&new_stat,
|
|
||||||
min_stat,
|
|
||||||
GSS_C_MECH_CODE,
|
|
||||||
GSS_C_NO_OID,
|
|
||||||
&msg_ctx,
|
|
||||||
&status_string);
|
|
||||||
syslog(LOG_ERR, "gss_accept_sec_context: %.*s",
|
|
||||||
(int)status_string.length,
|
|
||||||
(char*)status_string.value);
|
|
||||||
gss_release_buffer(&new_stat, &status_string);
|
|
||||||
reply(431, "Security resource unavailable");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client_name)
|
|
||||||
gss_release_name(&min_stat, &client_name);
|
|
||||||
free(p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gssapi_userok(void*, char*);
|
|
||||||
int gssapi_session(void*, char*);
|
|
||||||
|
|
||||||
struct sec_server_mech gss_server_mech = {
|
|
||||||
"GSSAPI",
|
|
||||||
sizeof(struct gssapi_data),
|
|
||||||
gss_init, /* init */
|
|
||||||
NULL, /* end */
|
|
||||||
gss_check_prot,
|
|
||||||
gss_overhead,
|
|
||||||
gss_encode,
|
|
||||||
gss_decode,
|
|
||||||
/* */
|
|
||||||
NULL,
|
|
||||||
gss_adat,
|
|
||||||
NULL, /* pbsz */
|
|
||||||
NULL, /* ccc */
|
|
||||||
gssapi_userok,
|
|
||||||
gssapi_session
|
|
||||||
};
|
|
||||||
|
|
||||||
#else /* FTP_SERVER */
|
|
||||||
|
|
||||||
extern struct sockaddr *hisctladdr, *myctladdr;
|
|
||||||
|
|
||||||
static int
|
|
||||||
import_name(const char *kname, const char *host, gss_name_t *target_name)
|
|
||||||
{
|
|
||||||
OM_uint32 maj_stat, min_stat;
|
|
||||||
gss_buffer_desc name;
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
name.length = asprintf(&str, "%s@%s", kname, host);
|
|
||||||
if (str == NULL) {
|
|
||||||
printf("Out of memory\n");
|
|
||||||
return AUTH_ERROR;
|
|
||||||
}
|
|
||||||
name.value = str;
|
|
||||||
|
|
||||||
maj_stat = gss_import_name(&min_stat,
|
|
||||||
&name,
|
|
||||||
GSS_C_NT_HOSTBASED_SERVICE,
|
|
||||||
target_name);
|
|
||||||
if (GSS_ERROR(maj_stat)) {
|
|
||||||
OM_uint32 new_stat;
|
|
||||||
OM_uint32 msg_ctx = 0;
|
|
||||||
gss_buffer_desc status_string;
|
|
||||||
|
|
||||||
gss_display_status(&new_stat,
|
|
||||||
min_stat,
|
|
||||||
GSS_C_MECH_CODE,
|
|
||||||
GSS_C_NO_OID,
|
|
||||||
&msg_ctx,
|
|
||||||
&status_string);
|
|
||||||
printf("Error importing name %.*s: %.*s\n",
|
|
||||||
(int)name.length,
|
|
||||||
(char *)name.value,
|
|
||||||
(int)status_string.length,
|
|
||||||
(char *)status_string.value);
|
|
||||||
free(name.value);
|
|
||||||
gss_release_buffer(&new_stat, &status_string);
|
|
||||||
return AUTH_ERROR;
|
|
||||||
}
|
|
||||||
free(name.value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
gss_auth(void *app_data, char *host)
|
|
||||||
{
|
|
||||||
|
|
||||||
OM_uint32 maj_stat, min_stat;
|
|
||||||
gss_name_t target_name;
|
|
||||||
gss_buffer_desc input, output_token;
|
|
||||||
int context_established = 0;
|
|
||||||
char *p;
|
|
||||||
int n = 0;
|
|
||||||
gss_channel_bindings_t bindings;
|
|
||||||
struct gssapi_data *d = app_data;
|
|
||||||
OM_uint32 mech_flags = GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG;
|
|
||||||
|
|
||||||
const char *knames[] = { "ftp", "host", NULL }, **kname = knames;
|
|
||||||
|
|
||||||
|
|
||||||
if(import_name(*kname++, host, &target_name))
|
|
||||||
return AUTH_ERROR;
|
|
||||||
|
|
||||||
input.length = 0;
|
|
||||||
input.value = NULL;
|
|
||||||
|
|
||||||
if (ftp_do_gss_bindings) {
|
|
||||||
bindings = malloc(sizeof(*bindings));
|
|
||||||
if (bindings == NULL)
|
|
||||||
errx(1, "out of memory");
|
|
||||||
|
|
||||||
sockaddr_to_gss_address (myctladdr,
|
|
||||||
&bindings->initiator_addrtype,
|
|
||||||
&bindings->initiator_address);
|
|
||||||
sockaddr_to_gss_address (hisctladdr,
|
|
||||||
&bindings->acceptor_addrtype,
|
|
||||||
&bindings->acceptor_address);
|
|
||||||
|
|
||||||
bindings->application_data.length = 0;
|
|
||||||
bindings->application_data.value = NULL;
|
|
||||||
} else
|
|
||||||
bindings = GSS_C_NO_CHANNEL_BINDINGS;
|
|
||||||
|
|
||||||
if (ftp_do_gss_delegate)
|
|
||||||
mech_flags |= GSS_C_DELEG_FLAG;
|
|
||||||
|
|
||||||
while(!context_established) {
|
|
||||||
maj_stat = gss_init_sec_context(&min_stat,
|
|
||||||
GSS_C_NO_CREDENTIAL,
|
|
||||||
&d->context_hdl,
|
|
||||||
target_name,
|
|
||||||
GSS_C_NO_OID,
|
|
||||||
mech_flags,
|
|
||||||
0,
|
|
||||||
bindings,
|
|
||||||
&input,
|
|
||||||
NULL,
|
|
||||||
&output_token,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
if (GSS_ERROR(maj_stat)) {
|
|
||||||
OM_uint32 new_stat;
|
|
||||||
OM_uint32 msg_ctx = 0;
|
|
||||||
gss_buffer_desc status_string;
|
|
||||||
|
|
||||||
d->context_hdl = GSS_C_NO_CONTEXT;
|
|
||||||
|
|
||||||
gss_release_name(&min_stat, &target_name);
|
|
||||||
|
|
||||||
if(*kname != NULL) {
|
|
||||||
|
|
||||||
if(import_name(*kname++, host, &target_name)) {
|
|
||||||
if (bindings != GSS_C_NO_CHANNEL_BINDINGS)
|
|
||||||
free(bindings);
|
|
||||||
return AUTH_ERROR;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bindings != GSS_C_NO_CHANNEL_BINDINGS)
|
|
||||||
free(bindings);
|
|
||||||
|
|
||||||
gss_display_status(&new_stat,
|
|
||||||
min_stat,
|
|
||||||
GSS_C_MECH_CODE,
|
|
||||||
GSS_C_NO_OID,
|
|
||||||
&msg_ctx,
|
|
||||||
&status_string);
|
|
||||||
printf("Error initializing security context: %.*s\n",
|
|
||||||
(int)status_string.length,
|
|
||||||
(char*)status_string.value);
|
|
||||||
gss_release_buffer(&new_stat, &status_string);
|
|
||||||
return AUTH_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.value) {
|
|
||||||
free(input.value);
|
|
||||||
input.value = NULL;
|
|
||||||
input.length = 0;
|
|
||||||
}
|
|
||||||
if (output_token.length != 0) {
|
|
||||||
rk_base64_encode(output_token.value, output_token.length, &p);
|
|
||||||
gss_release_buffer(&min_stat, &output_token);
|
|
||||||
n = command("ADAT %s", p);
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
if (GSS_ERROR(maj_stat) || n >= 4) {
|
|
||||||
if (d->context_hdl != GSS_C_NO_CONTEXT)
|
|
||||||
gss_delete_sec_context (&min_stat,
|
|
||||||
&d->context_hdl,
|
|
||||||
GSS_C_NO_BUFFER);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (maj_stat & GSS_S_CONTINUE_NEEDED) {
|
|
||||||
p = strstr(reply_string, "ADAT=");
|
|
||||||
if(p == NULL){
|
|
||||||
printf("Error: expected ADAT in reply. got: %s\n",
|
|
||||||
reply_string);
|
|
||||||
if (bindings != GSS_C_NO_CHANNEL_BINDINGS)
|
|
||||||
free(bindings);
|
|
||||||
return AUTH_ERROR;
|
|
||||||
} else {
|
|
||||||
p+=5;
|
|
||||||
input.value = malloc(strlen(p));
|
|
||||||
input.length = rk_base64_decode(p, input.value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(code != 235) {
|
|
||||||
printf("Unrecognized response code: %d\n", code);
|
|
||||||
if (bindings != GSS_C_NO_CHANNEL_BINDINGS)
|
|
||||||
free(bindings);
|
|
||||||
return AUTH_ERROR;
|
|
||||||
}
|
|
||||||
context_established = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gss_release_name(&min_stat, &target_name);
|
|
||||||
|
|
||||||
if (bindings != GSS_C_NO_CHANNEL_BINDINGS)
|
|
||||||
free(bindings);
|
|
||||||
if (input.value)
|
|
||||||
free(input.value);
|
|
||||||
|
|
||||||
{
|
|
||||||
gss_name_t targ_name;
|
|
||||||
|
|
||||||
maj_stat = gss_inquire_context(&min_stat,
|
|
||||||
d->context_hdl,
|
|
||||||
NULL,
|
|
||||||
&targ_name,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
if (GSS_ERROR(maj_stat) == 0) {
|
|
||||||
gss_buffer_desc name;
|
|
||||||
maj_stat = gss_display_name (&min_stat,
|
|
||||||
targ_name,
|
|
||||||
&name,
|
|
||||||
NULL);
|
|
||||||
if (GSS_ERROR(maj_stat) == 0) {
|
|
||||||
printf("Authenticated to <%.*s>\n",
|
|
||||||
(int)name.length,
|
|
||||||
(char *)name.value);
|
|
||||||
gss_release_buffer(&min_stat, &name);
|
|
||||||
}
|
|
||||||
gss_release_name(&min_stat, &targ_name);
|
|
||||||
} else
|
|
||||||
printf("Failed to get gss name of peer.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return AUTH_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sec_client_mech gss_client_mech = {
|
|
||||||
"GSSAPI",
|
|
||||||
sizeof(struct gssapi_data),
|
|
||||||
gss_init,
|
|
||||||
gss_auth,
|
|
||||||
NULL, /* end */
|
|
||||||
gss_check_prot,
|
|
||||||
gss_overhead,
|
|
||||||
gss_encode,
|
|
||||||
gss_decode,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FTP_SERVER */
|
|
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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_locl.h"
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
#if defined(KRB5)
|
|
||||||
|
|
||||||
void
|
|
||||||
afslog(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
if(argc > 2) {
|
|
||||||
printf("usage: %s [cell]\n", argv[0]);
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(argc == 2)
|
|
||||||
ret = command("SITE AFSLOG %s", argv[1]);
|
|
||||||
else
|
|
||||||
ret = command("SITE AFSLOG");
|
|
||||||
code = (ret == COMPLETE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int ftp_afslog_placeholder;
|
|
||||||
#endif
|
|
@@ -1,590 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1985, 1989, 1993, 1994
|
|
||||||
* 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. 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FTP User Program -- Command Interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ftp_locl.h"
|
|
||||||
#include <getarg.h>
|
|
||||||
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
static int help_flag;
|
|
||||||
static int version_flag;
|
|
||||||
static int debug_flag;
|
|
||||||
|
|
||||||
struct getargs getargs[] = {
|
|
||||||
{ NULL, 'd', arg_flag, &debug_flag,
|
|
||||||
"debug", NULL },
|
|
||||||
{ NULL, 'g', arg_negative_flag, &doglob,
|
|
||||||
"disables globbing", NULL},
|
|
||||||
{ NULL, 'i', arg_negative_flag, &interactive,
|
|
||||||
"Turn off interactive prompting", NULL},
|
|
||||||
{ NULL, 'l', arg_negative_flag, &lineedit,
|
|
||||||
"Turn off line editing", NULL},
|
|
||||||
{ NULL, 'n', arg_negative_flag, &autologin,
|
|
||||||
"Turn off auto-login", NULL},
|
|
||||||
{ NULL, 'p', arg_flag, &passivemode,
|
|
||||||
"passive mode", NULL},
|
|
||||||
{ NULL, 't', arg_counter, &trace,
|
|
||||||
"Packet tracing", NULL},
|
|
||||||
#ifdef KRB5
|
|
||||||
{ "gss-bindings", 0, arg_negative_flag, &ftp_do_gss_bindings,
|
|
||||||
"Don't use GSS-API bindings", NULL},
|
|
||||||
{ "gss-delegate", 0, arg_negative_flag, &ftp_do_gss_delegate,
|
|
||||||
"Disable delegation of GSS-API credentials", NULL},
|
|
||||||
#endif
|
|
||||||
{ NULL, 'v', arg_counter, &verbose,
|
|
||||||
"verbosity", NULL},
|
|
||||||
{ NULL, 'K', arg_negative_flag, &use_kerberos,
|
|
||||||
"Disable kerberos authentication", NULL},
|
|
||||||
{ "encrypt", 'x', arg_flag, &doencrypt,
|
|
||||||
"Encrypt command and data channel if possible" },
|
|
||||||
{ "version", 0, arg_flag, &version_flag },
|
|
||||||
{ "help", 'h', arg_flag, &help_flag },
|
|
||||||
};
|
|
||||||
|
|
||||||
static int num_args = sizeof(getargs) / sizeof(getargs[0]);
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(int ecode)
|
|
||||||
{
|
|
||||||
arg_printusage(getargs, num_args, NULL, "[host [port]]");
|
|
||||||
exit(ecode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int top;
|
|
||||||
struct passwd *pw = NULL;
|
|
||||||
char homedir[MaxPathLen];
|
|
||||||
struct servent *sp;
|
|
||||||
int optind = 0;
|
|
||||||
|
|
||||||
setprogname(argv[0]);
|
|
||||||
|
|
||||||
sp = getservbyname("ftp", "tcp");
|
|
||||||
if (sp == 0)
|
|
||||||
errx(1, "ftp/tcp: unknown service");
|
|
||||||
doglob = 1;
|
|
||||||
interactive = 1;
|
|
||||||
autologin = 1;
|
|
||||||
lineedit = 1;
|
|
||||||
passivemode = 0; /* passive mode not active */
|
|
||||||
use_kerberos = 1;
|
|
||||||
#ifdef KRB5
|
|
||||||
ftp_do_gss_bindings = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(getarg(getargs, num_args, argc, argv, &optind))
|
|
||||||
usage(1);
|
|
||||||
if(help_flag)
|
|
||||||
usage(0);
|
|
||||||
if(version_flag) {
|
|
||||||
print_version(NULL);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_flag) {
|
|
||||||
options |= SO_DEBUG;
|
|
||||||
debug++;
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
fromatty = isatty(fileno(stdin));
|
|
||||||
if (fromatty)
|
|
||||||
verbose++;
|
|
||||||
cpend = 0; /* no pending replies */
|
|
||||||
proxy = 0; /* proxy not active */
|
|
||||||
crflag = 1; /* strip c.r. on ascii gets */
|
|
||||||
sendport = -1; /* not using ports */
|
|
||||||
/*
|
|
||||||
* Set up the home directory in case we're globbing.
|
|
||||||
*/
|
|
||||||
pw = k_getpwuid(getuid());
|
|
||||||
if (pw != NULL) {
|
|
||||||
strlcpy(homedir, pw->pw_dir, sizeof(homedir));
|
|
||||||
home = homedir;
|
|
||||||
}
|
|
||||||
if (argc > 0) {
|
|
||||||
char *xargv[5];
|
|
||||||
|
|
||||||
if (setjmp(toplevel))
|
|
||||||
exit(0);
|
|
||||||
signal(SIGINT, intr);
|
|
||||||
signal(SIGPIPE, lostpeer);
|
|
||||||
xargv[0] = (char*)getprogname();
|
|
||||||
xargv[1] = argv[0];
|
|
||||||
xargv[2] = argv[1];
|
|
||||||
xargv[3] = argv[2];
|
|
||||||
xargv[4] = NULL;
|
|
||||||
setpeer(argc+1, xargv);
|
|
||||||
}
|
|
||||||
if(setjmp(toplevel) == 0)
|
|
||||||
top = 1;
|
|
||||||
else
|
|
||||||
top = 0;
|
|
||||||
if (top) {
|
|
||||||
signal(SIGINT, intr);
|
|
||||||
signal(SIGPIPE, lostpeer);
|
|
||||||
}
|
|
||||||
for (;;) {
|
|
||||||
cmdscanner(top);
|
|
||||||
top = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
intr(int sig)
|
|
||||||
{
|
|
||||||
|
|
||||||
longjmp(toplevel, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SHUT_RDWR
|
|
||||||
#define SHUT_RDWR 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RETSIGTYPE
|
|
||||||
lostpeer(int sig)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (connected) {
|
|
||||||
if (cout != NULL) {
|
|
||||||
shutdown(fileno(cout), SHUT_RDWR);
|
|
||||||
fclose(cout);
|
|
||||||
cout = NULL;
|
|
||||||
}
|
|
||||||
if (data >= 0) {
|
|
||||||
shutdown(data, SHUT_RDWR);
|
|
||||||
close(data);
|
|
||||||
data = -1;
|
|
||||||
}
|
|
||||||
connected = 0;
|
|
||||||
}
|
|
||||||
pswitch(1);
|
|
||||||
if (connected) {
|
|
||||||
if (cout != NULL) {
|
|
||||||
shutdown(fileno(cout), SHUT_RDWR);
|
|
||||||
fclose(cout);
|
|
||||||
cout = NULL;
|
|
||||||
}
|
|
||||||
connected = 0;
|
|
||||||
}
|
|
||||||
proxflag = 0;
|
|
||||||
pswitch(0);
|
|
||||||
sec_end();
|
|
||||||
SIGRETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
char *
|
|
||||||
tail(filename)
|
|
||||||
char *filename;
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
while (*filename) {
|
|
||||||
s = strrchr(filename, '/');
|
|
||||||
if (s == NULL)
|
|
||||||
break;
|
|
||||||
if (s[1])
|
|
||||||
return (s + 1);
|
|
||||||
*s = '\0';
|
|
||||||
}
|
|
||||||
return (filename);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char *
|
|
||||||
simple_readline(char *prompt)
|
|
||||||
{
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
printf ("%s", prompt);
|
|
||||||
fflush (stdout);
|
|
||||||
if(fgets(buf, sizeof(buf), stdin) == NULL)
|
|
||||||
return NULL;
|
|
||||||
if (buf[strlen(buf) - 1] == '\n')
|
|
||||||
buf[strlen(buf) - 1] = '\0';
|
|
||||||
return strdup(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef HAVE_READLINE
|
|
||||||
|
|
||||||
static char *
|
|
||||||
readline(char *prompt)
|
|
||||||
{
|
|
||||||
return simple_readline (prompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_history(char *p)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* These should not really be here */
|
|
||||||
|
|
||||||
char *readline(char *);
|
|
||||||
void add_history(char *);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Command parser.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
cmdscanner(int top)
|
|
||||||
{
|
|
||||||
struct cmd *c;
|
|
||||||
int l;
|
|
||||||
|
|
||||||
if (!top)
|
|
||||||
putchar('\n');
|
|
||||||
for (;;) {
|
|
||||||
if (fromatty) {
|
|
||||||
char *p;
|
|
||||||
if (lineedit)
|
|
||||||
p = readline("ftp> ");
|
|
||||||
else
|
|
||||||
p = simple_readline("ftp> ");
|
|
||||||
if(p == NULL) {
|
|
||||||
printf("\n");
|
|
||||||
quit(0, 0);
|
|
||||||
}
|
|
||||||
strlcpy(line, p, sizeof(line));
|
|
||||||
if (lineedit)
|
|
||||||
add_history(p);
|
|
||||||
free(p);
|
|
||||||
} else{
|
|
||||||
if (fgets(line, sizeof line, stdin) == NULL)
|
|
||||||
quit(0, 0);
|
|
||||||
}
|
|
||||||
/* XXX will break on long lines */
|
|
||||||
l = strlen(line);
|
|
||||||
if (l == 0)
|
|
||||||
break;
|
|
||||||
if (line[--l] == '\n') {
|
|
||||||
if (l == 0)
|
|
||||||
break;
|
|
||||||
line[l] = '\0';
|
|
||||||
} else if (l == sizeof(line) - 2) {
|
|
||||||
printf("sorry, input line too long\n");
|
|
||||||
while ((l = getchar()) != '\n' && l != EOF)
|
|
||||||
/* void */;
|
|
||||||
break;
|
|
||||||
} /* else it was a line without a newline */
|
|
||||||
makeargv();
|
|
||||||
if (margc == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
c = getcmd(margv[0]);
|
|
||||||
if (c == (struct cmd *)-1) {
|
|
||||||
printf("?Ambiguous command\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == 0) {
|
|
||||||
printf("?Invalid command\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c->c_conn && !connected) {
|
|
||||||
printf("Not connected.\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
(*c->c_handler)(margc, margv);
|
|
||||||
if (bell && c->c_bell)
|
|
||||||
putchar('\007');
|
|
||||||
if (c->c_handler != help)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
signal(SIGINT, intr);
|
|
||||||
signal(SIGPIPE, lostpeer);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cmd *
|
|
||||||
getcmd(char *name)
|
|
||||||
{
|
|
||||||
char *p, *q;
|
|
||||||
struct cmd *c, *found;
|
|
||||||
int nmatches, longest;
|
|
||||||
|
|
||||||
longest = 0;
|
|
||||||
nmatches = 0;
|
|
||||||
found = 0;
|
|
||||||
for (c = cmdtab; (p = c->c_name); c++) {
|
|
||||||
for (q = name; *q == *p++; q++)
|
|
||||||
if (*q == 0) /* exact match? */
|
|
||||||
return (c);
|
|
||||||
if (!*q) { /* the name was a prefix */
|
|
||||||
if (q - name > longest) {
|
|
||||||
longest = q - name;
|
|
||||||
nmatches = 1;
|
|
||||||
found = c;
|
|
||||||
} else if (q - name == longest)
|
|
||||||
nmatches++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nmatches > 1)
|
|
||||||
return ((struct cmd *)-1);
|
|
||||||
return (found);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Slice a string up into argc/argv.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int slrflag;
|
|
||||||
|
|
||||||
void
|
|
||||||
makeargv(void)
|
|
||||||
{
|
|
||||||
char **argp;
|
|
||||||
|
|
||||||
argp = margv;
|
|
||||||
stringbase = line; /* scan from first of buffer */
|
|
||||||
argbase = argbuf; /* store from first of buffer */
|
|
||||||
slrflag = 0;
|
|
||||||
for (margc = 0; ; margc++) {
|
|
||||||
/* Expand array if necessary */
|
|
||||||
if (margc == margvlen) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
margv = (margvlen == 0)
|
|
||||||
? (char **)malloc(20 * sizeof(char *))
|
|
||||||
: (char **)realloc(margv,
|
|
||||||
(margvlen + 20)*sizeof(char *));
|
|
||||||
if (margv == NULL)
|
|
||||||
errx(1, "cannot realloc argv array");
|
|
||||||
for(i = margvlen; i < margvlen + 20; ++i)
|
|
||||||
margv[i] = NULL;
|
|
||||||
margvlen += 20;
|
|
||||||
argp = margv + margc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*argp++ = slurpstring()) == NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse string into argbuf;
|
|
||||||
* implemented with FSM to
|
|
||||||
* handle quoting and strings
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
slurpstring(void)
|
|
||||||
{
|
|
||||||
int got_one = 0;
|
|
||||||
char *sb = stringbase;
|
|
||||||
char *ap = argbase;
|
|
||||||
char *tmp = argbase; /* will return this if token found */
|
|
||||||
|
|
||||||
if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
|
|
||||||
switch (slrflag) { /* and $ as token for macro invoke */
|
|
||||||
case 0:
|
|
||||||
slrflag++;
|
|
||||||
stringbase++;
|
|
||||||
return ((*sb == '!') ? "!" : "$");
|
|
||||||
/* NOTREACHED */
|
|
||||||
case 1:
|
|
||||||
slrflag++;
|
|
||||||
altarg = stringbase;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
S0:
|
|
||||||
switch (*sb) {
|
|
||||||
|
|
||||||
case '\0':
|
|
||||||
goto OUT;
|
|
||||||
|
|
||||||
case ' ':
|
|
||||||
case '\t':
|
|
||||||
sb++; goto S0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
switch (slrflag) {
|
|
||||||
case 0:
|
|
||||||
slrflag++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
slrflag++;
|
|
||||||
altarg = sb;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto S1;
|
|
||||||
}
|
|
||||||
|
|
||||||
S1:
|
|
||||||
switch (*sb) {
|
|
||||||
|
|
||||||
case ' ':
|
|
||||||
case '\t':
|
|
||||||
case '\0':
|
|
||||||
goto OUT; /* end of token */
|
|
||||||
|
|
||||||
case '\\':
|
|
||||||
sb++; goto S2; /* slurp next character */
|
|
||||||
|
|
||||||
case '"':
|
|
||||||
sb++; goto S3; /* slurp quoted string */
|
|
||||||
|
|
||||||
default:
|
|
||||||
*ap++ = *sb++; /* add character to token */
|
|
||||||
got_one = 1;
|
|
||||||
goto S1;
|
|
||||||
}
|
|
||||||
|
|
||||||
S2:
|
|
||||||
switch (*sb) {
|
|
||||||
|
|
||||||
case '\0':
|
|
||||||
goto OUT;
|
|
||||||
|
|
||||||
default:
|
|
||||||
*ap++ = *sb++;
|
|
||||||
got_one = 1;
|
|
||||||
goto S1;
|
|
||||||
}
|
|
||||||
|
|
||||||
S3:
|
|
||||||
switch (*sb) {
|
|
||||||
|
|
||||||
case '\0':
|
|
||||||
goto OUT;
|
|
||||||
|
|
||||||
case '"':
|
|
||||||
sb++; goto S1;
|
|
||||||
|
|
||||||
default:
|
|
||||||
*ap++ = *sb++;
|
|
||||||
got_one = 1;
|
|
||||||
goto S3;
|
|
||||||
}
|
|
||||||
|
|
||||||
OUT:
|
|
||||||
if (got_one)
|
|
||||||
*ap++ = '\0';
|
|
||||||
argbase = ap; /* update storage pointer */
|
|
||||||
stringbase = sb; /* update scan pointer */
|
|
||||||
if (got_one) {
|
|
||||||
return (tmp);
|
|
||||||
}
|
|
||||||
switch (slrflag) {
|
|
||||||
case 0:
|
|
||||||
slrflag++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
slrflag++;
|
|
||||||
altarg = (char *) 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define HELPINDENT ((int) sizeof ("directory"))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Help command.
|
|
||||||
* Call each command handler with argc == 0 and argv[0] == name.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
help(int argc, char **argv)
|
|
||||||
{
|
|
||||||
struct cmd *c;
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
int i, j, w, k;
|
|
||||||
int columns, width = 0, lines;
|
|
||||||
|
|
||||||
printf("Commands may be abbreviated. Commands are:\n\n");
|
|
||||||
for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
|
|
||||||
int len = strlen(c->c_name);
|
|
||||||
|
|
||||||
if (len > width)
|
|
||||||
width = len;
|
|
||||||
}
|
|
||||||
width = (width + 8) &~ 7;
|
|
||||||
columns = 80 / width;
|
|
||||||
if (columns == 0)
|
|
||||||
columns = 1;
|
|
||||||
lines = (NCMDS + columns - 1) / columns;
|
|
||||||
for (i = 0; i < lines; i++) {
|
|
||||||
for (j = 0; j < columns; j++) {
|
|
||||||
c = cmdtab + j * lines + i;
|
|
||||||
if ((!proxy || c->c_proxy)) {
|
|
||||||
printf("%s", c->c_name);
|
|
||||||
} else {
|
|
||||||
for (k=0; k < strlen(c->c_name); k++) {
|
|
||||||
putchar(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c + lines >= &cmdtab[NCMDS]) {
|
|
||||||
printf("\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
w = strlen(c->c_name);
|
|
||||||
while (w < width) {
|
|
||||||
w = (w + 8) &~ 7;
|
|
||||||
putchar('\t');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (--argc > 0) {
|
|
||||||
char *arg;
|
|
||||||
arg = *++argv;
|
|
||||||
c = getcmd(arg);
|
|
||||||
if (c == (struct cmd *)-1)
|
|
||||||
printf("?Ambiguous help command %s\n", arg);
|
|
||||||
else if (c == (struct cmd *)0)
|
|
||||||
printf("?Invalid help command %s\n", arg);
|
|
||||||
else
|
|
||||||
printf("%-*s\t%s\n", HELPINDENT,
|
|
||||||
c->c_name, c->c_help);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1989, 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. 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.
|
|
||||||
*
|
|
||||||
* @(#)pathnames.h 8.1 (Berkeley) 6/6/93
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_PATHS_H
|
|
||||||
#include <paths.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _PATH_TMP_XXX "/tmp/ftpXXXXXX"
|
|
||||||
|
|
||||||
#ifndef _PATH_BSHELL
|
|
||||||
#define _PATH_BSHELL "/bin/sh"
|
|
||||||
#endif
|
|
@@ -1,313 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1985, 1993, 1994
|
|
||||||
* 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. 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_locl.h"
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
static int token (void);
|
|
||||||
static FILE *cfile;
|
|
||||||
|
|
||||||
#define DEFAULT 1
|
|
||||||
#define LOGIN 2
|
|
||||||
#define PASSWD 3
|
|
||||||
#define ACCOUNT 4
|
|
||||||
#define MACDEF 5
|
|
||||||
#define PROT 6
|
|
||||||
#define ID 10
|
|
||||||
#define MACH 11
|
|
||||||
|
|
||||||
static char tokval[100];
|
|
||||||
|
|
||||||
static struct toktab {
|
|
||||||
char *tokstr;
|
|
||||||
int tval;
|
|
||||||
} toktab[]= {
|
|
||||||
{ "default", DEFAULT },
|
|
||||||
{ "login", LOGIN },
|
|
||||||
{ "password", PASSWD },
|
|
||||||
{ "passwd", PASSWD },
|
|
||||||
{ "account", ACCOUNT },
|
|
||||||
{ "machine", MACH },
|
|
||||||
{ "macdef", MACDEF },
|
|
||||||
{ "prot", PROT },
|
|
||||||
{ NULL, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write a copy of the hostname into `hostname, sz' and return a guess
|
|
||||||
* as to the `domain' of that hostname.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char *
|
|
||||||
guess_domain (char *hostname_str, size_t sz)
|
|
||||||
{
|
|
||||||
struct addrinfo *ai, *a;
|
|
||||||
struct addrinfo hints;
|
|
||||||
int error;
|
|
||||||
char *dot;
|
|
||||||
|
|
||||||
if (gethostname (hostname_str, sz) < 0) {
|
|
||||||
strlcpy (hostname_str, "", sz);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
dot = strchr (hostname_str, '.');
|
|
||||||
if (dot != NULL)
|
|
||||||
return dot + 1;
|
|
||||||
|
|
||||||
memset (&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_flags = AI_CANONNAME;
|
|
||||||
|
|
||||||
error = getaddrinfo (hostname_str, NULL, &hints, &ai);
|
|
||||||
if (error)
|
|
||||||
return hostname_str;
|
|
||||||
|
|
||||||
for (a = ai; a != NULL; a = a->ai_next)
|
|
||||||
if (a->ai_canonname != NULL) {
|
|
||||||
strlcpy (hostname_str, ai->ai_canonname, sz);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
freeaddrinfo (ai);
|
|
||||||
dot = strchr (hostname_str, '.');
|
|
||||||
if (dot != NULL)
|
|
||||||
return dot + 1;
|
|
||||||
else
|
|
||||||
return hostname_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ruserpassword(char *host, char **aname, char **apass, char **aacct)
|
|
||||||
{
|
|
||||||
char *hdir, buf[BUFSIZ], *tmp;
|
|
||||||
int t, i, c, usedefault = 0;
|
|
||||||
struct stat stb;
|
|
||||||
|
|
||||||
mydomain = guess_domain (myhostname, MaxHostNameLen);
|
|
||||||
|
|
||||||
hdir = getenv("HOME");
|
|
||||||
if (hdir == NULL)
|
|
||||||
hdir = ".";
|
|
||||||
snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
|
|
||||||
cfile = fopen(buf, "r");
|
|
||||||
if (cfile == NULL) {
|
|
||||||
if (errno != ENOENT)
|
|
||||||
warn("%s", buf);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
next:
|
|
||||||
while ((t = token())) switch(t) {
|
|
||||||
|
|
||||||
case DEFAULT:
|
|
||||||
usedefault = 1;
|
|
||||||
/* FALL THROUGH */
|
|
||||||
|
|
||||||
case MACH:
|
|
||||||
if (!usedefault) {
|
|
||||||
if (token() != ID)
|
|
||||||
continue;
|
|
||||||
/*
|
|
||||||
* Allow match either for user's input host name
|
|
||||||
* or official hostname. Also allow match of
|
|
||||||
* incompletely-specified host in local domain.
|
|
||||||
*/
|
|
||||||
if (strcasecmp(host, tokval) == 0)
|
|
||||||
goto match;
|
|
||||||
if (strcasecmp(hostname, tokval) == 0)
|
|
||||||
goto match;
|
|
||||||
if ((tmp = strchr(hostname, '.')) != NULL &&
|
|
||||||
tmp++ &&
|
|
||||||
strcasecmp(tmp, mydomain) == 0 &&
|
|
||||||
strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
|
|
||||||
tokval[tmp - hostname] == '\0')
|
|
||||||
goto match;
|
|
||||||
if ((tmp = strchr(host, '.')) != NULL &&
|
|
||||||
tmp++ &&
|
|
||||||
strcasecmp(tmp, mydomain) == 0 &&
|
|
||||||
strncasecmp(host, tokval, tmp - host) == 0 &&
|
|
||||||
tokval[tmp - host] == '\0')
|
|
||||||
goto match;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
match:
|
|
||||||
while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
|
|
||||||
|
|
||||||
case LOGIN:
|
|
||||||
if (token()) {
|
|
||||||
if (*aname == 0) {
|
|
||||||
*aname = strdup(tokval);
|
|
||||||
} else {
|
|
||||||
if (strcmp(*aname, tokval))
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PASSWD:
|
|
||||||
if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
|
|
||||||
fstat(fileno(cfile), &stb) >= 0 &&
|
|
||||||
(stb.st_mode & 077) != 0) {
|
|
||||||
warnx("Error: .netrc file is readable by others.");
|
|
||||||
warnx("Remove password or make file unreadable by others.");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (token() && *apass == 0) {
|
|
||||||
*apass = strdup(tokval);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ACCOUNT:
|
|
||||||
if (fstat(fileno(cfile), &stb) >= 0
|
|
||||||
&& (stb.st_mode & 077) != 0) {
|
|
||||||
warnx("Error: .netrc file is readable by others.");
|
|
||||||
warnx("Remove account or make file unreadable by others.");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (token() && *aacct == 0) {
|
|
||||||
*aacct = strdup(tokval);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MACDEF:
|
|
||||||
if (proxy) {
|
|
||||||
fclose(cfile);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
while ((c=getc(cfile)) != EOF &&
|
|
||||||
(c == ' ' || c == '\t'));
|
|
||||||
if (c == EOF || c == '\n') {
|
|
||||||
printf("Missing macdef name argument.\n");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (macnum == 16) {
|
|
||||||
printf("Limit of 16 macros have already been defined\n");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
tmp = macros[macnum].mac_name;
|
|
||||||
*tmp++ = c;
|
|
||||||
for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
|
|
||||||
!isspace(c); ++i) {
|
|
||||||
*tmp++ = c;
|
|
||||||
}
|
|
||||||
if (c == EOF) {
|
|
||||||
printf("Macro definition missing null line terminator.\n");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
*tmp = '\0';
|
|
||||||
if (c != '\n') {
|
|
||||||
while ((c=getc(cfile)) != EOF && c != '\n');
|
|
||||||
}
|
|
||||||
if (c == EOF) {
|
|
||||||
printf("Macro definition missing null line terminator.\n");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (macnum == 0) {
|
|
||||||
macros[macnum].mac_start = macbuf;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
|
|
||||||
}
|
|
||||||
tmp = macros[macnum].mac_start;
|
|
||||||
while (tmp != macbuf + 4096) {
|
|
||||||
if ((c=getc(cfile)) == EOF) {
|
|
||||||
printf("Macro definition missing null line terminator.\n");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
*tmp = c;
|
|
||||||
if (*tmp == '\n') {
|
|
||||||
if (*(tmp-1) == '\0') {
|
|
||||||
macros[macnum++].mac_end = tmp - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*tmp = '\0';
|
|
||||||
}
|
|
||||||
tmp++;
|
|
||||||
}
|
|
||||||
if (tmp == macbuf + 4096) {
|
|
||||||
printf("4K macro buffer exceeded\n");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PROT:
|
|
||||||
token();
|
|
||||||
if(doencrypt == 0 && sec_request_prot(tokval) < 0)
|
|
||||||
warnx("Unknown protection level \"%s\"", tokval);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
warnx("Unknown .netrc keyword %s", tokval);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
fclose(cfile);
|
|
||||||
return (0);
|
|
||||||
bad:
|
|
||||||
fclose(cfile);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
token(void)
|
|
||||||
{
|
|
||||||
char *cp;
|
|
||||||
int c;
|
|
||||||
struct toktab *t;
|
|
||||||
|
|
||||||
if (feof(cfile) || ferror(cfile))
|
|
||||||
return (0);
|
|
||||||
while ((c = getc(cfile)) != EOF &&
|
|
||||||
(c == '\n' || c == '\t' || c == ' ' || c == ','))
|
|
||||||
continue;
|
|
||||||
if (c == EOF)
|
|
||||||
return (0);
|
|
||||||
cp = tokval;
|
|
||||||
if (c == '"') {
|
|
||||||
while ((c = getc(cfile)) != EOF && c != '"') {
|
|
||||||
if (c == '\\')
|
|
||||||
c = getc(cfile);
|
|
||||||
*cp++ = c;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*cp++ = c;
|
|
||||||
while ((c = getc(cfile)) != EOF
|
|
||||||
&& c != '\n' && c != '\t' && c != ' ' && c != ',') {
|
|
||||||
if (c == '\\')
|
|
||||||
c = getc(cfile);
|
|
||||||
*cp++ = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*cp = 0;
|
|
||||||
if (tokval[0] == 0)
|
|
||||||
return (0);
|
|
||||||
for (t = toktab; t->tokstr; t++)
|
|
||||||
if (!strcmp(t->tokstr, tokval))
|
|
||||||
return (t->tval);
|
|
||||||
return (ID);
|
|
||||||
}
|
|
@@ -1,883 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1998-2002, 2005 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
#include "ftpd_locl.h"
|
|
||||||
#else
|
|
||||||
#include "ftp_locl.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
static enum protection_level command_prot;
|
|
||||||
static enum protection_level data_prot;
|
|
||||||
static size_t buffer_size;
|
|
||||||
|
|
||||||
struct buffer {
|
|
||||||
void *data;
|
|
||||||
size_t size;
|
|
||||||
size_t index;
|
|
||||||
int eof_flag;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct buffer in_buffer, out_buffer;
|
|
||||||
int sec_complete;
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
enum protection_level level;
|
|
||||||
const char *name;
|
|
||||||
} level_names[] = {
|
|
||||||
{ prot_clear, "clear" },
|
|
||||||
{ prot_safe, "safe" },
|
|
||||||
{ prot_confidential, "confidential" },
|
|
||||||
{ prot_private, "private" }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
level_to_name(enum protection_level level)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
|
|
||||||
if(level_names[i].level == level)
|
|
||||||
return level_names[i].name;
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef FTP_SERVER /* not used in server */
|
|
||||||
static enum protection_level
|
|
||||||
name_to_level(const char *name)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
|
|
||||||
if(!strncasecmp(level_names[i].name, name, strlen(name)))
|
|
||||||
return level_names[i].level;
|
|
||||||
return prot_invalid;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
|
|
||||||
static struct sec_server_mech *mechs[] = {
|
|
||||||
#ifdef KRB5
|
|
||||||
&gss_server_mech,
|
|
||||||
#endif
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sec_server_mech *mech;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static struct sec_client_mech *mechs[] = {
|
|
||||||
#ifdef KRB5
|
|
||||||
&gss_client_mech,
|
|
||||||
#endif
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sec_client_mech *mech;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void *app_data;
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_getc(FILE *F)
|
|
||||||
{
|
|
||||||
if(sec_complete && data_prot) {
|
|
||||||
char c;
|
|
||||||
if(sec_read(fileno(F), &c, 1) <= 0)
|
|
||||||
return EOF;
|
|
||||||
return c;
|
|
||||||
} else
|
|
||||||
return getc(F);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
block_read(int fd, void *buf, size_t len)
|
|
||||||
{
|
|
||||||
unsigned char *p = buf;
|
|
||||||
int b;
|
|
||||||
while(len) {
|
|
||||||
b = read(fd, p, len);
|
|
||||||
if (b == 0)
|
|
||||||
return 0;
|
|
||||||
else if (b < 0)
|
|
||||||
return -1;
|
|
||||||
len -= b;
|
|
||||||
p += b;
|
|
||||||
}
|
|
||||||
return p - (unsigned char*)buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
block_write(int fd, void *buf, size_t len)
|
|
||||||
{
|
|
||||||
unsigned char *p = buf;
|
|
||||||
int b;
|
|
||||||
while(len) {
|
|
||||||
b = write(fd, p, len);
|
|
||||||
if(b < 0)
|
|
||||||
return -1;
|
|
||||||
len -= b;
|
|
||||||
p += b;
|
|
||||||
}
|
|
||||||
return p - (unsigned char*)buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
sec_get_data(int fd, struct buffer *buf, int level)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
int b;
|
|
||||||
void *tmp;
|
|
||||||
|
|
||||||
b = block_read(fd, &len, sizeof(len));
|
|
||||||
if (b == 0)
|
|
||||||
return 0;
|
|
||||||
else if (b < 0)
|
|
||||||
return -1;
|
|
||||||
len = ntohl(len);
|
|
||||||
tmp = realloc(buf->data, len);
|
|
||||||
if (tmp == NULL)
|
|
||||||
return -1;
|
|
||||||
buf->data = tmp;
|
|
||||||
b = block_read(fd, buf->data, len);
|
|
||||||
if (b == 0)
|
|
||||||
return 0;
|
|
||||||
else if (b < 0)
|
|
||||||
return -1;
|
|
||||||
buf->size = (*mech->decode)(app_data, buf->data, len, data_prot);
|
|
||||||
buf->index = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
buffer_read(struct buffer *buf, void *dataptr, size_t len)
|
|
||||||
{
|
|
||||||
len = min(len, buf->size - buf->index);
|
|
||||||
memcpy(dataptr, (char*)buf->data + buf->index, len);
|
|
||||||
buf->index += len;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
buffer_write(struct buffer *buf, void *dataptr, size_t len)
|
|
||||||
{
|
|
||||||
if(buf->index + len > buf->size) {
|
|
||||||
void *tmp;
|
|
||||||
if(buf->data == NULL)
|
|
||||||
tmp = malloc(1024);
|
|
||||||
else
|
|
||||||
tmp = realloc(buf->data, buf->index + len);
|
|
||||||
if(tmp == NULL)
|
|
||||||
return -1;
|
|
||||||
buf->data = tmp;
|
|
||||||
buf->size = buf->index + len;
|
|
||||||
}
|
|
||||||
memcpy((char*)buf->data + buf->index, dataptr, len);
|
|
||||||
buf->index += len;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_read(int fd, void *dataptr, int length)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
int rx = 0;
|
|
||||||
|
|
||||||
if(sec_complete == 0 || data_prot == 0)
|
|
||||||
return read(fd, dataptr, length);
|
|
||||||
|
|
||||||
if(in_buffer.eof_flag){
|
|
||||||
in_buffer.eof_flag = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = buffer_read(&in_buffer, dataptr, length);
|
|
||||||
length -= len;
|
|
||||||
rx += len;
|
|
||||||
dataptr = (char*)dataptr + len;
|
|
||||||
|
|
||||||
while(length){
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = sec_get_data(fd, &in_buffer, data_prot);
|
|
||||||
if (ret < 0)
|
|
||||||
return -1;
|
|
||||||
if(ret == 0 && in_buffer.size == 0) {
|
|
||||||
if(rx)
|
|
||||||
in_buffer.eof_flag = 1;
|
|
||||||
return rx;
|
|
||||||
}
|
|
||||||
len = buffer_read(&in_buffer, dataptr, length);
|
|
||||||
length -= len;
|
|
||||||
rx += len;
|
|
||||||
dataptr = (char*)dataptr + len;
|
|
||||||
}
|
|
||||||
return rx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
sec_send(int fd, char *from, int length)
|
|
||||||
{
|
|
||||||
int bytes;
|
|
||||||
void *buf;
|
|
||||||
bytes = (*mech->encode)(app_data, from, length, data_prot, &buf);
|
|
||||||
bytes = htonl(bytes);
|
|
||||||
block_write(fd, &bytes, sizeof(bytes));
|
|
||||||
block_write(fd, buf, ntohl(bytes));
|
|
||||||
free(buf);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_fflush(FILE *F)
|
|
||||||
{
|
|
||||||
if(data_prot != prot_clear) {
|
|
||||||
if(out_buffer.index > 0){
|
|
||||||
sec_write(fileno(F), out_buffer.data, out_buffer.index);
|
|
||||||
out_buffer.index = 0;
|
|
||||||
}
|
|
||||||
sec_send(fileno(F), NULL, 0);
|
|
||||||
}
|
|
||||||
fflush(F);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_write(int fd, char *dataptr, int length)
|
|
||||||
{
|
|
||||||
int len = buffer_size;
|
|
||||||
int tx = 0;
|
|
||||||
|
|
||||||
if(data_prot == prot_clear)
|
|
||||||
return write(fd, dataptr, length);
|
|
||||||
|
|
||||||
len -= (*mech->overhead)(app_data, data_prot, len);
|
|
||||||
while(length){
|
|
||||||
if(length < len)
|
|
||||||
len = length;
|
|
||||||
sec_send(fd, dataptr, len);
|
|
||||||
length -= len;
|
|
||||||
dataptr += len;
|
|
||||||
tx += len;
|
|
||||||
}
|
|
||||||
return tx;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_vfprintf2(FILE *f, const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
int ret;
|
|
||||||
if(data_prot == prot_clear)
|
|
||||||
return vfprintf(f, fmt, ap);
|
|
||||||
else {
|
|
||||||
int len;
|
|
||||||
len = vasprintf(&buf, fmt, ap);
|
|
||||||
if (len == -1)
|
|
||||||
return len;
|
|
||||||
ret = buffer_write(&out_buffer, buf, len);
|
|
||||||
free(buf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_fprintf2(FILE *f, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
ret = sec_vfprintf2(f, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_putc(int c, FILE *F)
|
|
||||||
{
|
|
||||||
char ch = c;
|
|
||||||
if(data_prot == prot_clear)
|
|
||||||
return putc(c, F);
|
|
||||||
|
|
||||||
buffer_write(&out_buffer, &ch, 1);
|
|
||||||
if(c == '\n' || out_buffer.index >= 1024 /* XXX */) {
|
|
||||||
sec_write(fileno(F), out_buffer.data, out_buffer.index);
|
|
||||||
out_buffer.index = 0;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_read_msg(char *s, int level)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *buf;
|
|
||||||
int return_code;
|
|
||||||
|
|
||||||
buf = malloc(strlen(s));
|
|
||||||
len = rk_base64_decode(s + 4, buf); /* XXX */
|
|
||||||
|
|
||||||
len = (*mech->decode)(app_data, buf, len, level);
|
|
||||||
if(len < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
if(buf[3] == '-')
|
|
||||||
return_code = 0;
|
|
||||||
else
|
|
||||||
sscanf(buf, "%d", &return_code);
|
|
||||||
if(buf[len-1] == '\n')
|
|
||||||
buf[len-1] = '\0';
|
|
||||||
strcpy(s, buf);
|
|
||||||
free(buf);
|
|
||||||
return return_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_vfprintf(FILE *f, const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
void *enc;
|
|
||||||
int len;
|
|
||||||
if(!sec_complete)
|
|
||||||
return vfprintf(f, fmt, ap);
|
|
||||||
|
|
||||||
if (vasprintf(&buf, fmt, ap) == -1) {
|
|
||||||
printf("Failed to allocate command.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
len = (*mech->encode)(app_data, buf, strlen(buf), command_prot, &enc);
|
|
||||||
free(buf);
|
|
||||||
if(len < 0) {
|
|
||||||
printf("Failed to encode command.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(rk_base64_encode(enc, len, &buf) < 0){
|
|
||||||
free(enc);
|
|
||||||
printf("Out of memory base64-encoding.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
free(enc);
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
if(command_prot == prot_safe)
|
|
||||||
fprintf(f, "631 %s\r\n", buf);
|
|
||||||
else if(command_prot == prot_private)
|
|
||||||
fprintf(f, "632 %s\r\n", buf);
|
|
||||||
else if(command_prot == prot_confidential)
|
|
||||||
fprintf(f, "633 %s\r\n", buf);
|
|
||||||
#else
|
|
||||||
if(command_prot == prot_safe)
|
|
||||||
fprintf(f, "MIC %s", buf);
|
|
||||||
else if(command_prot == prot_private)
|
|
||||||
fprintf(f, "ENC %s", buf);
|
|
||||||
else if(command_prot == prot_confidential)
|
|
||||||
fprintf(f, "CONF %s", buf);
|
|
||||||
#endif
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_fprintf(FILE *f, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int ret;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
ret = sec_vfprintf(f, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end common stuff */
|
|
||||||
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
|
|
||||||
int ccc_passed;
|
|
||||||
|
|
||||||
void
|
|
||||||
auth(char *auth_name)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
void *tmp;
|
|
||||||
|
|
||||||
for(i = 0; (mech = mechs[i]) != NULL; i++){
|
|
||||||
if(!strcasecmp(auth_name, mech->name)){
|
|
||||||
tmp = realloc(app_data, mech->size);
|
|
||||||
if (tmp == NULL) {
|
|
||||||
reply(431, "Unable to accept %s at this time", mech->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
app_data = tmp;
|
|
||||||
|
|
||||||
if(mech->init && (*mech->init)(app_data) != 0) {
|
|
||||||
reply(431, "Unable to accept %s at this time", mech->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(mech->auth) {
|
|
||||||
(*mech->auth)(app_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(mech->adat)
|
|
||||||
reply(334, "Send authorization data.");
|
|
||||||
else
|
|
||||||
reply(234, "Authorization complete.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free (app_data);
|
|
||||||
app_data = NULL;
|
|
||||||
reply(504, "%s is unknown to me", auth_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
adat(char *auth_data)
|
|
||||||
{
|
|
||||||
if(mech && !sec_complete) {
|
|
||||||
void *buf = malloc(strlen(auth_data));
|
|
||||||
size_t len;
|
|
||||||
len = rk_base64_decode(auth_data, buf);
|
|
||||||
(*mech->adat)(app_data, buf, len);
|
|
||||||
free(buf);
|
|
||||||
} else
|
|
||||||
reply(503, "You must %sissue an AUTH first.", mech ? "re-" : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
void pbsz(int size)
|
|
||||||
{
|
|
||||||
size_t new = size;
|
|
||||||
if(!sec_complete)
|
|
||||||
reply(503, "Incomplete security data exchange.");
|
|
||||||
if(mech->pbsz)
|
|
||||||
new = (*mech->pbsz)(app_data, size);
|
|
||||||
if(buffer_size != new){
|
|
||||||
buffer_size = size;
|
|
||||||
}
|
|
||||||
if(new != size)
|
|
||||||
reply(200, "PBSZ=%lu", (unsigned long)new);
|
|
||||||
else
|
|
||||||
reply(200, "OK");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
prot(char *pl)
|
|
||||||
{
|
|
||||||
int p = -1;
|
|
||||||
|
|
||||||
if(buffer_size == 0){
|
|
||||||
reply(503, "No protection buffer size negotiated.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!strcasecmp(pl, "C"))
|
|
||||||
p = prot_clear;
|
|
||||||
else if(!strcasecmp(pl, "S"))
|
|
||||||
p = prot_safe;
|
|
||||||
else if(!strcasecmp(pl, "E"))
|
|
||||||
p = prot_confidential;
|
|
||||||
else if(!strcasecmp(pl, "P"))
|
|
||||||
p = prot_private;
|
|
||||||
else {
|
|
||||||
reply(504, "Unrecognized protection level.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sec_complete){
|
|
||||||
if((*mech->check_prot)(app_data, p)){
|
|
||||||
reply(536, "%s does not support %s protection.",
|
|
||||||
mech->name, level_to_name(p));
|
|
||||||
}else{
|
|
||||||
data_prot = (enum protection_level)p;
|
|
||||||
reply(200, "Data protection is %s.", level_to_name(p));
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
reply(503, "Incomplete security data exchange.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ccc(void)
|
|
||||||
{
|
|
||||||
if(sec_complete){
|
|
||||||
if(mech->ccc && (*mech->ccc)(app_data) == 0) {
|
|
||||||
command_prot = data_prot = prot_clear;
|
|
||||||
ccc_passed = 1;
|
|
||||||
} else
|
|
||||||
reply(534, "You must be joking.");
|
|
||||||
}else
|
|
||||||
reply(503, "Incomplete security data exchange.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void mec(char *msg, enum protection_level level)
|
|
||||||
{
|
|
||||||
void *buf;
|
|
||||||
size_t len, buf_size;
|
|
||||||
if(!sec_complete) {
|
|
||||||
reply(503, "Incomplete security data exchange.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
buf_size = strlen(msg) + 2;
|
|
||||||
buf = malloc(buf_size);
|
|
||||||
if (buf == NULL) {
|
|
||||||
reply(501, "Failed to allocate %lu", (unsigned long)buf_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
len = rk_base64_decode(msg, buf);
|
|
||||||
command_prot = level;
|
|
||||||
if(len == (size_t)-1) {
|
|
||||||
free(buf);
|
|
||||||
reply(501, "Failed to base64-decode command");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
len = (*mech->decode)(app_data, buf, len, level);
|
|
||||||
if(len == (size_t)-1) {
|
|
||||||
free(buf);
|
|
||||||
reply(535, "Failed to decode command");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
((char*)buf)[len] = '\0';
|
|
||||||
if(strstr((char*)buf, "\r\n") == NULL)
|
|
||||||
strlcat((char*)buf, "\r\n", buf_size);
|
|
||||||
new_ftp_command(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_userok(char *userstr)
|
|
||||||
{
|
|
||||||
if(sec_complete)
|
|
||||||
return (*mech->userok)(app_data, userstr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_session(char *user)
|
|
||||||
{
|
|
||||||
if(sec_complete && mech->session)
|
|
||||||
return (*mech->session)(app_data, user);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *ftp_command;
|
|
||||||
|
|
||||||
void
|
|
||||||
new_ftp_command(char *command)
|
|
||||||
{
|
|
||||||
ftp_command = command;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
delete_ftp_command(void)
|
|
||||||
{
|
|
||||||
free(ftp_command);
|
|
||||||
ftp_command = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
secure_command(void)
|
|
||||||
{
|
|
||||||
return ftp_command != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum protection_level
|
|
||||||
get_command_prot(void)
|
|
||||||
{
|
|
||||||
return command_prot;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* FTP_SERVER */
|
|
||||||
|
|
||||||
void
|
|
||||||
sec_status(void)
|
|
||||||
{
|
|
||||||
if(sec_complete){
|
|
||||||
printf("Using %s for authentication.\n", mech->name);
|
|
||||||
printf("Using %s command channel.\n", level_to_name(command_prot));
|
|
||||||
printf("Using %s data channel.\n", level_to_name(data_prot));
|
|
||||||
if(buffer_size > 0)
|
|
||||||
printf("Protection buffer size: %lu.\n",
|
|
||||||
(unsigned long)buffer_size);
|
|
||||||
}else{
|
|
||||||
printf("Not using any security mechanism.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
sec_prot_internal(int level)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
char *p;
|
|
||||||
unsigned int s = 1048576;
|
|
||||||
|
|
||||||
int old_verbose = verbose;
|
|
||||||
verbose = 0;
|
|
||||||
|
|
||||||
if(!sec_complete){
|
|
||||||
printf("No security data exchange has taken place.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(level){
|
|
||||||
ret = command("PBSZ %u", s);
|
|
||||||
if(ret != COMPLETE){
|
|
||||||
printf("Failed to set protection buffer size.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
buffer_size = s;
|
|
||||||
p = strstr(reply_string, "PBSZ=");
|
|
||||||
if(p)
|
|
||||||
sscanf(p, "PBSZ=%u", &s);
|
|
||||||
if(s < buffer_size)
|
|
||||||
buffer_size = s;
|
|
||||||
}
|
|
||||||
verbose = old_verbose;
|
|
||||||
ret = command("PROT %c", level["CSEP"]); /* XXX :-) */
|
|
||||||
if(ret != COMPLETE){
|
|
||||||
printf("Failed to set protection level.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
data_prot = (enum protection_level)level;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum protection_level
|
|
||||||
set_command_prot(enum protection_level level)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
enum protection_level old = command_prot;
|
|
||||||
if(level != command_prot && level == prot_clear) {
|
|
||||||
ret = command("CCC");
|
|
||||||
if(ret != COMPLETE) {
|
|
||||||
printf("Failed to clear command channel.\n");
|
|
||||||
return prot_invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
command_prot = level;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sec_prot(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int level = -1;
|
|
||||||
|
|
||||||
if(argc > 3)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
if(argc == 1) {
|
|
||||||
sec_status();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(!sec_complete) {
|
|
||||||
printf("No security data exchange has taken place.\n");
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
level = name_to_level(argv[argc - 1]);
|
|
||||||
|
|
||||||
if(level == -1)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
if((*mech->check_prot)(app_data, level)) {
|
|
||||||
printf("%s does not implement %s protection.\n",
|
|
||||||
mech->name, level_to_name(level));
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc == 2 || strncasecmp(argv[1], "data", strlen(argv[1])) == 0) {
|
|
||||||
if(sec_prot_internal(level) < 0){
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if(strncasecmp(argv[1], "command", strlen(argv[1])) == 0) {
|
|
||||||
if(set_command_prot(level) < 0) {
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
goto usage;
|
|
||||||
code = 0;
|
|
||||||
return;
|
|
||||||
usage:
|
|
||||||
printf("usage: %s [command|data] [clear|safe|confidential|private]\n",
|
|
||||||
argv[0]);
|
|
||||||
code = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sec_prot_command(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int level;
|
|
||||||
|
|
||||||
if(argc > 2)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
if(!sec_complete) {
|
|
||||||
printf("No security data exchange has taken place.\n");
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc == 1) {
|
|
||||||
sec_status();
|
|
||||||
} else {
|
|
||||||
level = name_to_level(argv[1]);
|
|
||||||
if(level == -1)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
if((*mech->check_prot)(app_data, level)) {
|
|
||||||
printf("%s does not implement %s protection.\n",
|
|
||||||
mech->name, level_to_name(level));
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(set_command_prot(level) < 0) {
|
|
||||||
code = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
code = 0;
|
|
||||||
return;
|
|
||||||
usage:
|
|
||||||
printf("usage: %s [clear|safe|confidential|private]\n",
|
|
||||||
argv[0]);
|
|
||||||
code = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum protection_level request_data_prot;
|
|
||||||
|
|
||||||
void
|
|
||||||
sec_set_protection_level(void)
|
|
||||||
{
|
|
||||||
if(sec_complete && data_prot != request_data_prot)
|
|
||||||
sec_prot_internal(request_data_prot);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_request_prot(char *level)
|
|
||||||
{
|
|
||||||
int l = name_to_level(level);
|
|
||||||
if(l == -1)
|
|
||||||
return -1;
|
|
||||||
request_data_prot = (enum protection_level)l;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sec_login(char *host)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct sec_client_mech **m;
|
|
||||||
int old_verbose = verbose;
|
|
||||||
|
|
||||||
verbose = -1; /* shut up all messages this will produce (they
|
|
||||||
are usually not very user friendly) */
|
|
||||||
|
|
||||||
for(m = mechs; *m && (*m)->name; m++) {
|
|
||||||
void *tmp;
|
|
||||||
|
|
||||||
tmp = realloc(app_data, (*m)->size);
|
|
||||||
if (tmp == NULL) {
|
|
||||||
warnx ("realloc %lu failed", (unsigned long)(*m)->size);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
app_data = tmp;
|
|
||||||
|
|
||||||
if((*m)->init && (*(*m)->init)(app_data) != 0) {
|
|
||||||
printf("Skipping %s...\n", (*m)->name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
printf("Trying %s...\n", (*m)->name);
|
|
||||||
ret = command("AUTH %s", (*m)->name);
|
|
||||||
if(ret != CONTINUE){
|
|
||||||
if(code == 504){
|
|
||||||
printf("%s is not supported by the server.\n", (*m)->name);
|
|
||||||
}else if(code == 534){
|
|
||||||
printf("%s rejected as security mechanism.\n", (*m)->name);
|
|
||||||
}else if(ret == ERROR) {
|
|
||||||
printf("The server doesn't support the FTP "
|
|
||||||
"security extensions.\n");
|
|
||||||
verbose = old_verbose;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = (*(*m)->auth)(app_data, host);
|
|
||||||
|
|
||||||
if(ret == AUTH_CONTINUE)
|
|
||||||
continue;
|
|
||||||
else if(ret != AUTH_OK){
|
|
||||||
/* mechanism is supposed to output error string */
|
|
||||||
verbose = old_verbose;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mech = *m;
|
|
||||||
sec_complete = 1;
|
|
||||||
if(doencrypt) {
|
|
||||||
command_prot = prot_private;
|
|
||||||
request_data_prot = prot_private;
|
|
||||||
} else {
|
|
||||||
command_prot = prot_safe;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
verbose = old_verbose;
|
|
||||||
return *m == NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sec_end(void)
|
|
||||||
{
|
|
||||||
if (mech != NULL) {
|
|
||||||
if(mech->end)
|
|
||||||
(*mech->end)(app_data);
|
|
||||||
if (app_data != NULL) {
|
|
||||||
memset(app_data, 0, mech->size);
|
|
||||||
free(app_data);
|
|
||||||
app_data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sec_complete = 0;
|
|
||||||
data_prot = (enum protection_level)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FTP_SERVER */
|
|
||||||
|
|
@@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#ifndef __security_h__
|
|
||||||
#define __security_h__
|
|
||||||
|
|
||||||
enum protection_level {
|
|
||||||
prot_invalid = -1,
|
|
||||||
prot_clear = 0,
|
|
||||||
prot_safe = 1,
|
|
||||||
prot_confidential = 2,
|
|
||||||
prot_private = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sec_client_mech {
|
|
||||||
char *name;
|
|
||||||
size_t size;
|
|
||||||
int (*init)(void *);
|
|
||||||
int (*auth)(void *, char*);
|
|
||||||
void (*end)(void *);
|
|
||||||
int (*check_prot)(void *, int);
|
|
||||||
int (*overhead)(void *, int, int);
|
|
||||||
int (*encode)(void *, void*, int, int, void**);
|
|
||||||
int (*decode)(void *, void*, int, int);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sec_server_mech {
|
|
||||||
char *name;
|
|
||||||
size_t size;
|
|
||||||
int (*init)(void *);
|
|
||||||
void (*end)(void *);
|
|
||||||
int (*check_prot)(void *, int);
|
|
||||||
int (*overhead)(void *, int, int);
|
|
||||||
int (*encode)(void *, void*, int, int, void**);
|
|
||||||
int (*decode)(void *, void*, int, int);
|
|
||||||
|
|
||||||
int (*auth)(void *);
|
|
||||||
int (*adat)(void *, void*, size_t);
|
|
||||||
size_t (*pbsz)(void *, size_t);
|
|
||||||
int (*ccc)(void*);
|
|
||||||
int (*userok)(void*, char*);
|
|
||||||
int (*session)(void*, char*);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define AUTH_OK 0
|
|
||||||
#define AUTH_CONTINUE 1
|
|
||||||
#define AUTH_ERROR 2
|
|
||||||
|
|
||||||
extern int ftp_do_gss_bindings;
|
|
||||||
extern int ftp_do_gss_delegate;
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
extern struct sec_server_mech krb4_server_mech, gss_server_mech;
|
|
||||||
#else
|
|
||||||
extern struct sec_client_mech krb4_client_mech, gss_client_mech;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int sec_complete;
|
|
||||||
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
extern char *ftp_command;
|
|
||||||
void new_ftp_command(char*);
|
|
||||||
void delete_ftp_command(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ---- */
|
|
||||||
|
|
||||||
|
|
||||||
int sec_fflush (FILE *);
|
|
||||||
int sec_fprintf (FILE *, const char *, ...)
|
|
||||||
__attribute__ ((format (printf, 2,3)));
|
|
||||||
int sec_getc (FILE *);
|
|
||||||
int sec_putc (int, FILE *);
|
|
||||||
int sec_read (int, void *, int);
|
|
||||||
int sec_read_msg (char *, int);
|
|
||||||
int sec_vfprintf (FILE *, const char *, va_list)
|
|
||||||
__attribute__ ((format (printf, 2,0)));
|
|
||||||
int sec_fprintf2(FILE *f, const char *fmt, ...)
|
|
||||||
__attribute__ ((format (printf, 2,3)));
|
|
||||||
int sec_vfprintf2(FILE *, const char *, va_list)
|
|
||||||
__attribute__ ((format (printf, 2,0)));
|
|
||||||
int sec_write (int, char *, int);
|
|
||||||
|
|
||||||
#ifdef FTP_SERVER
|
|
||||||
void adat (char *);
|
|
||||||
void auth (char *);
|
|
||||||
void ccc (void);
|
|
||||||
void mec (char *, enum protection_level);
|
|
||||||
void pbsz (int);
|
|
||||||
void prot (char *);
|
|
||||||
void delete_ftp_command (void);
|
|
||||||
void new_ftp_command (char *);
|
|
||||||
int sec_userok (char *);
|
|
||||||
int sec_session(char *);
|
|
||||||
int secure_command (void);
|
|
||||||
enum protection_level get_command_prot(void);
|
|
||||||
#else
|
|
||||||
void sec_end (void);
|
|
||||||
int sec_login (char *);
|
|
||||||
void sec_prot (int, char **);
|
|
||||||
void sec_prot_command (int, char **);
|
|
||||||
int sec_request_prot (char *);
|
|
||||||
void sec_set_protection_level (void);
|
|
||||||
void sec_status (void);
|
|
||||||
|
|
||||||
enum protection_level set_command_prot(enum protection_level);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __security_h__ */
|
|
@@ -1,54 +0,0 @@
|
|||||||
# $Id$
|
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.am.common
|
|
||||||
|
|
||||||
AM_CPPFLAGS += -I$(srcdir)/../common -DFTP_SERVER
|
|
||||||
|
|
||||||
WFLAGS += $(WFLAGS_LITE)
|
|
||||||
|
|
||||||
libexec_PROGRAMS = ftpd
|
|
||||||
|
|
||||||
CHECK_LOCAL =
|
|
||||||
|
|
||||||
if KRB5
|
|
||||||
krb5_sources = gssapi.c gss_userok.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ftpd_SOURCES = \
|
|
||||||
extern.h \
|
|
||||||
ftpcmd.y \
|
|
||||||
ftpd.c \
|
|
||||||
ftpd_locl.h \
|
|
||||||
logwtmp.c \
|
|
||||||
ls.c \
|
|
||||||
pathnames.h \
|
|
||||||
popen.c \
|
|
||||||
security.c \
|
|
||||||
kauth.c \
|
|
||||||
klist.c \
|
|
||||||
$(krb5_sources)
|
|
||||||
|
|
||||||
EXTRA_ftpd_SOURCES = kauth.c gssapi.c gss_userok.c
|
|
||||||
|
|
||||||
$(ftpd_OBJECTS): security.h
|
|
||||||
|
|
||||||
security.c:
|
|
||||||
@test -f security.c || $(LN_S) $(srcdir)/../ftp/security.c .
|
|
||||||
security.h:
|
|
||||||
@test -f security.h || $(LN_S) $(srcdir)/../ftp/security.h .
|
|
||||||
gssapi.c:
|
|
||||||
@test -f gssapi.c || $(LN_S) $(srcdir)/../ftp/gssapi.c .
|
|
||||||
|
|
||||||
CLEANFILES = security.c security.h gssapi.c
|
|
||||||
|
|
||||||
man_MANS = ftpd.8 ftpusers.5
|
|
||||||
|
|
||||||
LDADD = ../common/libcommon.a \
|
|
||||||
$(LIB_otp) \
|
|
||||||
$(LIB_gssapi) \
|
|
||||||
$(LIB_krb5) \
|
|
||||||
$(LIB_kafs) \
|
|
||||||
$(LIB_hcrypto) \
|
|
||||||
$(LIB_roken)
|
|
||||||
|
|
||||||
EXTRA_DIST = NTMakefile $(man_MANS)
|
|
@@ -1,35 +0,0 @@
|
|||||||
########################################################################
|
|
||||||
#
|
|
||||||
# Copyright (c) 2009, Secure Endpoints Inc.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions
|
|
||||||
# are met:
|
|
||||||
#
|
|
||||||
# - Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# - 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.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
|
|
||||||
# COPYRIGHT HOLDER 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
RELDIR=appl\ftp\ftpd
|
|
||||||
|
|
||||||
!include ../../../windows/NTMakefile.w32
|
|
||||||
|
|
@@ -1,150 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 1992, 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. 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.
|
|
||||||
*
|
|
||||||
* @(#)extern.h 8.2 (Berkeley) 4/4/94
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _EXTERN_H_
|
|
||||||
#define _EXTERN_H_
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
#include <netdb.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#ifdef HAVE_PWD_H
|
|
||||||
#include <pwd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_LIMITS_H
|
|
||||||
#include <limits.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NBBY
|
|
||||||
#define NBBY CHAR_BIT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void abor(void);
|
|
||||||
void blkfree(char **);
|
|
||||||
char **copyblk(char **);
|
|
||||||
void cwd(const char *);
|
|
||||||
void do_delete(char *);
|
|
||||||
void dologout(int);
|
|
||||||
void eprt(char *);
|
|
||||||
void epsv(char *);
|
|
||||||
void fatal(char *);
|
|
||||||
int filename_check(char *);
|
|
||||||
int ftpd_pclose(FILE *);
|
|
||||||
FILE *ftpd_popen(char *, char *, int, int);
|
|
||||||
char *ftpd_getline(char *, int);
|
|
||||||
void ftpd_logwtmp(char *, char *, char *);
|
|
||||||
void lreply(int, const char *, ...)
|
|
||||||
__attribute__ ((format (printf, 2, 3)));
|
|
||||||
void makedir(char *);
|
|
||||||
void nack(char *);
|
|
||||||
void nreply(const char *, ...)
|
|
||||||
__attribute__ ((format (printf, 1, 2)));
|
|
||||||
void pass(char *);
|
|
||||||
void pasv(void);
|
|
||||||
void perror_reply(int, const char *);
|
|
||||||
void pwd(void);
|
|
||||||
void removedir(char *);
|
|
||||||
void renamecmd(char *, char *);
|
|
||||||
char *renamefrom(char *);
|
|
||||||
void reply(int, const char *, ...)
|
|
||||||
__attribute__ ((format (printf, 2, 3)));
|
|
||||||
void retrieve(const char *, char *);
|
|
||||||
void send_file_list(char *);
|
|
||||||
void setproctitle(const char *, ...)
|
|
||||||
__attribute__ ((format (printf, 1, 2)));
|
|
||||||
void statcmd(void);
|
|
||||||
void statfilecmd(char *);
|
|
||||||
void do_store(char *, char *, int);
|
|
||||||
void upper(char *);
|
|
||||||
void user(char *);
|
|
||||||
void yyerror(char *);
|
|
||||||
|
|
||||||
void list_file(char*);
|
|
||||||
|
|
||||||
void kauth(char *, char*);
|
|
||||||
void klist(void);
|
|
||||||
void cond_kdestroy(void);
|
|
||||||
void kdestroy(void);
|
|
||||||
void krbtkfile(const char *tkfile);
|
|
||||||
void afslog(const char *, int);
|
|
||||||
void afsunlog(void);
|
|
||||||
|
|
||||||
extern int do_destroy_tickets;
|
|
||||||
extern char *k5ccname;
|
|
||||||
|
|
||||||
int find(char *);
|
|
||||||
|
|
||||||
int builtin_ls(FILE*, const char*);
|
|
||||||
|
|
||||||
int do_login(int code, char *passwd);
|
|
||||||
int klogin(char *name, char *password);
|
|
||||||
|
|
||||||
const char *ftp_rooted(const char *path);
|
|
||||||
|
|
||||||
extern struct sockaddr *ctrl_addr, *his_addr;
|
|
||||||
extern char hostname[];
|
|
||||||
|
|
||||||
extern struct sockaddr *data_dest;
|
|
||||||
extern int logged_in;
|
|
||||||
extern struct passwd *pw;
|
|
||||||
extern int guest;
|
|
||||||
extern int dochroot;
|
|
||||||
extern int logging;
|
|
||||||
extern int type;
|
|
||||||
extern off_t file_size;
|
|
||||||
extern off_t byte_count;
|
|
||||||
extern int ccc_passed;
|
|
||||||
|
|
||||||
extern int form;
|
|
||||||
extern int debug;
|
|
||||||
extern int ftpd_timeout;
|
|
||||||
extern int maxtimeout;
|
|
||||||
extern int pdata;
|
|
||||||
extern char hostname[], remotehost[];
|
|
||||||
extern char proctitle[];
|
|
||||||
extern int usedefault;
|
|
||||||
extern char tmpline[];
|
|
||||||
extern int paranoid;
|
|
||||||
|
|
||||||
#endif /* _EXTERN_H_ */
|
|
File diff suppressed because it is too large
Load Diff
@@ -1,503 +0,0 @@
|
|||||||
.\" $NetBSD: ftpd.8,v 1.7 1995/04/11 02:44:53 cgd Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1985, 1988, 1991, 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. 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.
|
|
||||||
.\"
|
|
||||||
.\" @(#)ftpd.8 8.2 (Berkeley) 4/19/94
|
|
||||||
.\"
|
|
||||||
.Dd July 19, 2003
|
|
||||||
.Dt FTPD 8
|
|
||||||
.Os BSD 4.2
|
|
||||||
.Sh NAME
|
|
||||||
.Nm ftpd
|
|
||||||
.Nd Internet File Transfer Protocol server
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Op Fl a Ar authmode
|
|
||||||
.Op Fl dilvU
|
|
||||||
.Op Fl g Ar umask
|
|
||||||
.Op Fl p Ar port
|
|
||||||
.Op Fl T Ar maxtimeout
|
|
||||||
.Op Fl t Ar timeout
|
|
||||||
.Op Fl Fl gss-bindings
|
|
||||||
.Op Fl I | Fl Fl no-insecure-oob
|
|
||||||
.Op Fl u Ar default umask
|
|
||||||
.Op Fl B | Fl Fl builtin-ls
|
|
||||||
.Op Fl Fl good-chars= Ns Ar string
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
.Nm Ftpd
|
|
||||||
is the
|
|
||||||
Internet File Transfer Protocol
|
|
||||||
server process. The server uses the
|
|
||||||
.Tn TCP
|
|
||||||
protocol
|
|
||||||
and listens at the port specified in the
|
|
||||||
.Dq ftp
|
|
||||||
service specification; see
|
|
||||||
.Xr services 5 .
|
|
||||||
.Pp
|
|
||||||
Available options:
|
|
||||||
.Bl -tag -width Ds
|
|
||||||
.It Fl a
|
|
||||||
Select the level of authentication required. Kerberised login can not
|
|
||||||
be turned off. The default is to only allow kerberised login. Other
|
|
||||||
possibilities can be turned on by giving a string of comma separated
|
|
||||||
flags as argument to
|
|
||||||
.Fl a .
|
|
||||||
Recognised flags are:
|
|
||||||
.Bl -tag -width plain
|
|
||||||
.It Ar plain
|
|
||||||
Allow logging in with plaintext password. The password can be a(n) OTP
|
|
||||||
or an ordinary password.
|
|
||||||
.It Ar otp
|
|
||||||
Same as
|
|
||||||
.Ar plain ,
|
|
||||||
but only OTP is allowed.
|
|
||||||
.It Ar ftp
|
|
||||||
Allow anonymous login.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The following combination modes exists for backwards compatibility:
|
|
||||||
.Bl -tag -width plain
|
|
||||||
.It Ar none
|
|
||||||
Same as
|
|
||||||
.Ar plain,ftp .
|
|
||||||
.It Ar safe
|
|
||||||
Same as
|
|
||||||
.Ar ftp .
|
|
||||||
.It Ar user
|
|
||||||
Ignored.
|
|
||||||
.El
|
|
||||||
.It Fl d
|
|
||||||
Debugging information is written to the syslog using LOG_FTP.
|
|
||||||
.It Fl g
|
|
||||||
Anonymous users will get a umask of
|
|
||||||
.Ar umask .
|
|
||||||
.It Fl Fl gss-bindings
|
|
||||||
require the peer to use GSS-API bindings (ie make sure IP addresses match).
|
|
||||||
.It Fl i
|
|
||||||
Open a socket and wait for a connection. This is mainly used for
|
|
||||||
debugging when ftpd isn't started by inetd.
|
|
||||||
.It Fl l
|
|
||||||
Each successful and failed
|
|
||||||
.Xr ftp 1
|
|
||||||
session is logged using syslog with a facility of LOG_FTP.
|
|
||||||
If this option is specified twice, the retrieve (get), store (put), append,
|
|
||||||
delete, make directory, remove directory and rename operations and
|
|
||||||
their filename arguments are also logged.
|
|
||||||
.It Fl p
|
|
||||||
Use
|
|
||||||
.Ar port
|
|
||||||
(a service name or number) instead of the default
|
|
||||||
.Ar ftp/tcp .
|
|
||||||
.It Fl T
|
|
||||||
A client may also request a different timeout period;
|
|
||||||
the maximum period allowed may be set to
|
|
||||||
.Ar timeout
|
|
||||||
seconds with the
|
|
||||||
.Fl T
|
|
||||||
option.
|
|
||||||
The default limit is 2 hours.
|
|
||||||
.It Fl t
|
|
||||||
The inactivity timeout period is set to
|
|
||||||
.Ar timeout
|
|
||||||
seconds (the default is 15 minutes).
|
|
||||||
.It Fl u
|
|
||||||
Set the initial umask to something else than the default 027.
|
|
||||||
.It Fl U
|
|
||||||
In previous versions of
|
|
||||||
.Nm ftpd ,
|
|
||||||
when a passive mode client requested a data connection to the server, the
|
|
||||||
server would use data ports in the range 1024..4999. Now, by default,
|
|
||||||
if the system supports the IP_PORTRANGE socket option, the server will
|
|
||||||
use data ports in the range 49152..65535. Specifying this option will
|
|
||||||
revert to the old behavior.
|
|
||||||
.It Fl v
|
|
||||||
Verbose mode.
|
|
||||||
.It Xo
|
|
||||||
.Fl B ,
|
|
||||||
.Fl Fl builtin-ls
|
|
||||||
.Xc
|
|
||||||
use built-in ls to list files
|
|
||||||
.It Xo
|
|
||||||
.Fl Fl good-chars= Ns Ar string
|
|
||||||
.Xc
|
|
||||||
allowed anonymous upload filename chars
|
|
||||||
.It Xo
|
|
||||||
.Fl I
|
|
||||||
.Fl Fl no-insecure-oob
|
|
||||||
.Xc
|
|
||||||
don't allow insecure out of band.
|
|
||||||
Heimdal ftp clients before 0.6.3 doesn't support secure oob, so turning
|
|
||||||
on this option makes them no longer work.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The file
|
|
||||||
.Pa /etc/nologin
|
|
||||||
can be used to disable ftp access.
|
|
||||||
If the file exists,
|
|
||||||
.Nm
|
|
||||||
displays it and exits.
|
|
||||||
If the file
|
|
||||||
.Pa /etc/ftpwelcome
|
|
||||||
exists,
|
|
||||||
.Nm
|
|
||||||
prints it before issuing the
|
|
||||||
.Dq ready
|
|
||||||
message.
|
|
||||||
If the file
|
|
||||||
.Pa /etc/motd
|
|
||||||
exists,
|
|
||||||
.Nm
|
|
||||||
prints it after a successful login.
|
|
||||||
.Pp
|
|
||||||
The ftp server currently supports the following ftp requests.
|
|
||||||
The case of the requests is ignored.
|
|
||||||
.Bl -column "Request" -offset indent
|
|
||||||
.It Request Ta "Description"
|
|
||||||
.It ABOR Ta "abort previous command"
|
|
||||||
.It ACCT Ta "specify account (ignored)"
|
|
||||||
.It ALLO Ta "allocate storage (vacuously)"
|
|
||||||
.It APPE Ta "append to a file"
|
|
||||||
.It CDUP Ta "change to parent of current working directory"
|
|
||||||
.It CWD Ta "change working directory"
|
|
||||||
.It DELE Ta "delete a file"
|
|
||||||
.It HELP Ta "give help information"
|
|
||||||
.It LIST Ta "give list files in a directory" Pq Dq Li "ls -lgA"
|
|
||||||
.It MKD Ta "make a directory"
|
|
||||||
.It MDTM Ta "show last modification time of file"
|
|
||||||
.It MODE Ta "specify data transfer" Em mode
|
|
||||||
.It NLST Ta "give name list of files in directory"
|
|
||||||
.It NOOP Ta "do nothing"
|
|
||||||
.It PASS Ta "specify password"
|
|
||||||
.It PASV Ta "prepare for server-to-server transfer"
|
|
||||||
.It PORT Ta "specify data connection port"
|
|
||||||
.It PWD Ta "print the current working directory"
|
|
||||||
.It QUIT Ta "terminate session"
|
|
||||||
.It REST Ta "restart incomplete transfer"
|
|
||||||
.It RETR Ta "retrieve a file"
|
|
||||||
.It RMD Ta "remove a directory"
|
|
||||||
.It RNFR Ta "specify rename-from file name"
|
|
||||||
.It RNTO Ta "specify rename-to file name"
|
|
||||||
.It SITE Ta "non-standard commands (see next section)"
|
|
||||||
.It SIZE Ta "return size of file"
|
|
||||||
.It STAT Ta "return status of server"
|
|
||||||
.It STOR Ta "store a file"
|
|
||||||
.It STOU Ta "store a file with a unique name"
|
|
||||||
.It STRU Ta "specify data transfer" Em structure
|
|
||||||
.It SYST Ta "show operating system type of server system"
|
|
||||||
.It TYPE Ta "specify data transfer" Em type
|
|
||||||
.It USER Ta "specify user name"
|
|
||||||
.It XCUP Ta "change to parent of current working directory (deprecated)"
|
|
||||||
.It XCWD Ta "change working directory (deprecated)"
|
|
||||||
.It XMKD Ta "make a directory (deprecated)"
|
|
||||||
.It XPWD Ta "print the current working directory (deprecated)"
|
|
||||||
.It XRMD Ta "remove a directory (deprecated)"
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The following commands are specified by RFC2228.
|
|
||||||
.Bl -column Request -offset indent
|
|
||||||
.It AUTH Ta "authentication/security mechanism"
|
|
||||||
.It ADAT Ta "authentication/security data"
|
|
||||||
.It PROT Ta "data channel protection level"
|
|
||||||
.It PBSZ Ta "protection buffer size"
|
|
||||||
.It MIC Ta "integrity protected command"
|
|
||||||
.It CONF Ta "confidentiality protected command"
|
|
||||||
.It ENC Ta "privacy protected command"
|
|
||||||
.It CCC Ta "clear command channel"
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The following non-standard or
|
|
||||||
.Tn UNIX
|
|
||||||
specific commands are supported
|
|
||||||
by the
|
|
||||||
SITE request.
|
|
||||||
.Pp
|
|
||||||
.Bl -column Request -offset indent
|
|
||||||
.It UMASK Ta change umask, (e.g.
|
|
||||||
.Ic "SITE UMASK 002" )
|
|
||||||
.It IDLE Ta set idle-timer, (e.g.
|
|
||||||
.Ic "SITE IDLE 60" )
|
|
||||||
.It CHMOD Ta change mode of a file (e.g.
|
|
||||||
.Ic "SITE CHMOD 755 filename" )
|
|
||||||
.It FIND Ta quickly find a specific file with GNU
|
|
||||||
.Xr locate 1 .
|
|
||||||
.It HELP Ta give help information.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The following Kerberos related site commands are understood.
|
|
||||||
.Bl -column Request -offset indent
|
|
||||||
.It KAUTH Ta obtain remote tickets.
|
|
||||||
.It KLIST Ta show remote tickets
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The remaining ftp requests specified in Internet RFC 959
|
|
||||||
are
|
|
||||||
recognized, but not implemented.
|
|
||||||
MDTM and SIZE are not specified in RFC 959, but will appear in the
|
|
||||||
next updated FTP RFC.
|
|
||||||
.Pp
|
|
||||||
The ftp server will abort an active file transfer only when the
|
|
||||||
ABOR
|
|
||||||
command is preceded by a Telnet "Interrupt Process" (IP)
|
|
||||||
signal and a Telnet "Synch" signal in the command Telnet stream,
|
|
||||||
as described in Internet RFC 959.
|
|
||||||
If a
|
|
||||||
STAT
|
|
||||||
command is received during a data transfer, preceded by a Telnet IP
|
|
||||||
and Synch, transfer status will be returned.
|
|
||||||
.Pp
|
|
||||||
.Nm Ftpd
|
|
||||||
interprets file names according to the
|
|
||||||
.Dq globbing
|
|
||||||
conventions used by
|
|
||||||
.Xr csh 1 .
|
|
||||||
This allows users to use the metacharacters
|
|
||||||
.Dq Li \&*?[]{}~ .
|
|
||||||
.Pp
|
|
||||||
.Nm Ftpd
|
|
||||||
authenticates users according to these rules.
|
|
||||||
.Pp
|
|
||||||
.Bl -enum -offset indent
|
|
||||||
.It
|
|
||||||
If Kerberos authentication is used, the user must pass valid tickets
|
|
||||||
and the principal must be allowed to login as the remote user.
|
|
||||||
.It
|
|
||||||
The login name must be in the password data base, and not have a null
|
|
||||||
password (if Kerberos is used the password field is not checked). In
|
|
||||||
this case a password must be provided by the client before any file
|
|
||||||
operations may be performed. If the user has an OTP key, the response
|
|
||||||
from a successful USER command will include an OTP challenge. The
|
|
||||||
client may choose to respond with a PASS command giving either a
|
|
||||||
standard password or an OTP one-time password. The server will
|
|
||||||
automatically determine which type of password it has been given and
|
|
||||||
attempt to authenticate accordingly. See
|
|
||||||
.Xr otp 1
|
|
||||||
for more information on OTP authentication.
|
|
||||||
.It
|
|
||||||
The login name must not appear in the file
|
|
||||||
.Pa /etc/ftpusers .
|
|
||||||
.It
|
|
||||||
The user must have a standard shell returned by
|
|
||||||
.Xr getusershell 3 .
|
|
||||||
.It
|
|
||||||
If the user name appears in the file
|
|
||||||
.Pa /etc/ftpchroot
|
|
||||||
the session's root will be changed to the user's login directory by
|
|
||||||
.Xr chroot 2
|
|
||||||
as for an
|
|
||||||
.Dq anonymous
|
|
||||||
or
|
|
||||||
.Dq ftp
|
|
||||||
account (see next item). However, the user must still supply a password.
|
|
||||||
This feature is intended as a compromise between a fully anonymous account
|
|
||||||
and a fully privileged account. The account should also be set up as for an
|
|
||||||
anonymous account.
|
|
||||||
.It
|
|
||||||
If the user name is
|
|
||||||
.Dq anonymous
|
|
||||||
or
|
|
||||||
.Dq ftp ,
|
|
||||||
an
|
|
||||||
anonymous ftp account must be present in the password
|
|
||||||
file (user
|
|
||||||
.Dq ftp ) .
|
|
||||||
In this case the user is allowed
|
|
||||||
to log in by specifying any password (by convention an email address for
|
|
||||||
the user should be used as the password).
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
In the last case,
|
|
||||||
.Nm ftpd
|
|
||||||
takes special measures to restrict the client's access privileges.
|
|
||||||
The server performs a
|
|
||||||
.Xr chroot 2
|
|
||||||
to the home directory of the
|
|
||||||
.Dq ftp
|
|
||||||
user.
|
|
||||||
In order that system security is not breached, it is recommended
|
|
||||||
that the
|
|
||||||
.Dq ftp
|
|
||||||
subtree be constructed with care, consider following these guidelines
|
|
||||||
for anonymous ftp.
|
|
||||||
.Pp
|
|
||||||
In general all files should be owned by
|
|
||||||
.Dq root ,
|
|
||||||
and have non-write permissions (644 or 755 depending on the kind of
|
|
||||||
file). No files should be owned or writable by
|
|
||||||
.Dq ftp
|
|
||||||
(possibly with exception for the
|
|
||||||
.Pa ~ftp/incoming ,
|
|
||||||
as specified below).
|
|
||||||
.Bl -tag -width "~ftp/pub" -offset indent
|
|
||||||
.It Pa ~ftp
|
|
||||||
The
|
|
||||||
.Dq ftp
|
|
||||||
homedirectory should be owned by root.
|
|
||||||
.It Pa ~ftp/bin
|
|
||||||
The directory for external programs (such as
|
|
||||||
.Xr ls 1 ) .
|
|
||||||
These programs must either be statically linked, or you must setup an
|
|
||||||
environment for dynamic linking when running chrooted.
|
|
||||||
These programs will be used if present:
|
|
||||||
.Bl -tag -width "locate" -offset indent
|
|
||||||
.It ls
|
|
||||||
Used when listing files.
|
|
||||||
.It compress
|
|
||||||
When retrieving a filename that ends in
|
|
||||||
.Pa .Z ,
|
|
||||||
and that file isn't present,
|
|
||||||
.Nm
|
|
||||||
will try to find the filename without
|
|
||||||
.Pa .Z
|
|
||||||
and compress it on the fly.
|
|
||||||
.It gzip
|
|
||||||
Same as compress, just with files ending in
|
|
||||||
.Pa .gz .
|
|
||||||
.It gtar
|
|
||||||
Enables retrieval of whole directories as files ending in
|
|
||||||
.Pa .tar .
|
|
||||||
Can also be combined with compression. You must use GNU Tar (or some
|
|
||||||
other that supports the
|
|
||||||
.Fl z
|
|
||||||
and
|
|
||||||
.Fl Z
|
|
||||||
flags).
|
|
||||||
.It locate
|
|
||||||
Will enable ``fast find'' with the
|
|
||||||
.Ic SITE FIND
|
|
||||||
command. You must also create a
|
|
||||||
.Pa locatedb
|
|
||||||
file in
|
|
||||||
.Pa ~ftp/etc .
|
|
||||||
.El
|
|
||||||
.It Pa ~ftp/etc
|
|
||||||
If you put copies of the
|
|
||||||
.Xr passwd 5
|
|
||||||
and
|
|
||||||
.Xr group 5
|
|
||||||
files here, ls will be able to produce owner names rather than
|
|
||||||
numbers. Remember to remove any passwords from these files.
|
|
||||||
.Pp
|
|
||||||
The file
|
|
||||||
.Pa motd ,
|
|
||||||
if present, will be printed after a successful login.
|
|
||||||
.It Pa ~ftp/dev
|
|
||||||
Put a copy of
|
|
||||||
.Xr /dev/null 7
|
|
||||||
here.
|
|
||||||
.It Pa ~ftp/pub
|
|
||||||
Traditional place to put whatever you want to make public.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
If you want guests to be able to upload files, create a
|
|
||||||
.Pa ~ftp/incoming
|
|
||||||
directory owned by
|
|
||||||
.Dq root ,
|
|
||||||
and group
|
|
||||||
.Dq ftp
|
|
||||||
with mode 730 (make sure
|
|
||||||
.Dq ftp
|
|
||||||
is member of group
|
|
||||||
.Dq ftp ) .
|
|
||||||
The following restrictions apply to anonymous users:
|
|
||||||
.Bl -bullet
|
|
||||||
.It
|
|
||||||
Directories created will have mode 700.
|
|
||||||
.It
|
|
||||||
Uploaded files will be created with an umask of 777, if not changed
|
|
||||||
with the
|
|
||||||
.Fl g
|
|
||||||
option.
|
|
||||||
.It
|
|
||||||
These command are not accessible:
|
|
||||||
.Ic DELE , RMD , RNTO , RNFR ,
|
|
||||||
.Ic SITE UMASK ,
|
|
||||||
and
|
|
||||||
.Ic SITE CHMOD .
|
|
||||||
.It
|
|
||||||
Filenames must start with an alpha-numeric character, and consist of
|
|
||||||
alpha-numeric characters or any of the following:
|
|
||||||
.Li \&+
|
|
||||||
(plus),
|
|
||||||
.Li \&-
|
|
||||||
(minus),
|
|
||||||
.Li \&=
|
|
||||||
(equal),
|
|
||||||
.Li \&_
|
|
||||||
(underscore),
|
|
||||||
.Li \&.
|
|
||||||
(period), and
|
|
||||||
.Li \&,
|
|
||||||
(comma).
|
|
||||||
.El
|
|
||||||
.Sh FILES
|
|
||||||
.Bl -tag -width /etc/ftpwelcome -compact
|
|
||||||
.It Pa /etc/ftpusers
|
|
||||||
Access list for users.
|
|
||||||
.It Pa /etc/ftpchroot
|
|
||||||
List of normal users who should be chroot'd.
|
|
||||||
.It Pa /etc/ftpwelcome
|
|
||||||
Welcome notice.
|
|
||||||
.It Pa /etc/motd
|
|
||||||
Welcome notice after login.
|
|
||||||
.It Pa /etc/nologin
|
|
||||||
Displayed and access refused.
|
|
||||||
.It Pa ~/.klogin
|
|
||||||
Login access for Kerberos.
|
|
||||||
.El
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr ftp 1 ,
|
|
||||||
.Xr otp 1 ,
|
|
||||||
.Xr getusershell 3 ,
|
|
||||||
.Xr ftpusers 5 ,
|
|
||||||
.Xr syslogd 8
|
|
||||||
.Sh STANDARDS
|
|
||||||
.Bl -tag -compact -width "RFC 1938"
|
|
||||||
.It Cm RFC 959
|
|
||||||
FTP PROTOCOL SPECIFICATION
|
|
||||||
.It Cm RFC 1938
|
|
||||||
OTP Specification
|
|
||||||
.It Cm RFC 2228
|
|
||||||
FTP Security Extensions.
|
|
||||||
.El
|
|
||||||
.Sh BUGS
|
|
||||||
The server must run as the super-user
|
|
||||||
to create sockets with privileged port numbers. It maintains
|
|
||||||
an effective user id of the logged in user, reverting to
|
|
||||||
the super-user only when binding addresses to sockets. The
|
|
||||||
possible security holes have been extensively
|
|
||||||
scrutinized, but are possibly incomplete.
|
|
||||||
.Sh HISTORY
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
command appeared in
|
|
||||||
.Bx 4.2 .
|
|
2376
appl/ftp/ftpd/ftpd.c
2376
appl/ftp/ftpd/ftpd.c
File diff suppressed because it is too large
Load Diff
@@ -1,171 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#ifndef __ftpd_locl_h__
|
|
||||||
#define __ftpd_locl_h__
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FTP server.
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_IOCCOM_H
|
|
||||||
#include <sys/ioccom.h>
|
|
||||||
#endif
|
|
||||||
#ifdef TIME_WITH_SYS_TIME
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
#elif defined(HAVE_SYS_TIME_H)
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_RESOURCE_H
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_WAIT_H
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
|
||||||
#include <netinet/in_systm.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IP_H
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_MMAN_H
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <arpa/ftp.h>
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ARPA_TELNET_H
|
|
||||||
#include <arpa/telnet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#ifdef HAVE_DIRENT_H
|
|
||||||
#include <dirent.h>
|
|
||||||
#endif
|
|
||||||
#include <errno.h>
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#endif
|
|
||||||
#include <glob.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#ifdef HAVE_PWD_H
|
|
||||||
#include <pwd.h>
|
|
||||||
#endif
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#ifdef HAVE_SYSLOG_H
|
|
||||||
#include <syslog.h>
|
|
||||||
#endif
|
|
||||||
#include <time.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GRP_H
|
|
||||||
#include <grp.h>
|
|
||||||
#endif
|
|
||||||
#include <fnmatch.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_BSD_BSD_H
|
|
||||||
#include <bsd/bsd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <err.h>
|
|
||||||
#include "roken.h"
|
|
||||||
|
|
||||||
#include "pathnames.h"
|
|
||||||
#include "extern.h"
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include "security.h"
|
|
||||||
|
|
||||||
#ifdef KRB5
|
|
||||||
#include <krb5.h>
|
|
||||||
#endif /* KRB5 */
|
|
||||||
|
|
||||||
#if defined(KRB5) && !defined(NO_AFS)
|
|
||||||
#include <kafs.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef OTP
|
|
||||||
#include <otp.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SOCKS
|
|
||||||
#include <socks.h>
|
|
||||||
extern int LIBPREFIX(fclose) (FILE *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* SunOS doesn't have any declaration of fclose */
|
|
||||||
|
|
||||||
int fclose(FILE *stream);
|
|
||||||
|
|
||||||
int yyparse(void);
|
|
||||||
|
|
||||||
#ifndef LOG_FTP
|
|
||||||
#define LOG_FTP LOG_DAEMON
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ftpd_locl_h__ */
|
|
@@ -1,37 +0,0 @@
|
|||||||
.\" $Id$
|
|
||||||
.\"
|
|
||||||
.Dd May 7, 1997
|
|
||||||
.Dt FTPUSERS 5
|
|
||||||
.Os KTH-KRB
|
|
||||||
.Sh NAME
|
|
||||||
.Pa /etc/ftpusers
|
|
||||||
.Nd FTP access list file
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
.Pa /etc/ftpusers
|
|
||||||
contains a list of users that should be allowed or denied FTP
|
|
||||||
access. Each line contains a user, optionally followed by
|
|
||||||
.Dq allow
|
|
||||||
(anything but
|
|
||||||
.Dq allow
|
|
||||||
is ignored). The semi-user
|
|
||||||
.Dq *
|
|
||||||
matches any user. Users that has an explicit
|
|
||||||
.Dq allow ,
|
|
||||||
or that does not match any line, are allowed access. Anyone else is
|
|
||||||
denied access.
|
|
||||||
.Pp
|
|
||||||
Note that this is compatible with the old format, where this file
|
|
||||||
contained a list of users that should be denied access.
|
|
||||||
.Sh EXAMPLES
|
|
||||||
This will deny anyone but
|
|
||||||
.Dq foo
|
|
||||||
and
|
|
||||||
.Dq bar
|
|
||||||
to use FTP:
|
|
||||||
.Bd -literal
|
|
||||||
foo allow
|
|
||||||
bar allow
|
|
||||||
*
|
|
||||||
.Ed
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr ftpd 8
|
|
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1998 - 2001 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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 "ftpd_locl.h"
|
|
||||||
#include <gssapi/gssapi.h>
|
|
||||||
|
|
||||||
/* XXX sync with gssapi.c */
|
|
||||||
struct gssapi_data {
|
|
||||||
gss_ctx_id_t context_hdl;
|
|
||||||
gss_name_t client_name;
|
|
||||||
gss_cred_id_t delegated_cred_handle;
|
|
||||||
void *mech_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
int gssapi_userok(void*, char*); /* to keep gcc happy */
|
|
||||||
int gssapi_session(void*, char*); /* to keep gcc happy */
|
|
||||||
|
|
||||||
int
|
|
||||||
gssapi_userok(void *app_data, char *username)
|
|
||||||
{
|
|
||||||
struct gssapi_data *data = app_data;
|
|
||||||
|
|
||||||
/* Yes, this logic really is inverted. */
|
|
||||||
return !gss_userok(data->client_name, username);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
gssapi_session(void *app_data, char *username)
|
|
||||||
{
|
|
||||||
struct gssapi_data *data = app_data;
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (data->delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
|
|
||||||
major = gss_store_cred(&minor, data->delegated_cred_handle,
|
|
||||||
GSS_C_INITIATE, GSS_C_NO_OID,
|
|
||||||
1, 1, NULL, NULL);
|
|
||||||
if (GSS_ERROR(major))
|
|
||||||
ret = 1;
|
|
||||||
#ifndef NO_AFS
|
|
||||||
afslog(NULL, 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
gss_release_cred(&minor, &data->delegated_cred_handle);
|
|
||||||
return ret;
|
|
||||||
}
|
|
@@ -1,145 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995 - 1999, 2003 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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 "ftpd_locl.h"
|
|
||||||
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
#if defined(KRB5)
|
|
||||||
|
|
||||||
int do_destroy_tickets = 1;
|
|
||||||
char *k5ccname;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef KRB5
|
|
||||||
|
|
||||||
static void
|
|
||||||
dest_cc(void)
|
|
||||||
{
|
|
||||||
krb5_context context;
|
|
||||||
krb5_error_code ret;
|
|
||||||
krb5_ccache id;
|
|
||||||
|
|
||||||
ret = krb5_init_context(&context);
|
|
||||||
if (ret == 0) {
|
|
||||||
if (k5ccname)
|
|
||||||
ret = krb5_cc_resolve(context, k5ccname, &id);
|
|
||||||
else
|
|
||||||
ret = krb5_cc_default (context, &id);
|
|
||||||
if (ret)
|
|
||||||
krb5_free_context(context);
|
|
||||||
}
|
|
||||||
if (ret == 0) {
|
|
||||||
krb5_cc_destroy(context, id);
|
|
||||||
krb5_free_context (context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KRB5)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only destroy if we created the tickets
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
cond_kdestroy(void)
|
|
||||||
{
|
|
||||||
if (do_destroy_tickets) {
|
|
||||||
#if KRB5
|
|
||||||
dest_cc();
|
|
||||||
#endif
|
|
||||||
do_destroy_tickets = 0;
|
|
||||||
}
|
|
||||||
#ifndef NO_AFS
|
|
||||||
afsunlog();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
kdestroy(void)
|
|
||||||
{
|
|
||||||
#if KRB5
|
|
||||||
dest_cc();
|
|
||||||
#endif
|
|
||||||
#ifndef NO_AFS
|
|
||||||
afsunlog();
|
|
||||||
#endif
|
|
||||||
reply(200, "Tickets destroyed");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NO_AFS
|
|
||||||
void
|
|
||||||
afslog(const char *cell, int quiet)
|
|
||||||
{
|
|
||||||
if(k_hasafs()) {
|
|
||||||
#ifdef KRB5
|
|
||||||
krb5_context context;
|
|
||||||
krb5_error_code ret;
|
|
||||||
krb5_ccache id;
|
|
||||||
|
|
||||||
ret = krb5_init_context(&context);
|
|
||||||
if (ret == 0) {
|
|
||||||
if (k5ccname)
|
|
||||||
ret = krb5_cc_resolve(context, k5ccname, &id);
|
|
||||||
else
|
|
||||||
ret = krb5_cc_default(context, &id);
|
|
||||||
if (ret)
|
|
||||||
krb5_free_context(context);
|
|
||||||
}
|
|
||||||
if (ret == 0) {
|
|
||||||
krb5_afslog(context, id, cell, 0);
|
|
||||||
krb5_cc_close (context, id);
|
|
||||||
krb5_free_context (context);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!quiet)
|
|
||||||
reply(200, "afslog done");
|
|
||||||
} else {
|
|
||||||
if (!quiet)
|
|
||||||
reply(200, "no AFS present");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
afsunlog(void)
|
|
||||||
{
|
|
||||||
if(k_hasafs())
|
|
||||||
k_unlog();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
int ftpd_afslog_placeholder;
|
|
||||||
#endif /* KRB5 */
|
|
@@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995 - 2005 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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 "ftpd_locl.h"
|
|
||||||
|
|
||||||
#ifdef KRB5
|
|
||||||
|
|
||||||
static int
|
|
||||||
print_cred(krb5_context context, krb5_creds *cred)
|
|
||||||
{
|
|
||||||
char t1[128], t2[128], *str;
|
|
||||||
krb5_error_code ret;
|
|
||||||
krb5_timestamp sec;
|
|
||||||
|
|
||||||
krb5_timeofday (context, &sec);
|
|
||||||
|
|
||||||
if(cred->times.starttime)
|
|
||||||
krb5_format_time(context, cred->times.starttime, t1, sizeof(t1), 1);
|
|
||||||
else
|
|
||||||
krb5_format_time(context, cred->times.authtime, t1, sizeof(t1), 1);
|
|
||||||
|
|
||||||
if(cred->times.endtime > sec)
|
|
||||||
krb5_format_time(context, cred->times.endtime, t2, sizeof(t2), 1);
|
|
||||||
else
|
|
||||||
strlcpy(t2, ">>>Expired<<<", sizeof(t2));
|
|
||||||
|
|
||||||
ret = krb5_unparse_name (context, cred->server, &str);
|
|
||||||
if (ret) {
|
|
||||||
lreply(500, "krb5_unparse_name: %d", ret);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lreply(200, "%-20s %-20s %s", t1, t2, str);
|
|
||||||
free(str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
print_tickets (krb5_context context,
|
|
||||||
krb5_ccache ccache,
|
|
||||||
krb5_principal principal)
|
|
||||||
{
|
|
||||||
krb5_error_code ret;
|
|
||||||
krb5_cc_cursor cursor;
|
|
||||||
krb5_creds cred;
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
ret = krb5_unparse_name (context, principal, &str);
|
|
||||||
if (ret) {
|
|
||||||
lreply(500, "krb5_unparse_name: %d", ret);
|
|
||||||
return 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
lreply(200, "%17s: %s:%s",
|
|
||||||
"Credentials cache",
|
|
||||||
krb5_cc_get_type(context, ccache),
|
|
||||||
krb5_cc_get_name(context, ccache));
|
|
||||||
lreply(200, "%17s: %s", "Principal", str);
|
|
||||||
free (str);
|
|
||||||
|
|
||||||
ret = krb5_cc_start_seq_get (context, ccache, &cursor);
|
|
||||||
if (ret) {
|
|
||||||
lreply(500, "krb5_cc_start_seq_get: %d", ret);
|
|
||||||
return 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
lreply(200, " Issued Expires Principal");
|
|
||||||
|
|
||||||
while ((ret = krb5_cc_next_cred (context,
|
|
||||||
ccache,
|
|
||||||
&cursor,
|
|
||||||
&cred)) == 0) {
|
|
||||||
if (print_cred(context, &cred))
|
|
||||||
return 500;
|
|
||||||
krb5_free_cred_contents (context, &cred);
|
|
||||||
}
|
|
||||||
if (ret != KRB5_CC_END) {
|
|
||||||
lreply(500, "krb5_cc_get_next: %d", ret);
|
|
||||||
return 500;
|
|
||||||
}
|
|
||||||
ret = krb5_cc_end_seq_get (context, ccache, &cursor);
|
|
||||||
if (ret) {
|
|
||||||
lreply(500, "krb5_cc_end_seq_get: %d", ret);
|
|
||||||
return 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
klist5(void)
|
|
||||||
{
|
|
||||||
krb5_error_code ret;
|
|
||||||
krb5_context context;
|
|
||||||
krb5_ccache ccache;
|
|
||||||
krb5_principal principal;
|
|
||||||
int exit_status = 200;
|
|
||||||
|
|
||||||
ret = krb5_init_context (&context);
|
|
||||||
if (ret) {
|
|
||||||
lreply(500, "krb5_init_context failed: %d", ret);
|
|
||||||
return 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k5ccname)
|
|
||||||
ret = krb5_cc_resolve(context, k5ccname, &ccache);
|
|
||||||
else
|
|
||||||
ret = krb5_cc_default (context, &ccache);
|
|
||||||
if (ret) {
|
|
||||||
lreply(500, "krb5_cc_default: %d", ret);
|
|
||||||
return 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = krb5_cc_get_principal (context, ccache, &principal);
|
|
||||||
if (ret) {
|
|
||||||
if(ret == ENOENT)
|
|
||||||
lreply(500, "No ticket file: %s",
|
|
||||||
krb5_cc_get_name(context, ccache));
|
|
||||||
else
|
|
||||||
lreply(500, "krb5_cc_get_principal: %d", ret);
|
|
||||||
|
|
||||||
return 500;
|
|
||||||
}
|
|
||||||
exit_status = print_tickets (context, ccache, principal);
|
|
||||||
|
|
||||||
ret = krb5_cc_close (context, ccache);
|
|
||||||
if (ret) {
|
|
||||||
lreply(500, "krb5_cc_close: %d", ret);
|
|
||||||
exit_status = 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
krb5_free_principal (context, principal);
|
|
||||||
krb5_free_context (context);
|
|
||||||
return exit_status;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
|
||||||
klist(void)
|
|
||||||
{
|
|
||||||
#if KRB5
|
|
||||||
int res = klist5();
|
|
||||||
reply(res, " ");
|
|
||||||
#else
|
|
||||||
reply(500, "Command not implemented.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
@@ -1,208 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
RCSID("$Id$");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#ifdef TIME_WITH_SYS_TIME
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
#elif defined(HAVE_SYS_TIME_H)
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UTMP_H
|
|
||||||
#include <utmp.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UTMPX_H
|
|
||||||
#include <utmpx.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ASL_H
|
|
||||||
#include <asl.h>
|
|
||||||
#endif
|
|
||||||
#include <roken.h>
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
#ifndef HAVE_UTMPX_H
|
|
||||||
#ifndef WTMP_FILE
|
|
||||||
#ifdef _PATH_WTMP
|
|
||||||
#define WTMP_FILE _PATH_WTMP
|
|
||||||
#else
|
|
||||||
#define WTMP_FILE "/var/adm/wtmp"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_ASL_H
|
|
||||||
|
|
||||||
#ifndef ASL_KEY_FACILITY
|
|
||||||
#define ASL_KEY_FACILITY "Facility"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
ftpd_logwtmp_asl(char *line, char *name, char *host)
|
|
||||||
{
|
|
||||||
static aslmsg m = NULL;
|
|
||||||
static int init = 0;
|
|
||||||
|
|
||||||
if (!init) {
|
|
||||||
init = 1;
|
|
||||||
m = asl_new(ASL_TYPE_MSG);
|
|
||||||
if (m == NULL)
|
|
||||||
return;
|
|
||||||
asl_set(m, ASL_KEY_FACILITY, "org.h5l.ftpd");
|
|
||||||
}
|
|
||||||
if (m)
|
|
||||||
asl_log(NULL, m, ASL_LEVEL_NOTICE,
|
|
||||||
"host %s/%s user %s%sconnected pid %d",
|
|
||||||
host, line, name, name[0] ? " " : "dis", (int)getpid());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_ASL_H
|
|
||||||
|
|
||||||
static void
|
|
||||||
ftpd_logwtmp_wtmp(char *line, char *name, char *host)
|
|
||||||
{
|
|
||||||
static int init = 0;
|
|
||||||
#ifdef WTMP_FILE
|
|
||||||
static int fd;
|
|
||||||
#endif
|
|
||||||
#ifdef WTMPX_FILE
|
|
||||||
static int fdx;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UTMP_H
|
|
||||||
struct utmp ut;
|
|
||||||
#endif
|
|
||||||
#if defined(WTMPX_FILE) || defined(HAVE_UTMPX_H)
|
|
||||||
struct utmpx utx;
|
|
||||||
#endif
|
|
||||||
#if defined(WTMP_FILE) || defined(WTMPX_FILE)
|
|
||||||
ssize_t ret;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UTMPX_H
|
|
||||||
memset(&utx, 0, sizeof(struct utmpx));
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UTMP_H
|
|
||||||
memset(&ut, 0, sizeof(struct utmp));
|
|
||||||
#ifdef HAVE_STRUCT_UTMP_UT_TYPE
|
|
||||||
if(name[0])
|
|
||||||
ut.ut_type = USER_PROCESS;
|
|
||||||
else
|
|
||||||
ut.ut_type = DEAD_PROCESS;
|
|
||||||
#endif
|
|
||||||
strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
|
||||||
strncpy(ut.ut_name, name, sizeof(ut.ut_name));
|
|
||||||
#ifdef HAVE_STRUCT_UTMP_UT_PID
|
|
||||||
ut.ut_pid = getpid();
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRUCT_UTMP_UT_HOST
|
|
||||||
strncpy(ut.ut_host, host, sizeof(ut.ut_host));
|
|
||||||
#endif
|
|
||||||
ut.ut_time = time(NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(WTMPX_FILE) || defined(HAVE_UTMPX_H)
|
|
||||||
strncpy(utx.ut_line, line, sizeof(utx.ut_line));
|
|
||||||
strncpy(utx.ut_user, name, sizeof(utx.ut_user));
|
|
||||||
strncpy(utx.ut_host, host, sizeof(utx.ut_host));
|
|
||||||
#ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN
|
|
||||||
utx.ut_syslen = strlen(host) + 1;
|
|
||||||
if (utx.ut_syslen > sizeof(utx.ut_host))
|
|
||||||
utx.ut_syslen = sizeof(utx.ut_host);
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
gettimeofday (&tv, 0);
|
|
||||||
utx.ut_tv.tv_sec = tv.tv_sec;
|
|
||||||
utx.ut_tv.tv_usec = tv.tv_usec;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(name[0])
|
|
||||||
utx.ut_type = USER_PROCESS;
|
|
||||||
else
|
|
||||||
utx.ut_type = DEAD_PROCESS;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UTMPX_H
|
|
||||||
pututxline(&utx);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!init){
|
|
||||||
#ifdef WTMP_FILE
|
|
||||||
fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0);
|
|
||||||
#endif
|
|
||||||
#ifdef WTMPX_FILE
|
|
||||||
fdx = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0);
|
|
||||||
#endif
|
|
||||||
init = 1;
|
|
||||||
}
|
|
||||||
#if defined(WTMP_FILE) || defined(WTMPX_FILE)
|
|
||||||
if(fd >= 0) {
|
|
||||||
#ifdef WTMP_FILE
|
|
||||||
ret = write(fd, &ut, sizeof(struct utmp)); /* XXX */
|
|
||||||
#endif
|
|
||||||
#ifdef WTMPX_FILE
|
|
||||||
ret = write(fdx, &utx, sizeof(struct utmpx));
|
|
||||||
#endif
|
|
||||||
if (ret == -1)
|
|
||||||
syslog(LOG_ERR, "ftpd_logwtmp_wtmp(): write(2) failed: %m");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !HAVE_ASL_H */
|
|
||||||
|
|
||||||
void
|
|
||||||
ftpd_logwtmp(char *line, char *name, char *host)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_ASL_H
|
|
||||||
ftpd_logwtmp_asl(line, name, host);
|
|
||||||
#else
|
|
||||||
ftpd_logwtmp_wtmp(line, name, host);
|
|
||||||
#endif
|
|
||||||
}
|
|
@@ -1,886 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
|
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
||||||
* 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 KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
|
|
||||||
|
|
||||||
#ifndef TEST
|
|
||||||
#include "ftpd_locl.h"
|
|
||||||
|
|
||||||
RCSID("$Id$");
|
|
||||||
|
|
||||||
#else
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#define sec_fprintf2 fprintf
|
|
||||||
#define sec_fflush fflush
|
|
||||||
static void list_files(FILE *out, const char **files, int n_files, int flags);
|
|
||||||
static int parse_flags(const char *options);
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i = 1;
|
|
||||||
int flags;
|
|
||||||
if(argc > 1 && argv[1][0] == '-') {
|
|
||||||
flags = parse_flags(argv[1]);
|
|
||||||
i = 2;
|
|
||||||
} else
|
|
||||||
flags = parse_flags(NULL);
|
|
||||||
|
|
||||||
list_files(stdout, (const char **)argv + i, argc - i, flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct fileinfo {
|
|
||||||
struct stat st;
|
|
||||||
int inode;
|
|
||||||
int bsize;
|
|
||||||
char mode[11];
|
|
||||||
int n_link;
|
|
||||||
char *user;
|
|
||||||
char *group;
|
|
||||||
char *size;
|
|
||||||
char *major;
|
|
||||||
char *minor;
|
|
||||||
char *date;
|
|
||||||
char *filename;
|
|
||||||
char *link;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_fileinfo(struct fileinfo *f)
|
|
||||||
{
|
|
||||||
free(f->user);
|
|
||||||
free(f->group);
|
|
||||||
free(f->size);
|
|
||||||
free(f->major);
|
|
||||||
free(f->minor);
|
|
||||||
free(f->date);
|
|
||||||
free(f->filename);
|
|
||||||
free(f->link);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LS_DIRS (1 << 0)
|
|
||||||
#define LS_IGNORE_DOT (1 << 1)
|
|
||||||
#define LS_SORT_MODE (3 << 2)
|
|
||||||
#define SORT_MODE(f) ((f) & LS_SORT_MODE)
|
|
||||||
#define LS_SORT_NAME (1 << 2)
|
|
||||||
#define LS_SORT_MTIME (2 << 2)
|
|
||||||
#define LS_SORT_SIZE (3 << 2)
|
|
||||||
#define LS_SORT_REVERSE (1 << 4)
|
|
||||||
|
|
||||||
#define LS_SIZE (1 << 5)
|
|
||||||
#define LS_INODE (1 << 6)
|
|
||||||
#define LS_TYPE (1 << 7)
|
|
||||||
#define LS_DISP_MODE (3 << 8)
|
|
||||||
#define DISP_MODE(f) ((f) & LS_DISP_MODE)
|
|
||||||
#define LS_DISP_LONG (1 << 8)
|
|
||||||
#define LS_DISP_COLUMN (2 << 8)
|
|
||||||
#define LS_DISP_CROSS (3 << 8)
|
|
||||||
#define LS_SHOW_ALL (1 << 10)
|
|
||||||
#define LS_RECURSIVE (1 << 11)
|
|
||||||
#define LS_EXTRA_BLANK (1 << 12)
|
|
||||||
#define LS_SHOW_DIRNAME (1 << 13)
|
|
||||||
#define LS_DIR_FLAG (1 << 14) /* these files come via list_dir */
|
|
||||||
|
|
||||||
#ifndef S_ISTXT
|
|
||||||
#define S_ISTXT S_ISVTX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(_S_IFMT) && defined(S_IFMT)
|
|
||||||
#define _S_IFMT S_IFMT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef S_ISSOCK
|
|
||||||
#define S_ISSOCK(mode) (((mode) & _S_IFMT) == S_IFSOCK)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef S_ISLNK
|
|
||||||
#define S_ISLNK(mode) (((mode) & _S_IFMT) == S_IFLNK)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
block_convert(size_t blocks)
|
|
||||||
{
|
|
||||||
#ifdef S_BLKSIZE
|
|
||||||
return blocks * S_BLKSIZE / 1024;
|
|
||||||
#else
|
|
||||||
return blocks * 512 / 1024;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
make_fileinfo(FILE *out, const char *filename, struct fileinfo *file, int flags)
|
|
||||||
{
|
|
||||||
char buf[128];
|
|
||||||
int file_type = 0;
|
|
||||||
struct stat *st = &file->st;
|
|
||||||
|
|
||||||
file->inode = st->st_ino;
|
|
||||||
file->bsize = block_convert(st->st_blocks);
|
|
||||||
|
|
||||||
if(S_ISDIR(st->st_mode)) {
|
|
||||||
file->mode[0] = 'd';
|
|
||||||
file_type = '/';
|
|
||||||
}
|
|
||||||
else if(S_ISCHR(st->st_mode))
|
|
||||||
file->mode[0] = 'c';
|
|
||||||
else if(S_ISBLK(st->st_mode))
|
|
||||||
file->mode[0] = 'b';
|
|
||||||
else if(S_ISREG(st->st_mode)) {
|
|
||||||
file->mode[0] = '-';
|
|
||||||
if(st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
|
|
||||||
file_type = '*';
|
|
||||||
}
|
|
||||||
else if(S_ISFIFO(st->st_mode)) {
|
|
||||||
file->mode[0] = 'p';
|
|
||||||
file_type = '|';
|
|
||||||
}
|
|
||||||
else if(S_ISLNK(st->st_mode)) {
|
|
||||||
file->mode[0] = 'l';
|
|
||||||
file_type = '@';
|
|
||||||
}
|
|
||||||
else if(S_ISSOCK(st->st_mode)) {
|
|
||||||
file->mode[0] = 's';
|
|
||||||
file_type = '=';
|
|
||||||
}
|
|
||||||
#ifdef S_ISWHT
|
|
||||||
else if(S_ISWHT(st->st_mode)) {
|
|
||||||
file->mode[0] = 'w';
|
|
||||||
file_type = '%';
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
file->mode[0] = '?';
|
|
||||||
{
|
|
||||||
char *x[] = { "---", "--x", "-w-", "-wx",
|
|
||||||
"r--", "r-x", "rw-", "rwx" };
|
|
||||||
strcpy(file->mode + 1, x[(st->st_mode & S_IRWXU) >> 6]);
|
|
||||||
strcpy(file->mode + 4, x[(st->st_mode & S_IRWXG) >> 3]);
|
|
||||||
strcpy(file->mode + 7, x[(st->st_mode & S_IRWXO) >> 0]);
|
|
||||||
if((st->st_mode & S_ISUID)) {
|
|
||||||
if((st->st_mode & S_IXUSR))
|
|
||||||
file->mode[3] = 's';
|
|
||||||
else
|
|
||||||
file->mode[3] = 'S';
|
|
||||||
}
|
|
||||||
if((st->st_mode & S_ISGID)) {
|
|
||||||
if((st->st_mode & S_IXGRP))
|
|
||||||
file->mode[6] = 's';
|
|
||||||
else
|
|
||||||
file->mode[6] = 'S';
|
|
||||||
}
|
|
||||||
if((st->st_mode & S_ISTXT)) {
|
|
||||||
if((st->st_mode & S_IXOTH))
|
|
||||||
file->mode[9] = 't';
|
|
||||||
else
|
|
||||||
file->mode[9] = 'T';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file->n_link = st->st_nlink;
|
|
||||||
{
|
|
||||||
struct passwd *pwd;
|
|
||||||
pwd = getpwuid(st->st_uid);
|
|
||||||
if(pwd == NULL) {
|
|
||||||
if (asprintf(&file->user, "%u", (unsigned)st->st_uid) == -1)
|
|
||||||
file->user = NULL;
|
|
||||||
} else
|
|
||||||
file->user = strdup(pwd->pw_name);
|
|
||||||
if (file->user == NULL) {
|
|
||||||
syslog(LOG_ERR, "out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
struct group *grp;
|
|
||||||
grp = getgrgid(st->st_gid);
|
|
||||||
if(grp == NULL) {
|
|
||||||
if (asprintf(&file->group, "%u", (unsigned)st->st_gid) == -1)
|
|
||||||
file->group = NULL;
|
|
||||||
} else
|
|
||||||
file->group = strdup(grp->gr_name);
|
|
||||||
if (file->group == NULL) {
|
|
||||||
syslog(LOG_ERR, "out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
|
|
||||||
#if defined(major) && defined(minor)
|
|
||||||
if (asprintf(&file->major, "%u", (unsigned)major(st->st_rdev)) == -1)
|
|
||||||
file->major = NULL;
|
|
||||||
if (asprintf(&file->minor, "%u", (unsigned)minor(st->st_rdev)) == -1)
|
|
||||||
file->minor = NULL;
|
|
||||||
#else
|
|
||||||
/* Don't want to use the DDI/DKI crap. */
|
|
||||||
if (asprintf(&file->major, "%u", (unsigned)st->st_rdev) == -1)
|
|
||||||
file->major = NULL;
|
|
||||||
if (asprintf(&file->minor, "%u", 0) == -1)
|
|
||||||
file->minor = NULL;
|
|
||||||
#endif
|
|
||||||
if (file->major == NULL || file->minor == NULL) {
|
|
||||||
syslog(LOG_ERR, "out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (asprintf(&file->size, "%lu", (unsigned long)st->st_size) == -1)
|
|
||||||
file->size = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
time_t t = time(NULL);
|
|
||||||
time_t mtime = st->st_mtime;
|
|
||||||
struct tm *tm = localtime(&mtime);
|
|
||||||
if((t - mtime > 6*30*24*60*60) ||
|
|
||||||
(mtime - t > 6*30*24*60*60))
|
|
||||||
strftime(buf, sizeof(buf), "%b %e %Y", tm);
|
|
||||||
else
|
|
||||||
strftime(buf, sizeof(buf), "%b %e %H:%M", tm);
|
|
||||||
file->date = strdup(buf);
|
|
||||||
if (file->date == NULL) {
|
|
||||||
syslog(LOG_ERR, "out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const char *p = strrchr(filename, '/');
|
|
||||||
if(p)
|
|
||||||
p++;
|
|
||||||
else
|
|
||||||
p = filename;
|
|
||||||
if((flags & LS_TYPE) && file_type != 0) {
|
|
||||||
if (asprintf(&file->filename, "%s%c", p, file_type) == -1)
|
|
||||||
file->filename = NULL;
|
|
||||||
} else
|
|
||||||
file->filename = strdup(p);
|
|
||||||
if (file->filename == NULL) {
|
|
||||||
syslog(LOG_ERR, "out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(S_ISLNK(st->st_mode)) {
|
|
||||||
int n;
|
|
||||||
n = readlink((char *)filename, buf, sizeof(buf) - 1);
|
|
||||||
if(n >= 0) {
|
|
||||||
buf[n] = '\0';
|
|
||||||
file->link = strdup(buf);
|
|
||||||
if (file->link == NULL) {
|
|
||||||
syslog(LOG_ERR, "out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
sec_fprintf2(out, "readlink(%s): %s", filename, strerror(errno));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_file(FILE *out,
|
|
||||||
int flags,
|
|
||||||
struct fileinfo *f,
|
|
||||||
int max_inode,
|
|
||||||
int max_bsize,
|
|
||||||
int max_n_link,
|
|
||||||
int max_user,
|
|
||||||
int max_group,
|
|
||||||
int max_size,
|
|
||||||
int max_major,
|
|
||||||
int max_minor,
|
|
||||||
int max_date)
|
|
||||||
{
|
|
||||||
if(f->filename == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(flags & LS_INODE) {
|
|
||||||
sec_fprintf2(out, "%*d", max_inode, f->inode);
|
|
||||||
sec_fprintf2(out, " ");
|
|
||||||
}
|
|
||||||
if(flags & LS_SIZE) {
|
|
||||||
sec_fprintf2(out, "%*d", max_bsize, f->bsize);
|
|
||||||
sec_fprintf2(out, " ");
|
|
||||||
}
|
|
||||||
sec_fprintf2(out, "%s", f->mode);
|
|
||||||
sec_fprintf2(out, " ");
|
|
||||||
sec_fprintf2(out, "%*d", max_n_link, f->n_link);
|
|
||||||
sec_fprintf2(out, " ");
|
|
||||||
sec_fprintf2(out, "%-*s", max_user, f->user);
|
|
||||||
sec_fprintf2(out, " ");
|
|
||||||
sec_fprintf2(out, "%-*s", max_group, f->group);
|
|
||||||
sec_fprintf2(out, " ");
|
|
||||||
if(f->major != NULL && f->minor != NULL)
|
|
||||||
sec_fprintf2(out, "%*s, %*s", max_major, f->major, max_minor, f->minor);
|
|
||||||
else
|
|
||||||
sec_fprintf2(out, "%*s", max_size, f->size);
|
|
||||||
sec_fprintf2(out, " ");
|
|
||||||
sec_fprintf2(out, "%*s", max_date, f->date);
|
|
||||||
sec_fprintf2(out, " ");
|
|
||||||
sec_fprintf2(out, "%s", f->filename);
|
|
||||||
if(f->link)
|
|
||||||
sec_fprintf2(out, " -> %s", f->link);
|
|
||||||
sec_fprintf2(out, "\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_filename(struct fileinfo *a, struct fileinfo *b)
|
|
||||||
{
|
|
||||||
if(a->filename == NULL)
|
|
||||||
return 1;
|
|
||||||
if(b->filename == NULL)
|
|
||||||
return -1;
|
|
||||||
return strcmp(a->filename, b->filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_mtime(struct fileinfo *a, struct fileinfo *b)
|
|
||||||
{
|
|
||||||
if(a->filename == NULL)
|
|
||||||
return 1;
|
|
||||||
if(b->filename == NULL)
|
|
||||||
return -1;
|
|
||||||
return b->st.st_mtime - a->st.st_mtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_size(struct fileinfo *a, struct fileinfo *b)
|
|
||||||
{
|
|
||||||
if(a->filename == NULL)
|
|
||||||
return 1;
|
|
||||||
if(b->filename == NULL)
|
|
||||||
return -1;
|
|
||||||
return b->st.st_size - a->st.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int list_dir(FILE*, const char*, int);
|
|
||||||
|
|
||||||
static int
|
|
||||||
find_log10(int num)
|
|
||||||
{
|
|
||||||
int i = 1;
|
|
||||||
while(num > 10) {
|
|
||||||
i++;
|
|
||||||
num /= 10;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Operate as lstat but fake up entries for AFS mount points so we don't
|
|
||||||
* have to fetch them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
lstat_file (const char *file, struct stat *sb)
|
|
||||||
{
|
|
||||||
#if defined(KRB5) && !defined(NO_AFS)
|
|
||||||
if (k_hasafs()
|
|
||||||
&& strcmp(file, ".")
|
|
||||||
&& strcmp(file, "..")
|
|
||||||
&& strcmp(file, "/"))
|
|
||||||
{
|
|
||||||
struct ViceIoctl a_params;
|
|
||||||
char *dir, *last;
|
|
||||||
char *path_bkp;
|
|
||||||
static ino_t ino_counter = 0, ino_last = 0;
|
|
||||||
int ret;
|
|
||||||
const int maxsize = 2048;
|
|
||||||
|
|
||||||
path_bkp = strdup (file);
|
|
||||||
if (path_bkp == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
a_params.out = malloc (maxsize);
|
|
||||||
if (a_params.out == NULL) {
|
|
||||||
free (path_bkp);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If path contains more than the filename alone - split it */
|
|
||||||
|
|
||||||
last = strrchr (path_bkp, '/');
|
|
||||||
if (last != NULL) {
|
|
||||||
if(last[1] == '\0')
|
|
||||||
/* if path ended in /, replace with `.' */
|
|
||||||
a_params.in = ".";
|
|
||||||
else
|
|
||||||
a_params.in = last + 1;
|
|
||||||
while(last > path_bkp && *--last == '/');
|
|
||||||
if(*last != '/' || last != path_bkp) {
|
|
||||||
*++last = '\0';
|
|
||||||
dir = path_bkp;
|
|
||||||
} else
|
|
||||||
/* we got to the start, so this must be the root dir */
|
|
||||||
dir = "/";
|
|
||||||
} else {
|
|
||||||
/* file is relative to cdir */
|
|
||||||
dir = ".";
|
|
||||||
a_params.in = path_bkp;
|
|
||||||
}
|
|
||||||
|
|
||||||
a_params.in_size = strlen (a_params.in) + 1;
|
|
||||||
a_params.out_size = maxsize;
|
|
||||||
|
|
||||||
ret = k_pioctl (dir, VIOC_AFS_STAT_MT_PT, &a_params, 0);
|
|
||||||
free (a_params.out);
|
|
||||||
if (ret < 0) {
|
|
||||||
free (path_bkp);
|
|
||||||
|
|
||||||
if (errno != EINVAL)
|
|
||||||
return ret;
|
|
||||||
else
|
|
||||||
/* if we get EINVAL this is probably not a mountpoint */
|
|
||||||
return lstat (file, sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* wow this was a mountpoint, lets cook the struct stat
|
|
||||||
* use . as a prototype
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = lstat (dir, sb);
|
|
||||||
free (path_bkp);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (ino_last == sb->st_ino)
|
|
||||||
ino_counter++;
|
|
||||||
else {
|
|
||||||
ino_last = sb->st_ino;
|
|
||||||
ino_counter = 0;
|
|
||||||
}
|
|
||||||
sb->st_ino += ino_counter;
|
|
||||||
sb->st_nlink = 3;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* KRB5 */
|
|
||||||
return lstat (file, sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define IS_DOT_DOTDOT(X) ((X)[0] == '.' && ((X)[1] == '\0' || \
|
|
||||||
((X)[1] == '.' && (X)[2] == '\0')))
|
|
||||||
|
|
||||||
static int
|
|
||||||
list_files(FILE *out, const char **files, int n_files, int flags)
|
|
||||||
{
|
|
||||||
struct fileinfo *fi;
|
|
||||||
int i;
|
|
||||||
int *dirs = NULL;
|
|
||||||
size_t total_blocks = 0;
|
|
||||||
int n_print = 0;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if(n_files == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(n_files > 1)
|
|
||||||
flags |= LS_SHOW_DIRNAME;
|
|
||||||
|
|
||||||
fi = calloc(n_files, sizeof(*fi));
|
|
||||||
if (fi == NULL) {
|
|
||||||
syslog(LOG_ERR, "out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for(i = 0; i < n_files; i++) {
|
|
||||||
if(lstat_file(files[i], &fi[i].st) < 0) {
|
|
||||||
sec_fprintf2(out, "%s: %s\r\n", files[i], strerror(errno));
|
|
||||||
fi[i].filename = NULL;
|
|
||||||
} else {
|
|
||||||
int include_in_list = 1;
|
|
||||||
total_blocks += block_convert(fi[i].st.st_blocks);
|
|
||||||
if(S_ISDIR(fi[i].st.st_mode)) {
|
|
||||||
if(dirs == NULL)
|
|
||||||
dirs = calloc(n_files, sizeof(*dirs));
|
|
||||||
if(dirs == NULL) {
|
|
||||||
syslog(LOG_ERR, "%s: %m", files[i]);
|
|
||||||
ret = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
dirs[i] = 1;
|
|
||||||
if((flags & LS_DIRS) == 0)
|
|
||||||
include_in_list = 0;
|
|
||||||
}
|
|
||||||
if(include_in_list) {
|
|
||||||
ret = make_fileinfo(out, files[i], &fi[i], flags);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
n_print++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch(SORT_MODE(flags)) {
|
|
||||||
case LS_SORT_NAME:
|
|
||||||
qsort(fi, n_files, sizeof(*fi),
|
|
||||||
(int (*)(const void*, const void*))compare_filename);
|
|
||||||
break;
|
|
||||||
case LS_SORT_MTIME:
|
|
||||||
qsort(fi, n_files, sizeof(*fi),
|
|
||||||
(int (*)(const void*, const void*))compare_mtime);
|
|
||||||
break;
|
|
||||||
case LS_SORT_SIZE:
|
|
||||||
qsort(fi, n_files, sizeof(*fi),
|
|
||||||
(int (*)(const void*, const void*))compare_size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(DISP_MODE(flags) == LS_DISP_LONG) {
|
|
||||||
int max_inode = 0;
|
|
||||||
int max_bsize = 0;
|
|
||||||
int max_n_link = 0;
|
|
||||||
int max_user = 0;
|
|
||||||
int max_group = 0;
|
|
||||||
int max_size = 0;
|
|
||||||
int max_major = 0;
|
|
||||||
int max_minor = 0;
|
|
||||||
int max_date = 0;
|
|
||||||
for(i = 0; i < n_files; i++) {
|
|
||||||
if(fi[i].filename == NULL)
|
|
||||||
continue;
|
|
||||||
if(fi[i].inode > max_inode)
|
|
||||||
max_inode = fi[i].inode;
|
|
||||||
if(fi[i].bsize > max_bsize)
|
|
||||||
max_bsize = fi[i].bsize;
|
|
||||||
if(fi[i].n_link > max_n_link)
|
|
||||||
max_n_link = fi[i].n_link;
|
|
||||||
if(strlen(fi[i].user) > max_user)
|
|
||||||
max_user = strlen(fi[i].user);
|
|
||||||
if(strlen(fi[i].group) > max_group)
|
|
||||||
max_group = strlen(fi[i].group);
|
|
||||||
if(fi[i].major != NULL && strlen(fi[i].major) > max_major)
|
|
||||||
max_major = strlen(fi[i].major);
|
|
||||||
if(fi[i].minor != NULL && strlen(fi[i].minor) > max_minor)
|
|
||||||
max_minor = strlen(fi[i].minor);
|
|
||||||
if(fi[i].size != NULL && strlen(fi[i].size) > max_size)
|
|
||||||
max_size = strlen(fi[i].size);
|
|
||||||
if(strlen(fi[i].date) > max_date)
|
|
||||||
max_date = strlen(fi[i].date);
|
|
||||||
}
|
|
||||||
if(max_size < max_major + max_minor + 2)
|
|
||||||
max_size = max_major + max_minor + 2;
|
|
||||||
else if(max_size - max_minor - 2 > max_major)
|
|
||||||
max_major = max_size - max_minor - 2;
|
|
||||||
max_inode = find_log10(max_inode);
|
|
||||||
max_bsize = find_log10(max_bsize);
|
|
||||||
max_n_link = find_log10(max_n_link);
|
|
||||||
|
|
||||||
if(n_print > 0)
|
|
||||||
sec_fprintf2(out, "total %lu\r\n", (unsigned long)total_blocks);
|
|
||||||
if(flags & LS_SORT_REVERSE)
|
|
||||||
for(i = n_files - 1; i >= 0; i--)
|
|
||||||
print_file(out,
|
|
||||||
flags,
|
|
||||||
&fi[i],
|
|
||||||
max_inode,
|
|
||||||
max_bsize,
|
|
||||||
max_n_link,
|
|
||||||
max_user,
|
|
||||||
max_group,
|
|
||||||
max_size,
|
|
||||||
max_major,
|
|
||||||
max_minor,
|
|
||||||
max_date);
|
|
||||||
else
|
|
||||||
for(i = 0; i < n_files; i++)
|
|
||||||
print_file(out,
|
|
||||||
flags,
|
|
||||||
&fi[i],
|
|
||||||
max_inode,
|
|
||||||
max_bsize,
|
|
||||||
max_n_link,
|
|
||||||
max_user,
|
|
||||||
max_group,
|
|
||||||
max_size,
|
|
||||||
max_major,
|
|
||||||
max_minor,
|
|
||||||
max_date);
|
|
||||||
} else if(DISP_MODE(flags) == LS_DISP_COLUMN ||
|
|
||||||
DISP_MODE(flags) == LS_DISP_CROSS) {
|
|
||||||
int max_len = 0;
|
|
||||||
int size_len = 0;
|
|
||||||
int num_files = n_files;
|
|
||||||
int columns;
|
|
||||||
int j;
|
|
||||||
for(i = 0; i < n_files; i++) {
|
|
||||||
if(fi[i].filename == NULL) {
|
|
||||||
num_files--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(strlen(fi[i].filename) > max_len)
|
|
||||||
max_len = strlen(fi[i].filename);
|
|
||||||
if(find_log10(fi[i].bsize) > size_len)
|
|
||||||
size_len = find_log10(fi[i].bsize);
|
|
||||||
}
|
|
||||||
if(num_files == 0)
|
|
||||||
goto next;
|
|
||||||
if(flags & LS_SIZE) {
|
|
||||||
columns = 80 / (size_len + 1 + max_len + 1);
|
|
||||||
max_len = 80 / columns - size_len - 1;
|
|
||||||
} else {
|
|
||||||
columns = 80 / (max_len + 1); /* get space between columns */
|
|
||||||
max_len = 80 / columns;
|
|
||||||
}
|
|
||||||
if(flags & LS_SIZE)
|
|
||||||
sec_fprintf2(out, "total %lu\r\n",
|
|
||||||
(unsigned long)total_blocks);
|
|
||||||
if(DISP_MODE(flags) == LS_DISP_CROSS) {
|
|
||||||
for(i = 0, j = 0; i < n_files; i++) {
|
|
||||||
if(fi[i].filename == NULL)
|
|
||||||
continue;
|
|
||||||
if(flags & LS_SIZE)
|
|
||||||
sec_fprintf2(out, "%*u %-*s", size_len, fi[i].bsize,
|
|
||||||
max_len, fi[i].filename);
|
|
||||||
else
|
|
||||||
sec_fprintf2(out, "%-*s", max_len, fi[i].filename);
|
|
||||||
j++;
|
|
||||||
if(j == columns) {
|
|
||||||
sec_fprintf2(out, "\r\n");
|
|
||||||
j = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(j > 0)
|
|
||||||
sec_fprintf2(out, "\r\n");
|
|
||||||
} else {
|
|
||||||
int skip = (num_files + columns - 1) / columns;
|
|
||||||
|
|
||||||
for(i = 0; i < skip; i++) {
|
|
||||||
for(j = i; j < n_files;) {
|
|
||||||
while(j < n_files && fi[j].filename == NULL)
|
|
||||||
j++;
|
|
||||||
if(flags & LS_SIZE)
|
|
||||||
sec_fprintf2(out, "%*u %-*s", size_len, fi[j].bsize,
|
|
||||||
max_len, fi[j].filename);
|
|
||||||
else
|
|
||||||
sec_fprintf2(out, "%-*s", max_len, fi[j].filename);
|
|
||||||
j += skip;
|
|
||||||
}
|
|
||||||
sec_fprintf2(out, "\r\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(i = 0; i < n_files; i++) {
|
|
||||||
if(fi[i].filename == NULL)
|
|
||||||
continue;
|
|
||||||
sec_fprintf2(out, "%s\r\n", fi[i].filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next:
|
|
||||||
if(((flags & LS_DIRS) == 0 || (flags & LS_RECURSIVE)) && dirs != NULL) {
|
|
||||||
for(i = 0; i < n_files; i++) {
|
|
||||||
if(dirs[i]) {
|
|
||||||
const char *p = strrchr(files[i], '/');
|
|
||||||
if(p == NULL)
|
|
||||||
p = files[i];
|
|
||||||
else
|
|
||||||
p++;
|
|
||||||
if(!(flags & LS_DIR_FLAG) || !IS_DOT_DOTDOT(p)) {
|
|
||||||
if((flags & LS_SHOW_DIRNAME)) {
|
|
||||||
if ((flags & LS_EXTRA_BLANK))
|
|
||||||
sec_fprintf2(out, "\r\n");
|
|
||||||
sec_fprintf2(out, "%s:\r\n", files[i]);
|
|
||||||
}
|
|
||||||
list_dir(out, files[i], flags | LS_DIRS | LS_EXTRA_BLANK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
for(i = 0; i < n_files; i++)
|
|
||||||
free_fileinfo(&fi[i]);
|
|
||||||
free(fi);
|
|
||||||
if(dirs != NULL)
|
|
||||||
free(dirs);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_files (char **files, int n)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < n; ++i)
|
|
||||||
free (files[i]);
|
|
||||||
free (files);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hide_file(const char *filename, int flags)
|
|
||||||
{
|
|
||||||
if(filename[0] != '.')
|
|
||||||
return 0;
|
|
||||||
if((flags & LS_IGNORE_DOT))
|
|
||||||
return 1;
|
|
||||||
if(filename[1] == '\0' || (filename[1] == '.' && filename[2] == '\0')) {
|
|
||||||
if((flags & LS_SHOW_ALL))
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
list_dir(FILE *out, const char *directory, int flags)
|
|
||||||
{
|
|
||||||
DIR *d = opendir(directory);
|
|
||||||
struct dirent *ent;
|
|
||||||
char **files = NULL;
|
|
||||||
int n_files = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if(d == NULL) {
|
|
||||||
syslog(LOG_ERR, "%s: %m", directory);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
while((ent = readdir(d)) != NULL) {
|
|
||||||
void *tmp;
|
|
||||||
|
|
||||||
if(hide_file(ent->d_name, flags))
|
|
||||||
continue;
|
|
||||||
tmp = realloc(files, (n_files + 1) * sizeof(*files));
|
|
||||||
if (tmp == NULL) {
|
|
||||||
syslog(LOG_ERR, "%s: out of memory", directory);
|
|
||||||
free_files (files, n_files);
|
|
||||||
closedir (d);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
files = tmp;
|
|
||||||
ret = asprintf(&files[n_files], "%s/%s", directory, ent->d_name);
|
|
||||||
if (ret == -1) {
|
|
||||||
syslog(LOG_ERR, "%s: out of memory", directory);
|
|
||||||
free_files (files, n_files);
|
|
||||||
closedir (d);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
++n_files;
|
|
||||||
}
|
|
||||||
closedir(d);
|
|
||||||
return list_files(out, (const char**)files, n_files, flags | LS_DIR_FLAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
parse_flags(const char *options)
|
|
||||||
{
|
|
||||||
#ifdef TEST
|
|
||||||
int flags = LS_SORT_NAME | LS_IGNORE_DOT | LS_DISP_COLUMN;
|
|
||||||
#else
|
|
||||||
int flags = LS_SORT_NAME | LS_IGNORE_DOT | LS_DISP_LONG;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *p;
|
|
||||||
if(options == NULL || *options != '-')
|
|
||||||
return flags;
|
|
||||||
for(p = options + 1; *p; p++) {
|
|
||||||
switch(*p) {
|
|
||||||
case '1':
|
|
||||||
flags = (flags & ~LS_DISP_MODE);
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
flags |= LS_SHOW_ALL;
|
|
||||||
/*FALLTHROUGH*/
|
|
||||||
case 'A':
|
|
||||||
flags &= ~LS_IGNORE_DOT;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
flags = (flags & ~LS_DISP_MODE) | LS_DISP_COLUMN;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
flags |= LS_DIRS;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
flags = (flags & ~LS_SORT_MODE);
|
|
||||||
break;
|
|
||||||
case 'F':
|
|
||||||
flags |= LS_TYPE;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
flags |= LS_INODE;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
flags = (flags & ~LS_DISP_MODE) | LS_DISP_LONG;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
flags |= LS_SORT_REVERSE;
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
flags |= LS_RECURSIVE;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
flags |= LS_SIZE;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
flags = (flags & ~LS_SORT_MODE) | LS_SORT_SIZE;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
flags = (flags & ~LS_SORT_MODE) | LS_SORT_MTIME;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
flags = (flags & ~LS_DISP_MODE) | LS_DISP_CROSS;
|
|
||||||
break;
|
|
||||||
/* these are a bunch of unimplemented flags from BSD ls */
|
|
||||||
case 'k': /* display sizes in kB */
|
|
||||||
case 'c': /* last change time */
|
|
||||||
case 'L': /* list symlink target */
|
|
||||||
case 'm': /* stream output */
|
|
||||||
case 'o': /* BSD file flags */
|
|
||||||
case 'p': /* display / after directories */
|
|
||||||
case 'q': /* print non-graphic characters */
|
|
||||||
case 'u': /* use last access time */
|
|
||||||
case 'T': /* display complete time */
|
|
||||||
case 'W': /* include whiteouts */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
builtin_ls(FILE *out, const char *file)
|
|
||||||
{
|
|
||||||
int flags;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if(*file == '-') {
|
|
||||||
flags = parse_flags(file);
|
|
||||||
file = ".";
|
|
||||||
} else
|
|
||||||
flags = parse_flags("");
|
|
||||||
|
|
||||||
ret = list_files(out, &file, 1, flags);
|
|
||||||
sec_fflush(out);
|
|
||||||
return ret;
|
|
||||||
}
|
|
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1989, 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. 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.
|
|
||||||
*
|
|
||||||
* @(#)pathnames.h 8.1 (Berkeley) 6/4/93
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_PATHS_H
|
|
||||||
#include <paths.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _PATH_DEVNULL
|
|
||||||
#define _PATH_DEVNULL "/dev/null"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _PATH_NOLOGIN
|
|
||||||
#define _PATH_NOLOGIN "/etc/nologin"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _PATH_BSHELL
|
|
||||||
#define _PATH_BSHELL "/bin/sh"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _PATH_FTPUSERS
|
|
||||||
#define _PATH_FTPUSERS SYSCONFDIR "/ftpusers"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _PATH_FTPCHROOT SYSCONFDIR "/ftpchroot"
|
|
||||||
#define _PATH_FTPWELCOME SYSCONFDIR "/ftpwelcome"
|
|
||||||
#define _PATH_FTPLOGINMESG SYSCONFDIR "/motd"
|
|
||||||
|
|
||||||
#ifndef _PATH_ISSUE
|
|
||||||
#define _PATH_ISSUE SYSCONFDIR "/issue"
|
|
||||||
#endif
|
|
||||||
#define _PATH_ISSUE_NET SYSCONFDIR "/issue.net"
|
|
@@ -1,236 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1988, 1993, 1994
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software written by Ken Arnold and
|
|
||||||
* published in UNIX Review, Vol. 6, No. 8.
|
|
||||||
*
|
|
||||||
* 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. 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
RCSID("$Id$");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#ifdef TIME_WITH_SYS_TIME
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
#elif defined(HAVE_SYS_TIME_H)
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_RESOURCE_H
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <glob.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <roken.h>
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Special version of popen which avoids call to shell. This ensures
|
|
||||||
* no one may create a pipe to a hidden program as a side effect of a
|
|
||||||
* list or dir command.
|
|
||||||
*/
|
|
||||||
static int *pids;
|
|
||||||
static int fds;
|
|
||||||
|
|
||||||
/* return path prepended with ~ftp if that file exists, otherwise
|
|
||||||
* return path unchanged
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char *
|
|
||||||
ftp_rooted(const char *path)
|
|
||||||
{
|
|
||||||
static char home[MaxPathLen] = "";
|
|
||||||
static char newpath[MaxPathLen];
|
|
||||||
struct passwd *pwd;
|
|
||||||
|
|
||||||
if(!home[0])
|
|
||||||
if((pwd = k_getpwnam("ftp")))
|
|
||||||
strlcpy(home, pwd->pw_dir, sizeof(home));
|
|
||||||
snprintf(newpath, sizeof(newpath), "%s/%s", home, path);
|
|
||||||
if(access(newpath, X_OK))
|
|
||||||
strlcpy(newpath, path, sizeof(newpath));
|
|
||||||
return newpath;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define MAXARGS 100
|
|
||||||
#define MAXGLOBS 1000
|
|
||||||
|
|
||||||
FILE *
|
|
||||||
ftpd_popen(char *program, char *type, int do_stderr, int no_glob)
|
|
||||||
{
|
|
||||||
char *cp;
|
|
||||||
FILE *iop;
|
|
||||||
int argc, gargc, pdes[2], pid;
|
|
||||||
char **pop, *argv[MAXARGS], *gargv[MAXGLOBS];
|
|
||||||
char *foo;
|
|
||||||
|
|
||||||
if (strcmp(type, "r") && strcmp(type, "w"))
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
if (!pids) {
|
|
||||||
|
|
||||||
/* This function is ugly and should be rewritten, in
|
|
||||||
* modern unices there is no such thing as a maximum
|
|
||||||
* filedescriptor.
|
|
||||||
*/
|
|
||||||
|
|
||||||
fds = getdtablesize();
|
|
||||||
pids = (int*)calloc(fds, sizeof(int));
|
|
||||||
if(!pids)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pipe(pdes) < 0)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
/* break up string into pieces */
|
|
||||||
foo = NULL;
|
|
||||||
for (argc = 0, cp = program; argc < MAXARGS - 1; cp = NULL) {
|
|
||||||
if (!(argv[argc++] = strtok_r(cp, " \t\n", &foo)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
argv[MAXARGS - 1] = NULL;
|
|
||||||
|
|
||||||
gargv[0] = (char*)ftp_rooted(argv[0]);
|
|
||||||
/* glob each piece */
|
|
||||||
for (gargc = argc = 1; argv[argc] && gargc < MAXGLOBS - 1; argc++) {
|
|
||||||
glob_t gl;
|
|
||||||
int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE
|
|
||||||
|
|
|
||||||
#ifdef GLOB_MAXPATH
|
|
||||||
GLOB_MAXPATH
|
|
||||||
#else
|
|
||||||
GLOB_LIMIT
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
memset(&gl, 0, sizeof(gl));
|
|
||||||
if (no_glob ||
|
|
||||||
glob(argv[argc], flags, NULL, &gl) ||
|
|
||||||
gl.gl_pathc == 0)
|
|
||||||
gargv[gargc++] = strdup(argv[argc]);
|
|
||||||
else
|
|
||||||
for (pop = gl.gl_pathv;
|
|
||||||
*pop && gargc < MAXGLOBS - 1;
|
|
||||||
pop++)
|
|
||||||
gargv[gargc++] = strdup(*pop);
|
|
||||||
globfree(&gl);
|
|
||||||
}
|
|
||||||
gargv[gargc] = NULL;
|
|
||||||
|
|
||||||
iop = NULL;
|
|
||||||
switch(pid = fork()) {
|
|
||||||
case -1: /* error */
|
|
||||||
close(pdes[0]);
|
|
||||||
close(pdes[1]);
|
|
||||||
goto pfree;
|
|
||||||
/* NOTREACHED */
|
|
||||||
case 0: /* child */
|
|
||||||
if (*type == 'r') {
|
|
||||||
if (pdes[1] != STDOUT_FILENO) {
|
|
||||||
dup2(pdes[1], STDOUT_FILENO);
|
|
||||||
close(pdes[1]);
|
|
||||||
}
|
|
||||||
if(do_stderr)
|
|
||||||
dup2(STDOUT_FILENO, STDERR_FILENO);
|
|
||||||
close(pdes[0]);
|
|
||||||
} else {
|
|
||||||
if (pdes[0] != STDIN_FILENO) {
|
|
||||||
dup2(pdes[0], STDIN_FILENO);
|
|
||||||
close(pdes[0]);
|
|
||||||
}
|
|
||||||
close(pdes[1]);
|
|
||||||
}
|
|
||||||
execv(gargv[0], gargv);
|
|
||||||
gargv[0] = argv[0];
|
|
||||||
execv(gargv[0], gargv);
|
|
||||||
_exit(1);
|
|
||||||
}
|
|
||||||
/* parent; assume fdopen can't fail... */
|
|
||||||
if (*type == 'r') {
|
|
||||||
iop = fdopen(pdes[0], type);
|
|
||||||
close(pdes[1]);
|
|
||||||
} else {
|
|
||||||
iop = fdopen(pdes[1], type);
|
|
||||||
close(pdes[0]);
|
|
||||||
}
|
|
||||||
pids[fileno(iop)] = pid;
|
|
||||||
|
|
||||||
pfree:
|
|
||||||
for (argc = 1; gargv[argc] != NULL; argc++)
|
|
||||||
free(gargv[argc]);
|
|
||||||
|
|
||||||
|
|
||||||
return (iop);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ftpd_pclose(FILE *iop)
|
|
||||||
{
|
|
||||||
int fdes, status;
|
|
||||||
pid_t pid;
|
|
||||||
sigset_t sigset, osigset;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pclose returns -1 if stream is not associated with a
|
|
||||||
* `popened' command, or, if already `pclosed'.
|
|
||||||
*/
|
|
||||||
if (pids == 0 || pids[fdes = fileno(iop)] == 0)
|
|
||||||
return (-1);
|
|
||||||
fclose(iop);
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGINT);
|
|
||||||
sigaddset(&sigset, SIGQUIT);
|
|
||||||
sigaddset(&sigset, SIGHUP);
|
|
||||||
sigprocmask(SIG_BLOCK, &sigset, &osigset);
|
|
||||||
while ((pid = waitpid(pids[fdes], &status, 0)) < 0 && errno == EINTR)
|
|
||||||
continue;
|
|
||||||
sigprocmask(SIG_SETMASK, &osigset, NULL);
|
|
||||||
pids[fdes] = 0;
|
|
||||||
if (pid < 0)
|
|
||||||
return (pid);
|
|
||||||
if (WIFEXITED(status))
|
|
||||||
return (WEXITSTATUS(status));
|
|
||||||
return (1);
|
|
||||||
}
|
|
@@ -337,7 +337,6 @@ AC_HEADER_STDC
|
|||||||
AC_CHECK_HEADERS([\
|
AC_CHECK_HEADERS([\
|
||||||
CommonCrypto/CommonDigest.h \
|
CommonCrypto/CommonDigest.h \
|
||||||
CommonCrypto/CommonCryptor.h \
|
CommonCrypto/CommonCryptor.h \
|
||||||
arpa/ftp.h \
|
|
||||||
arpa/telnet.h \
|
arpa/telnet.h \
|
||||||
bind/bitypes.h \
|
bind/bitypes.h \
|
||||||
bsdsetjmp.h \
|
bsdsetjmp.h \
|
||||||
@@ -655,10 +654,6 @@ AC_CONFIG_FILES(Makefile \
|
|||||||
appl/Makefile \
|
appl/Makefile \
|
||||||
appl/afsutil/Makefile \
|
appl/afsutil/Makefile \
|
||||||
appl/dbutils/Makefile \
|
appl/dbutils/Makefile \
|
||||||
appl/ftp/Makefile \
|
|
||||||
appl/ftp/common/Makefile \
|
|
||||||
appl/ftp/ftp/Makefile \
|
|
||||||
appl/ftp/ftpd/Makefile \
|
|
||||||
appl/gssmask/Makefile \
|
appl/gssmask/Makefile \
|
||||||
appl/login/Makefile \
|
appl/login/Makefile \
|
||||||
appl/otp/Makefile \
|
appl/otp/Makefile \
|
||||||
|
@@ -133,9 +133,6 @@ static const char *const rcsid[] = { (const char *)rcsid, "@(#)" msg }
|
|||||||
/* Define to 1 if you have the `arc4random' function. */
|
/* Define to 1 if you have the `arc4random' function. */
|
||||||
/* #undef HAVE_ARC4RANDOM */
|
/* #undef HAVE_ARC4RANDOM */
|
||||||
|
|
||||||
/* Define to 1 if you have the <arpa/ftp.h> header file. */
|
|
||||||
/* #undef HAVE_ARPA_FTP_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
/* #undef HAVE_ARPA_INET_H */
|
/* #undef HAVE_ARPA_INET_H */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user