Hi,
I am attempting to setup and sftp server on a windows XP pro machine. I have
the latest cygwin and openssh files from cygwin.com. I downloaded the scponly
source files and am now attempting to compile them. I get the following error
message:
$ make
gcc -g -O2 -I. -I. -DHAVE_CONFIG_H
-DDEBUGFILE='"/usr/local/etc/scponly/debuglev
el"' -o scponly.o -c scponly.c
gcc -g -O2 -I. -I. -DHAVE_CONFIG_H
-DDEBUGFILE='"/usr/local/etc/scponly/debuglev
el"' -o helper.o -c helper.c
helper.c:12:36: libgen.h: No such file or directory
helper.c: In function `substitute_known_path':
helper.c:174: warning: passing arg 1 of `strdup' makes pointer from integer
with
out a cast
helper.c:179: warning: passing arg 1 of `strcmp' makes pointer from integer
with
out a cast
make: *** [helper.o] Error 1
I have only found a single post
http://www.cygwin.com/ml/cygwin/2004-11/msg01184.html
that says "scponly compiles easily under the new cygwin releases with a few
modifications to the makefile," but it doesn't say what those are. I have
included the configure utility screen output, the makefile, and helper.c file.
I would greatly appreciate any help on this.
Thanks,
Chad
# Autoconfed stuff
srcdir = .
prefix := /usr/local
exec_prefix := ${prefix}
bindir = ${exec_prefix}/bin
sbindir = ${exec_prefix}/sbin
mandir = ${prefix}/man
CFLAGS = -g -O2 -I$(srcdir) -I.
INSTALL = /usr/bin/install -c
CC = gcc
CHROOTED_NAME = scponlyc
CONFDIR := ${prefix}/etc/scponly
DEBUGFILE := ${CONFDIR}/debuglevel
DEFS := -DHAVE_CONFIG_H -DDEBUGFILE='"${DEBUGFILE}"'
LN_S = ln -s
all: scponly groups
clean:
rm -f *.o scponly *~ debuglevel ${CHROOTED_NAME} groups
love: clean all
scponly: scponly.o helper.o
${CC} ${CFLAGS} ${DEFS} -o $@ scponly.o helper.o
groups: groups.c
${CC} ${CFLAGS} ${DEFS} -o $@ $<
scponly.o: scponly.c config.h scponly.h
${CC} ${CFLAGS} ${DEFS} -o $@ -c $<
helper.o: helper.c config.h scponly.h
${CC} ${CFLAGS} ${DEFS} -o $@ -c $<
install: scponly debuglevel scponly.8
${INSTALL} -d ${bindir}
${INSTALL} -d ${mandir}/man8
${INSTALL} -d ${CONFDIR}
${INSTALL} -o 0 -g 0 scponly ${bindir}/scponly
${INSTALL} -o 0 -g 0 -m 0644 scponly.8 ${mandir}/man8/scponly.8
${INSTALL} -o 0 -g 0 -m 0644 debuglevel ${DEBUGFILE}
if test "x${CHROOTED_NAME}" != "x"; then \
${INSTALL} -d ${sbindir}; \
rm -f ${sbindir}/${CHROOTED_NAME}; \
cp scponly ${CHROOTED_NAME}; \
${INSTALL} -o 0 -g 0 -m 4755 ${CHROOTED_NAME}
${sbindir}/${CHROOTED_NAME}; \
fi
debuglevel:
echo "0" > $@
jail: install
chmod u+x ./setup_chroot.sh
./setup_chroot.sh
distclean: clean
rm -fr autom4te.cache
rm -f config.h config.log config.status Makefile setup_chroot.sh
maintainer-clean: distclean
rm -f configure
$ ./configure --enable-chrooted-binary
checking build system type... i686-pc-cygwin
checking host system type... i686-pc-cygwin
checking for gcc... gcc
checking for C compiler default output... a.exe
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... .exe
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking whether ln -s works... yes
checking for cut... /usr/bin/cut
checking for grep... /usr/bin/grep
checking for sort... /usr/bin/sort
checking for ldd... no
checking for useradd... no
checking for chown... /usr/bin/chown
checking for chmod... /usr/bin/chmod
checking for dirname... /usr/bin/dirname
checking for id... /usr/bin/id
checking for pw... no
checking for rm... /usr/bin/rm
checking for pwd_mkdb... no
configure: enabling core WinSCP and Vanilla SCP binaries...
checking for sftp-server... /usr/sbin/sftp-server
checking for ls... /bin/ls
checking for scp... /bin/scp
checking for rm... /bin/rm
checking for ln... /bin/ln
checking for mv... /bin/mv
checking for chmod... /bin/chmod
checking for chown... /bin/chown
checking for chgrp... /bin/chgrp
checking for mkdir... /bin/mkdir
checking for rmdir... /bin/rmdir
configure: enabling WinSCP compatability...
checking for pwd... /bin/pwd
checking for groups... /bin/groups
checking for id... /bin/id
checking for echo... /bin/echo
configure: enabling SFTP compatability...
checking for sftp-server... (cached) /usr/sbin/sftp-server
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking syslog.h usability... yes
checking syslog.h presence... yes
checking for syslog.h... yes
checking for unistd.h... (cached) yes
checking wordexp.h usability... no
checking wordexp.h presence... no
checking for wordexp.h... no
checking glob.h usability... yes
checking glob.h presence... yes
checking for glob.h... yes
checking libgen.h usability... no
checking libgen.h presence... no
checking for libgen.h... no
checking for gcc option to accept ANSI C... none needed
checking for an ANSI C-conforming const... yes
checking for inline... inline
checking for working alloca.h... yes
checking for alloca... yes
checking for malloc... yes
checking for atexit... yes
checking for bzero... yes
checking for strchr... yes
checking for strerror... yes
checking for glob... yes
checking for wordexp... no
checking for strspn... yes
checking for basename... no
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
/*
* helper functions for scponly
*/
#include <stdio.h> // io
#include <string.h> // for str*
#include <sys/types.h> // for stat, getpwuid
#include <sys/stat.h> // for stat
#include <unistd.h> // for exit, access, getpwuid, execve
#include <errno.h> // for debugging
#include <pwd.h> // to get username for config parsing
#include <time.h> // time
#include <libgen.h> // basename
#include <stdlib.h> // realloc
#include <syslog.h>
#include "scponly.h"
#include "config.h"
#ifdef HAVE_GLOB
#include <glob.h> // for glob()
#else
#ifdef HAVE_WORDEXP
#include <wordexp.h> // for wordexp()
#endif
#endif
#define MAX(x,y) ( ( x > y ) ? x : y )
extern int debuglevel;
extern char username[MAX_USERNAME];
extern char homedir[FILENAME_MAX];
extern cmd_t commands[];
extern cmd_arg_t dangerous_args[];
#ifdef UNIX_COMPAT
char* solaris_needs_strsep(char** str, char* delims)
{
char* tmpstr;
if (*str==NULL) {
return NULL;
}
tmpstr=*str;
while (**str!='\0') {
if (strchr(delims,**str)!=NULL) {
**str='\0';
(*str)++;
return tmpstr;
}
(*str)++;
}
*str=NULL;
return tmpstr;
}
#endif
void discard_vector(char **av)
{
char **tmpptr=av;
while (*tmpptr!=NULL)
free(*tmpptr++);
free(av);
}
char *flatten_vector(char **av)
{
char **tmpptr=av;
char *temp=NULL;
char *crptr=NULL;
char *outbuf=NULL;
int len=0,newlen=0;
while (*tmpptr!=NULL)
{
if (NULL != (crptr=strchr(*tmpptr, '\n')))
{
*crptr='\0';
}
if (outbuf!=NULL)
{
len = strlen(outbuf);
newlen=len + strlen(*tmpptr)+1;
}
else
{
len = 0;
newlen=strlen(*tmpptr);
}
if (NULL == (temp = realloc (outbuf, newlen + 1)))
{
perror("realloc");
if (outbuf)
free(outbuf);
exit(EXIT_FAILURE);
}
outbuf=temp;
temp=NULL;
if (len)
{
outbuf[len]=' ';
strcpy(&outbuf[len+1],*tmpptr);
}
else
strcpy(outbuf,*tmpptr);
*tmpptr++;
}
return (outbuf);
}
/*
* since some programs support invoking other programs for their encryption
* (dropings to replace ssh), we must refuse to support these arguments
*
* RETURN: 1 means reject this command, 0 means it is safe.
*/
int check_dangerous_args(char **av)
{
cmd_arg_t *cmdarg=dangerous_args;
char **tmpptr=av;
while (cmdarg != NULL)
{
if (cmdarg->name == NULL)
return 0;
if (exact_match(cmdarg->name,av[0]))
{
/*
* the command matches one of our dangerous
commands
* check the rest of the vector for dangerous
command
* line arguments
*/
tmpptr=av;
*tmpptr++;
while (*tmpptr!=NULL)
{
if(exact_match(*tmpptr, cmdarg->badarg))
{
syslog(LOG_ERR, "%s is not permitted
for use with %s (%s))",
cmdarg->badarg, cmdarg->name,
logstamp());
return 1;
}
*tmpptr++;
}
}
cmdarg++;
}
return 0;
}
int valid_arg_vector(char **av)
{
cmd_t *cmd=commands;
while (cmd != NULL)
{
if (cmd->name == NULL)
return 0;
if (exact_match(cmd->name,av[0]))
{
if ((cmd->argflag == 0) && (av[1]!=NULL))
{
return 0;
}
return 1;
}
cmd++;
}
return 0;
}
char *substitute_known_path(char *request)
{
cmd_t *cmd=commands;
char *stripped_req=strdup(basename(request));
while (cmd != NULL)
{
if (cmd->name == NULL)
break;
if (exact_match(basename(cmd->name),stripped_req))
{
free(stripped_req); //discard old pathname
return (strdup(cmd->name));
}
cmd++;
}
return (stripped_req);
}
char **build_arg_vector(char *request)
{
/*
* i strdup vector elements so i know they are
* mine to free later.
*/
char **ap, *argv[MAX_ARGC], *inputstring, *tmpstring, *freeme;
char **ap2,**av=(char **)malloc(MAX_ARGC * (sizeof(char *)));
ap=argv;
freeme=inputstring=strdup(request); // make a local copy
while (ap < &argv[(MAX_ARGC-1)])
{
if (inputstring && (*inputstring=='"'))
{
if (NULL != (tmpstring=strchr((inputstring+1),'"')))
{
*tmpstring++='\0';
*ap=(inputstring+1);
#ifdef UNIX_COMPAT
if (solaris_needs_strsep(&tmpstring, WHITE) ==
NULL)
#else
if (strsep(&tmpstring, WHITE) == NULL)
#endif
break;
inputstring=tmpstring;
if (**ap != '\0')
ap++;
continue;
}
}
#ifdef UNIX_COMPAT
if ((*ap = solaris_needs_strsep(&inputstring, WHITE)) == NULL)
#else
if ((*ap = strsep(&inputstring, WHITE)) == NULL)
#endif
break;
if (**ap != '\0')
ap++;
}
*ap = NULL;
ap=argv;
ap2=av;
while (*ap != NULL)
{
*ap2=strdup(*ap);
ap2++;
ap++;
}
*ap2 = NULL;
free(freeme);
return (av);
}
char **expand_wildcards(char **av_old)
#ifdef HAVE_GLOB
{
char **av_new=(char **)malloc(MAX_ARGC * (sizeof(char *)));
glob_t g;
int c_old,c_new,c; // argument counters
#ifdef UNIX_COMPAT
int flags = GLOB_NOCHECK;
#else
int flags = GLOB_NOCHECK | GLOB_TILDE;
#endif
g.gl_offs = c_new = c_old = 0;
while(av_old[c_old] != NULL )
{
if (0 == glob(av_old[c_old++],flags,NULL,&g))
{
c=0;
while((g.gl_pathv[c] != NULL) && (c_new < (MAX_ARGC-1)))
av_new[c_new++]=strdup(g.gl_pathv[c++]);
globfree(&g);
}
}
av_new[c_new]=NULL;
discard_vector(av_old);
return av_new;
}
#else
#ifdef HAVE_WORDEXP
{
return NULL;
}
#endif
#endif
int cntchr(char *buf, char x)
{
int count=0;
while (*buf!=0)
if (*buf++==x)
count++;
return count;
}
char *logstamp ()
{
/* Time and pid are handled for us by syslog(3). */
static char ret_buf[255];
static const char bad_ip[10] = "no ip?!";
char *ipstring = NULL;
ipstring = (char *)getenv("SSH_CLIENT");
if (!ipstring)
ipstring = (char *)getenv("SSH2_CLIENT");
if (!ipstring)
ipstring = (char *)bad_ip;
snprintf(ret_buf, sizeof(ret_buf)-1,
"username: %s(%d), IP/port: %s", username, getuid(), ipstring);
return ret_buf;
}
/*
* if big ends with small, return big without
* small in a new buf, else NULL
*/
inline char *strend (char *big, char *small)
{
int blen,slen;
slen=strlen(small);
blen=strlen(big);
if ((blen==0) || (slen==0) || (blen < slen))
{
return NULL;
}
if (0 == strcmp(&big[(blen-slen)],small))
{
char *tempbuf=NULL;
tempbuf=(char *)malloc(blen-slen+1);
if (tempbuf==NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
bzero(tempbuf,(blen-slen+1));
strncpy(tempbuf, big, blen-slen);
return tempbuf;
}
return NULL;
}
/*
* if big starts with small, return the char after
* the last char in small from big. ahem.
*/
inline char *strbeg (char *big, char *small)
{
if (strlen(big) <= strlen(small))
return NULL;
if (0==strncmp(big,small,strlen(small)))
return (big+strlen(small));
return NULL;
}
/*
* if any chars in string dont appear in ALLOWABLE
* then fail (return 0)
*/
int valid_chars(char *string)
{
int count;
if ((count=strspn(string,ALLOWABLE))==strlen(string))
return 1;
else
{
fprintf (stderr, "invalid characters in scp command!\n");
fprintf (stderr, "here:%s\n",string+count);
fprintf (stderr, "try using a wildcard to match this
file/directory\n");
return 0;
}
}
/*
* retrieves username and home directory from passwd database
*/
int get_uservar(void)
{
struct passwd *userinfo;
if (NULL==(userinfo=getpwuid(getuid())))
{
syslog (LOG_WARNING, "no knowledge of uid %d [%s]", getuid(),
logstamp());
if (debuglevel)
{
fprintf (stderr, "no knowledge of uid %d\n", getuid());
perror ("getpwuid");
}
return 0;
}
if (debuglevel)
syslog(LOG_DEBUG, "retrieved home directory of \"%s\" for user
\"%s\"",
userinfo->pw_dir, userinfo->pw_name);
strncpy(username,userinfo->pw_name,MAX_USERNAME);
strncpy(homedir,userinfo->pw_dir,FILENAME_MAX);
return 1;
}
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/