Goodbye FTP
This commit is contained in:
@@ -14,7 +14,6 @@ endif
|
||||
SUBDIRS = \
|
||||
$(dir_afsutil) \
|
||||
dbutils \
|
||||
ftp \
|
||||
login \
|
||||
$(dir_otp) \
|
||||
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);
|
||||
}
|
Reference in New Issue
Block a user