#include <stdlib.h>
#include <string.h>
+#include "ftpd_var.h"
+
extern char *auth_type;
unsigned int maxbuf, actualbuf;
unsigned char *ucbuf;
-#if defined(STDARG) || (defined(__STDC__) && ! defined(VARARGS)) || defined(HAVE_STDARG_H)
-extern reply(int, char *, ...);
-extern lreply(int, char *, ...);
-#endif
-
static int kerror; /* XXX needed for all auth types */
#ifdef KRB5_KRB4_COMPAT
extern struct sockaddr_in his_addr, ctrl_addr;
extern int usedefault;
extern int transflag;
extern char tmpline[];
+
char **ftpglob();
off_t restart_point;
};
struct tab cmdtab[];
struct tab sitetab[];
+
+void sizecmd(char *);
+void help(struct tab *, char *);
+static int yylex(void);
%}
%union { int num; char *str; }
if (!auth_type)
reply(503, "Must first perform authentication");
else if (strlen($3) > 10 ||
- strlen($3) == 10 && strcmp($3,"4294967296") >= 0)
+ (strlen($3) == 10 &&
+ strcmp($3,"4294967296") >= 0))
reply(501, "Bad value for PBSZ: %s", $3);
else {
if (ucbuf) (void) free(ucbuf);
= {
if ($2 && $4 != NULL) {
struct stat stbuf;
- if (stat((char *) $4, &stbuf) < 0)
- perror_reply(550, "%s", (char *) $4);
+ if (stat($4, &stbuf) < 0)
+ perror_reply(550, $4);
else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
reply(550, "%s: not a plain file.",
(char *) $4);
= {
fromname = (char *) 0;
restart_point = $3;
- reply(350, "Restarting at %ld. %s", restart_point,
- "Send STORE or RETRIEVE to initiate transfer.");
+ reply(350, "Restarting at %ld. %s",
+ (long) restart_point,
+ "Send STORE or RETRIEVE to initiate transfer.");
}
;
char *s;
register FILE *iop;
{
- register c;
+ register int c;
register char *cs;
- int atmark;
cs = s;
/* tmpline may contain saved command from urgent mode interruption */
#endif /* NOENCRYPTION */
if ((cp = strpbrk(cs, " \r\n")))
*cp = '\0';
- if (kerror = radix_encode(cs, out, &len, 1)) {
+ kerror = radix_encode(cs, out, &len, 1);
+ if (kerror) {
reply(501, "Can't base 64 decode argument to %s command (%s)",
mic ? "MIC" : "ENC", radix_error(kerror));
*s = '\0';
dologout(1);
}
+static int
yylex()
{
static int cpos, state;
}
}
+void
upper(s)
register char *s;
{
return (p);
}
+void
help(ctab, s)
struct tab *ctab;
char *s;
c->name, c->help);
}
+void
sizecmd(filename)
char *filename;
{
(stbuf.st_mode&S_IFMT) != S_IFREG)
reply(550, "%s: not a plain file.", filename);
else
- reply(213, "%lu", stbuf.st_size);
+ reply(213, "%lu", (long) stbuf.st_size);
break;}
case TYPE_A: {
FILE *fin;
#endif
#include <sys/wait.h>
#include <sys/file.h>
-
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifdef HAVE_SHADOW
#include <shadow.h>
#endif
+#include <grp.h>
#include <setjmp.h>
#ifndef POSIX_SETJMP
#undef sigjmp_buf
#include <k5-util.h>
-#ifdef STDARG
-extern reply(int, char *, ...)
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
- __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
- ;
-extern lreply(int, char *, ...)
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
- __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
- ;
-#endif
-
#ifdef KRB5_KRB4_COMPAT
+#include <krb5.h>
#include <krb.h>
+#include <krb524.h>
AUTH_DAT kdata;
KTEXT_ST ticket;
#include <krb5.h>
krb5_context kcontext;
krb5_ccache ccache;
+
+static void ftpd_gss_convert_creds(char *name, gss_cred_id_t);
+static int ftpd_gss_userok(gss_buffer_t, char *name);
+
#endif /* GSSAPI */
char *auth_type; /* Authentication succeeded? If so, what type? */
* NOT to be used on this machine.
* Commonly used to disallow uucp.
*/
+#include "ftpd_var.h"
+#include "secure.h"
+
extern int errno;
extern char *crypt();
extern char version[];
void send_data();
FILE *dataconn();
#endif
+static void dolog(struct sockaddr_in *);
+static int receive_data(FILE *, FILE *);
+static void login(char *passwd);
+static void end_login(void);
+static int disallowed_user(char *);
+static int restricted_user(char *);
+static int checkuser(char *);
#ifdef SETPROCTITLE
char **Argv = NULL; /* pointer to argument vector */
int maxhostlen = 0;
int always_ip = 0;
+int
main(argc, argv, envp)
int argc;
char *argv[];
/*
* Set data channel protection level
*/
+void
setdlevel(prot_level)
int prot_level;
{
* "restrict." Restricted users are allowed to login, but a chroot() is
* done to their home directory.
*/
+void
user(name)
char *name;
{
return;
}
- if (pw = sgetpwnam(name)) {
+ pw = sgetpwnam(name);
+ if (pw) {
if ((shell = pw->pw_shell) == NULL || *shell == 0)
shell = "/bin/sh";
#ifdef HAVE_GETUSERSHELL
name = "[username too long]";
}
sprintf(buf, "GSSAPI user %s is%s authorized as %s",
- client_name.value, authorized ? "" : " not",
+ (char *) client_name.value,
+ authorized ? "" : " not",
name);
}
#ifdef KRB5_KRB4_COMPAT
* Return 1 if they are (a disallowed user), -1 if their username
* is followed by "restrict." (a restricted user). Otherwise return 0.
*/
+static int
checkuser(name)
char *name;
{
return (0);
}
+static int
disallowed_user(name)
char *name;
{
return(checkuser(name) == 1);
}
+static int
restricted_user(name)
char *name;
{
* Terminate login as previous user, if any, resetting state;
* used when USER command is given or login fails.
*/
+static void
end_login()
{
guest = 0;
}
+static int
kpass(name, passwd)
char *name, *passwd;
{
#ifdef GSSAPI
- krb5_error_code code;
krb5_principal server, me;
krb5_creds my_creds;
krb5_timestamp now;
return 0;
my_creds.client = me;
- sprintf(ccname, "FILE:/tmp/krb5cc_ftpd%d", getpid());
+ sprintf(ccname, "FILE:/tmp/krb5cc_ftpd%ld", (long) getpid());
if (krb5_cc_resolve(kcontext, ccname, &ccache))
return(0);
if (krb5_cc_initialize(kcontext, ccache, me))
if (krb_get_lrealm(realm, 1) != KSUCCESS)
goto nuke_ccache;
- sprintf(ccname, "%s_ftpd%d", TKT_ROOT, getpid());
+ sprintf(ccname, "%s_ftpd%ld", TKT_ROOT, (long) getpid());
krb_set_tkt_string(ccname);
if (krb_get_pw_in_tkt(name, "", realm, "krbtgt", realm, 1, passwd))
return(0);
}
+void
pass(passwd)
char *passwd;
{
return;
}
+static void
login(passwd)
char *passwd;
{
(void) initgroups(pw->pw_name, pw->pw_gid);
/* open wtmp before chroot */
- (void) sprintf(ttyline, "ftp%d", getpid());
+ (void) sprintf(ttyline, "ftp%ld", (long) getpid());
pty_logwtmp(ttyline, pw->pw_name, rhost_sane);
logged_in = 1;
end_login();
}
+void
retrieve(cmd, name)
char *cmd, *name;
{
syslog(LOG_NOTICE, "get: %i bytes transferred", byte_count);
}
+void
store_file(name, mode, unique)
char *name, *mode;
int unique;
* FTP_BUFSIZ
*/
#ifdef STDARG
+void
secure_error(char *fmt, ...)
#else
/* VARARGS1 */
+void
secure_error(fmt, p1, p2, p3, p4, p5)
char *fmt;
#endif
*
* N.B.: Form isn't handled.
*/
+static int
receive_data(instr, outstr)
FILE *instr, *outstr;
{
return (-1);
}
+void
statfilecmd(filename)
char *filename;
{
reply(211, "End of Status");
}
+void
statcmd()
{
struct sockaddr_in *sin;
u_char *a, *p;
char str[FTP_BUFSIZ];
- lreply(211, "%s FTP server status:", hostname, version);
+ lreply(211, "%s FTP server status:", hostname);
reply(0, " %s", version);
sprintf(str, " Connected to %s", remotehost[0] ? remotehost : "");
sprintf(&str[strlen(str)], " (%s)", rhost_addra);
reply(211, "End of status");
}
+void
fatal(s)
char *s;
{
* FTP_BUFSIZ bytes for now.
*/
#ifdef STDARG
+void
reply(int n, char *fmt, ...)
#else
/* VARARGS2 */
+void
reply(n, fmt, p0, p1, p2, p3, p4, p5)
int n;
char *fmt;
if (length >= sizeof(in) / 4 * 3) {
syslog(LOG_ERR, "input to radix_encode too long");
fputs(in, stdout);
- } else if (kerror = radix_encode(out, in, &length, 0)) {
+ } else if ((kerror = radix_encode(out, in, &length, 0))) {
syslog(LOG_ERR, "Couldn't encode reply (%s)",
radix_error(kerror));
fputs(in,stdout);
* FTP_BUFSIZ
*/
#ifdef STDARG
+void
lreply(int n, char *fmt, ...)
#else
/* VARARGS2 */
+void
lreply(n, fmt, p0, p1, p2, p3, p4, p5)
int n;
char *fmt;
cont_char = ' ';
}
+void
ack(s)
char *s;
{
reply(250, "%s command successful.", s);
}
+void
nack(s)
char *s;
{
}
/* ARGSUSED */
+void
yyerror(s)
char *s;
{
char *cp;
- if (cp = strchr(cbuf,'\n'))
+ cp = strchr(cbuf,'\n');
+ if (cp)
*cp = '\0';
reply(500, "'%.*s': command not understood.",
- FTP_BUFSIZ - sizeof("'': command not understood."), cbuf);
+ (int) (FTP_BUFSIZ - sizeof("'': command not understood.")),
+ cbuf);
}
+void
delete_file(name)
char *name;
{
ack("DELE");
}
+void
cwd(path)
char *path;
{
ack("CWD");
}
+void
makedir(name)
char *name;
{
reply(257, "MKD command successful.");
}
+void
removedir(name)
char *name;
{
ack("RMD");
}
+void
pwd()
{
if (getcwd(pathbuf, sizeof pathbuf) == (char *)NULL)
return (name);
}
+void
renamecmd(from, to)
char *from, *to;
{
ack("RNTO");
}
+static void
dolog(sin)
struct sockaddr_in *sin;
{
* Record logout in wtmp file
* and exit with supplied status.
*/
+void
dologout(status)
int status;
{
if (strcmp(cp, "STAT") == 0) {
if (file_size != (off_t) -1)
reply(213, "Status: %lu of %lu bytes transferred",
- byte_count, file_size);
+ (unsigned long) byte_count,
+ (unsigned long) file_size);
else
- reply(213, "Status: %lu bytes transferred", byte_count);
+ reply(213, "Status: %lu bytes transferred",
+ (unsigned long) byte_count);
}
}
* a legitimate response by Jon Postel in a telephone conversation
* with Rick Adams on 25 Jan 89.
*/
+void
passive()
{
int len;
/*
* Format and send reply containing system error number.
*/
+void
perror_reply(code, string)
int code;
char *string;
*/
if (strlen(string) + extra_len > FTP_BUFSIZ) {
reply(code, "(truncated)%.*s: %s.",
- FTP_BUFSIZ - extra_len, string, err_string);
+ (int) (FTP_BUFSIZ - extra_len), string, err_string);
} else {
reply(code, "%s: %s.", string, err_string);
}
}
+void
auth(type)
char *type;
{
reply(504, "Unknown authentication type: %s", type);
}
+int
auth_data(data)
char *data;
{
int kerror, length;
#ifdef KRB5_KRB4_COMPAT
- int i;
static char **service=NULL;
char instance[INST_SZ];
u_long cksum;
}
#ifdef KRB5_KRB4_COMPAT
if (strcmp(temp_auth_type, "KERBEROS_V4") == 0) {
- if (kerror = radix_encode(data, out_buf, &length, 1)) {
+ kerror = radix_encode(data, out_buf, &length, 1);
+ if (kerror) {
reply(501, "Couldn't decode ADAT (%s)",
radix_error(kerror));
syslog(LOG_ERR, "Couldn't decode ADAT (%s)",
secure_error("ADAT: reply too long");
return(0);
}
- if (kerror = radix_encode(out_buf, buf, &length, 0)) {
+
+ kerror = radix_encode(out_buf, buf, &length, 0);
+ if (kerror) {
secure_error("Couldn't encode ADAT reply (%s)",
radix_error(kerror));
return(0);
chan.application_data.length = 0;
chan.application_data.value = 0;
- if (kerror = radix_encode(data, gout_buf, &length, 1)) {
+ kerror = radix_encode(data, gout_buf, &length, 1);
+ if (kerror) {
reply(501, "Couldn't decode ADAT (%s)",
radix_error(kerror));
syslog(LOG_ERR, "Couldn't decode ADAT (%s)",
&deleg_creds);
return(0);
}
- if (kerror = radix_encode(out_tok.value, gbuf, &out_tok.length, 0)) {
+ kerror = radix_encode(out_tok.value, gbuf,
+ &out_tok.length, 0);
+ if (kerror) {
secure_error("Couldn't encode ADAT reply (%s)",
radix_error(kerror));
syslog(LOG_ERR, "couldn't encode ADAT reply");
#endif /* GSSAPI */
/* Other auth types go here ... */
/* Also need to check authorization, but that is done in user() */
+ return(0);
}
static char *onefile[] = {
* FTP_BUFSIZ
*/
#ifdef STDARG
+int
secure_fprintf(FILE *stream, char *fmt, ...)
#else
+int
secure_fprintf(stream, fmt, p1, p2, p3, p4, p5)
FILE *stream;
char *fmt;
#endif
}
+void
send_file_list(whichfiles)
char *whichfiles;
{
(void)secure_flush(fileno(dout));
return;
}
- while (dirname = *dirlist++) {
+ while ((dirname = *dirlist++)) {
if (stat(dirname, &st) < 0) {
/*
* If user typed "ls -l", etc, and the client
#endif /* SETPROCTITLE */
#ifdef GSSAPI
+void
reply_gss_error(code, maj_stat, min_stat, s)
int code;
OM_uint32 maj_stat, min_stat;
reply(code, "GSSAPI error: %s", s);
}
+void
secure_gss_error(maj_stat, min_stat, s)
OM_uint32 maj_stat, min_stat;
char *s;
/* ftpd_gss_userok -- hide details of getting the name and verifying it */
/* returns 0 for OK */
+static int
ftpd_gss_userok(client_name, name)
gss_buffer_t client_name;
char *name;
/* ftpd_gss_convert_creds -- write out forwarded creds */
/* (code lifted from login.krb5) */
+static void
ftpd_gss_convert_creds(name, creds)
char *name;
gss_cred_id_t creds;
if (krb5_parse_name(kcontext, name, &me))
return;
- sprintf(ccname, "FILE:/tmp/krb5cc_ftpd%d", getpid());
+ sprintf(ccname, "FILE:/tmp/krb5cc_ftpd%ld", (long) getpid());
if (krb5_cc_resolve(kcontext, ccname, &ccache))
return;
if (krb5_cc_initialize(kcontext, ccache, me))
if (krb524_convert_creds_kdc(kcontext, v5creds, &v4creds))
goto cleanup;
- sprintf(ccname, "%s_ftpd%d", TKT_ROOT, getpid());
+ sprintf(ccname, "%s_ftpd%ld", TKT_ROOT, (long) getpid());
krb_set_tkt_string(ccname);
if (in_tkt(v4creds.pname, v4creds.pinst) != KSUCCESS)
--- /dev/null
+/*
+ * appl/gssftp/ftpd/ftp_var.h
+ *
+ * Copyright 2001 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * Prototypes for various functions in the ftpd sources.
+ */
+
+#ifndef FTPD_VAR_H__
+#define FTPD_VAR_H__
+
+/* Prototypes */
+
+#ifdef GSSAPI
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_generic.h>
+#endif
+
+/* radix.c */
+char *radix_error PROTOTYPE((int));
+int radix_encode PROTOTYPE((unsigned char *, unsigned char *, int *, int));
+
+/* ftpd.c */
+void ack(char *);
+int auth_data(char *);
+void auth(char *);
+void cwd(char *);
+void delete_file(char *);
+void dologout(int);
+void fatal(char *);
+void makedir(char *);
+void nack(char *);
+void pass(char *);
+void passive(void);
+void perror_reply(int, char *);
+void pwd(void);
+void removedir(char *);
+void renamecmd(char *, char *);
+void retrieve(char *, char *);
+void send_file_list(char *);
+void setdlevel(int);
+void statcmd();
+void statfilecmd(char *);
+void store_file(char *, char *, int);
+void user(char *);
+void yyerror(char *);
+
+#ifdef GSSAPI
+void
+reply_gss_error(int, OM_uint32, OM_uint32, char *);
+#endif
+
+
+#if defined(STDARG) || (defined(__STDC__) && ! defined(VARARGS)) || defined(HAVE_STDARG_H)
+extern void reply(int, char *, ...)
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+ __attribute__ ((__format__ (__printf__, 2, 3)))
+#endif
+ ;
+extern void lreply(int, char *, ...)
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+ __attribute__ ((__format__ (__printf__, 2, 3)))
+#endif
+ ;
+#endif
+
+
+/* ftpcmd.y */
+void upper(char *);
+
+#endif /* FTPD_VAR_H__ */
+