From 3722f46d6f0f3361dad710e0534d5c54eaa46314 Mon Sep 17 00:00:00 2001 From: Johan Danielsson Date: Thu, 26 Mar 1998 02:56:10 +0000 Subject: [PATCH] Changes for new merged security stuff. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@4670 ec53bebd-3082-4978-b11e-865c3cabbd6b --- appl/ftp/ftp/cmds.c | 2 +- appl/ftp/ftp/ftp.c | 31 ++--- appl/ftp/ftp/ftp_locl.h | 7 +- appl/ftp/ftp/main.c | 2 +- appl/ftp/ftpd/Makefile.in | 19 ++- appl/ftp/ftpd/ftpcmd.y | 112 +++++------------ appl/ftp/ftpd/ftpd.c | 250 +++++++++++--------------------------- 7 files changed, 132 insertions(+), 291 deletions(-) diff --git a/appl/ftp/ftp/cmds.c b/appl/ftp/ftp/cmds.c index 5aa9b6e52..85ede7c2d 100644 --- a/appl/ftp/ftp/cmds.c +++ b/appl/ftp/ftp/cmds.c @@ -1484,7 +1484,7 @@ disconnect(int argc, char **argv) } cout = NULL; connected = 0; - krb4_quit(); + sec_end(); data = -1; if (!proxy) { macnum = 0; diff --git a/appl/ftp/ftp/ftp.c b/appl/ftp/ftp/ftp.c index a55a2c01c..c4f2c64c9 100644 --- a/appl/ftp/ftp/ftp.c +++ b/appl/ftp/ftp/ftp.c @@ -177,7 +177,7 @@ login(char *host) user = pass = acct = 0; - if(do_klogin(host)) + if(sec_login(host)) printf("\n*** Using plaintext user and password ***\n\n"); else{ printf("Kerberos authentication successful.\n\n"); @@ -202,7 +202,7 @@ login(char *host) strcpy(username, user); n = command("USER %s", user); if (n == CONTINUE) { - if(auth_complete) + if(sec_complete) pass = myname; else if (pass == NULL) { char prompt[128]; @@ -281,10 +281,7 @@ command(char *fmt, ...) vfprintf(stdout, fmt, ap); va_start(ap, fmt); } - if(auth_complete) - krb4_write_enc(cout, fmt, ap); - else - vfprintf(cout, fmt, ap); + sec_vfprintf(cout, fmt, ap); va_end(ap); if(debug){ printf("\n"); @@ -348,16 +345,18 @@ getreply(int expecteof) if(isdigit(buf[0])){ sscanf(buf, "%d", &code); if(code == 631){ - krb4_read_mic(buf); + sec_read_msg(buf, prot_safe); sscanf(buf, "%d", &code); lead_string = "S:"; } else if(code == 632){ - krb4_read_enc(buf); + sec_read_msg(buf, prot_private); sscanf(buf, "%d", &code); lead_string = "P:"; }else if(code == 633){ - printf("Received confidential reply!\n"); - }else if(auth_complete) + sec_read_msg(buf, prot_confidential); + sscanf(buf, "%d", &code); + lead_string = "C:"; + }else if(sec_complete) lead_string = "!!"; else lead_string = ""; @@ -393,7 +392,7 @@ getreply(int expecteof) } }else{ if(verbose > 0 || (verbose > -1 && code > 499)){ - if(auth_complete) + if(sec_complete) fprintf(stdout, "!!"); fprintf(stdout, "%s\n", buf); } @@ -499,11 +498,13 @@ getreply(int expecteof) continue; } *cp = '\0'; - if(auth_complete){ + if(sec_complete){ if(code == 631) - krb4_read_mic(reply_string); - else - krb4_read_enc(reply_string); + sec_read_msg(reply_string, prot_safe); + else if(code == 632) + sec_read_msg(reply_string, prot_private); + else if(code == 633) + sec_read_msg(reply_string, prot_confidential); n = code / 100 + '0'; } diff --git a/appl/ftp/ftp/ftp_locl.h b/appl/ftp/ftp/ftp_locl.h index ce9c35d37..e11324728 100644 --- a/appl/ftp/ftp/ftp_locl.h +++ b/appl/ftp/ftp/ftp_locl.h @@ -127,13 +127,8 @@ extern int LIBPREFIX(fclose) __P((FILE *)); #include "common.h" #include "pathnames.h" -#include - -#include - -#include "krb4.h" - #include "roken.h" +#include "security.h" #if defined(__sun__) && !defined(__svr4) int fclose(FILE*); diff --git a/appl/ftp/ftp/main.c b/appl/ftp/ftp/main.c index d1dfcaf0b..2b8b9af4f 100644 --- a/appl/ftp/ftp/main.c +++ b/appl/ftp/ftp/main.c @@ -174,7 +174,7 @@ lostpeer(int sig) } proxflag = 0; pswitch(0); - krb4_quit(); + sec_end(); SIGRETURN(0); } diff --git a/appl/ftp/ftpd/Makefile.in b/appl/ftp/ftpd/Makefile.in index 6df23c61b..ec8170494 100644 --- a/appl/ftp/ftpd/Makefile.in +++ b/appl/ftp/ftpd/Makefile.in @@ -44,14 +44,25 @@ LIBROKEN= -L$(LIBTOP)/roken -lroken PROGS = ftpd$(EXECSUFFIX) -ftpd_SOURCES = ftpd.c ftpcmd.c logwtmp.c popen.c auth.c krb4.c kauth.c -ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o popen.o auth.o krb4.o kauth.o +ftpd_SOURCES = ftpd.c ftpcmd.c logwtmp.c popen.c security.c krb4.c kauth.c +ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o popen.o security.o krb4.o kauth.o SOURCES = $(ftpd_SOURCES) OBJECTS = $(ftpd_OBJS) all: $(PROGS) +$(ftpd_OBJS): security.h + +security.c: + $(LN_S) $(srcdir)/../ftp/security.c . +security.h: + $(LN_S) $(srcdir)/../ftp/security.h . +krb4.c: + $(LN_S) $(srcdir)/../ftp/krb4.c . +gssapi.c: + $(LN_S) $(srcdir)/../ftp/gssapi.c . + .c.o: $(CC) -c -I$(srcdir) -I$(srcdir)/../common -I$(INCTOP) $(DEFS) $(CFLAGS) $(CPPFLAGS) $< @@ -77,8 +88,10 @@ ftpcmd.c: ftpcmd.y TAGS: $(SOURCES) etags $(SOURCES) +CLEANFILES = ftpd$(EXECSUFFIX) ftpcmd.c security.c security.h krb4.c gssapi.c + clean cleandir: - rm -f *~ *.o core ftpd$(EXECSUFFIX) ftpcmd.c \#* + rm -f *~ *.o core \#* $(CLEANFILES) distclean: rm -f Makefile diff --git a/appl/ftp/ftpd/ftpcmd.y b/appl/ftp/ftpd/ftpcmd.y index 73728ea96..04fa32dff 100644 --- a/appl/ftp/ftpd/ftpcmd.y +++ b/appl/ftp/ftpd/ftpcmd.y @@ -42,73 +42,15 @@ %{ - -#ifdef HAVE_CONFIG_H -#include -#endif - +#include "ftpd_locl.h" RCSID("$Id$"); -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_FTP_H -#include -#endif - -#include -#include -#include -#ifdef HAVE_PWD_H -#include -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_SYSLOG_H -#include -#endif -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_BSD_BSD_H -#include -#endif - -#include - -#ifdef SOCKS -#include -extern int LIBPREFIX(fclose) __P((FILE *)); -#endif - -#include "extern.h" -#include "auth.h" - off_t restart_point; static int cmd_type; static int cmd_form; static int cmd_bytesz; -char cbuf[512]; +char cbuf[2048]; char *fromname; struct tab { @@ -170,7 +112,7 @@ static int yylex (void); %token STRING %token NUMBER -%type check_login check_login_no_guest octal_number byte_size +%type check_login check_login_no_guest check_secure octal_number byte_size %type struct_code mode_code type_code form_code %type pathstring pathname password username @@ -218,12 +160,17 @@ cmd } | MIC SP STRING CRLF { - mic($3); + mec($3, prot_safe); free($3); } | CONF SP STRING CRLF { - conf($3); + mec($3, prot_confidential); + free($3); + } + | ENC SP STRING CRLF + { + mec($3, prot_private); free($3); } | PASS SP password CRLF @@ -704,11 +651,6 @@ rcmd (long)restart_point, "Send STORE or RETRIEVE to initiate transfer."); } - | ENC SP STRING CRLF - { - enc($3); - free($3); - } ; username @@ -893,19 +835,24 @@ check_login_no_guest : check_login } ; -check_login - : /* empty */ +check_login : check_secure { - if(auth_complete && prot_level == prot_clear){ - reply(533, "Command protection level denied for paranoid reasons."); - $$ = 0; - }else - if (logged_in) - $$ = 1; - else { + if($1) { + if(($$ = logged_in) == 0) reply(530, "Please login with USER and PASS."); - $$ = 0; - } + } else + $$ = 0; + } + ; + +check_secure : /* empty */ + { + $$ = 1; + if(sec_complete && !secure_command()) { + $$ = 0; + reply(533, "Command protection level denied " + "for paranoid reasons."); + } } ; @@ -1014,8 +961,6 @@ lookup(struct tab *p, char *cmd) return (0); } -#include - /* * getline - a hacked up version of fgets to ignore TELNET escape codes. */ @@ -1036,7 +981,6 @@ getline(char *s, int n) #endif return s; } - prot_level = prot_clear; while ((c = getc(stdin)) != EOF) { c &= 0377; if (c == IAC) { @@ -1127,10 +1071,10 @@ yylex(void) dologout(0); } alarm(0); -#ifdef HASSETPROCTITLE +#ifdef HAVE_SETPROCTITLE if (strncasecmp(cbuf, "PASS", 4) != NULL) setproctitle("%s: %s", proctitle, cbuf); -#endif /* HASSETPROCTITLE */ +#endif if ((cp = strchr(cbuf, '\r'))) { *cp++ = '\n'; *cp = '\0'; diff --git a/appl/ftp/ftpd/ftpd.c b/appl/ftp/ftpd/ftpd.c index 50796f760..c0260602e 100644 --- a/appl/ftp/ftpd/ftpd.c +++ b/appl/ftp/ftpd/ftpd.c @@ -31,124 +31,9 @@ * SUCH DAMAGE. */ -#ifdef HAVE_CONFIG_H -#include -RCSID("$Id$"); -#endif - -/* - * FTP server. - */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#if defined(HAVE_SYS_IOCTL_H) && SunOS != 4 -#include -#endif -#ifdef TIME_WITH_SYS_TIME -#include -#include -#elif defined(HAVE_SYS_TIME_H) -#include -#else -#include -#endif -#ifdef HAVE_SYS_RESOURCE_H -#include -#endif -#ifdef HAVE_SYS_WAIT_H -#include -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN_SYSTM_H -#include -#endif -#ifdef HAVE_NETINET_IP_H -#include -#endif - -#ifdef HAVE_SYS_MMAN_H -#include -#endif - #define FTP_NAMES -#include -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_ARPA_TELNET_H -#include -#endif - -#include -#ifdef HAVE_DIRENT_H -#include -#endif -#include -#ifdef HAVE_FCNTL_H -#include -#endif -#include -#include -#ifdef HAVE_PWD_H -#include -#endif -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYSLOG_H -#include -#endif -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif - -#include - -#include "pathnames.h" -#include "extern.h" -#include "common.h" - -#include "auth.h" - -#include - -#include -#include "roken.h" - -#ifdef OTP -#include -#endif - -#ifdef SOCKS -#include -extern int LIBPREFIX(fclose) __P((FILE *)); -#endif - -void yyparse(); - -#ifndef LOG_FTP -#define LOG_FTP LOG_DAEMON -#endif +#include "ftpd_locl.h" +RCSID("$Id$"); static char version[] = "Version 6.00"; @@ -317,18 +202,20 @@ main(int argc, char **argv) int not_inetd = 0; int port; struct servent *sp; - char tkfile[1024]; set_progname (argv[0]); +#ifdef KRB4 /* detach from any tickets and tokens */ - - snprintf(tkfile, sizeof(tkfile), - "/tmp/ftp_%u", (unsigned)getpid()); - krb_set_tkt_string(tkfile); - if(k_hasafs()) - k_setpag(); - + { + char tkfile[1024]; + snprintf(tkfile, sizeof(tkfile), + "/tmp/ftp_%u", (unsigned)getpid()); + krb_set_tkt_string(tkfile); + if(k_hasafs()) + k_setpag(); + } +#endif sp = getservbyname("ftp", "tcp"); if(sp) port = sp->s_port; @@ -443,8 +330,6 @@ main(int argc, char **argv) syslog(LOG_ERR, "signal: %m"); #endif - auth_init(); - /* Try to handle urgent data inline */ #if defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT) if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (void *)&on, @@ -490,8 +375,15 @@ main(int argc, char **argv) /* reply(220,) must follow */ } gethostname(hostname, sizeof(hostname)); +#ifdef KRB5 + reply(220, "%s FTP server (%s+%s) ready.", hostname, + version, heimdal_version); +#elif defined(KRB4) reply(220, "%s FTP server (%s+%s) ready.", hostname, version, krb4_version); +#else + reply(220, "%s FTP server (%s) ready.", hostname, version); +#endif setjmp(errcatch); for (;;) yyparse(); @@ -575,7 +467,7 @@ user(char *name) { char *cp, *shell; - if(auth_level == 0 && !auth_complete){ + if(auth_level == 0 && !sec_complete){ reply(530, "No login allowed without authorization."); return; } @@ -610,7 +502,7 @@ user(char *name) remotehost, inet_ntoa(his_addr.sin_addr)); return; } - if((auth_level & AUTH_PLAIN) == 0 && !auth_complete){ + if((auth_level & AUTH_PLAIN) == 0 && !sec_complete){ reply(530, "Only authorized and anonymous login allowed."); return; } @@ -636,9 +528,12 @@ user(char *name) } if (logging) strncpy(curname, name, sizeof(curname)-1); - if(auth_ok()) - ct->userok(name); - else { + if(sec_complete) { + if(sec_userok(name) == 0) + do_login(232, name); + else + reply(530, "User %s access denied.", name); + } else { char ss[256]; #ifdef OTP @@ -655,7 +550,7 @@ user(char *name) char *s; #ifdef OTP - if (s = otp_error (&otp_ctx)) + if ((s = otp_error (&otp_ctx)) != NULL) lreply(530, "OTP: %s", s); #endif reply(530, @@ -888,6 +783,7 @@ pass(char *passwd) } #endif else if((auth_level & AUTH_OTP) == 0) { +#ifdef KRB4 char realm[REALM_SZ]; if((rval = krb_get_lrealm(realm, 1)) == KSUCCESS) rval = krb_verify_user(pw->pw_name, "", realm, @@ -897,12 +793,13 @@ pass(char *passwd) if(k_hasafs()) krb_afslog(0, 0); } else +#endif rval = unix_verify_user(pw->pw_name, passwd); } else { char *s; #ifdef OTP - if (s = otp_error(&otp_ctx)) + if ((s = otp_error(&otp_ctx)) != NULL) lreply(530, "OTP: %s", s); #endif } @@ -1268,8 +1165,6 @@ send_data(FILE *instr, FILE *outstr) int c, cnt, filefd, netfd; static char *buf; static size_t bufsize; - int i = 0; - char s[1024]; transflag++; if (setjmp(urgcatch)) { @@ -1279,27 +1174,20 @@ send_data(FILE *instr, FILE *outstr) switch (type) { case TYPE_A: - while ((c = getc(instr)) != EOF) { - byte_count++; - if(i > 1022){ - auth_write(fileno(outstr), s, i); - i = 0; - } - if(c == '\n') - s[i++] = '\r'; - s[i++] = c; - } - if(i) - auth_write(fileno(outstr), s, i); - auth_write(fileno(outstr), s, 0); - fflush(outstr); - transflag = 0; - if (ferror(instr)) - goto file_err; - if (ferror(outstr)) - goto data_err; - reply(226, "Transfer complete."); - return; + while ((c = getc(instr)) != EOF) { + byte_count++; + if(c == '\n') + sec_putc('\r', outstr); + sec_putc(c, outstr); + } + sec_fflush(outstr); + transflag = 0; + if (ferror(instr)) + goto file_err; + if (ferror(outstr)) + goto data_err; + reply(226, "Transfer complete."); + return; case TYPE_I: case TYPE_L: @@ -1315,11 +1203,11 @@ send_data(FILE *instr, FILE *outstr) chunk = mmap(0, st.st_size, PROT_READ, MAP_SHARED, in, 0); if(chunk != (void *)MAP_FAILED) { cnt = st.st_size - restart_point; - auth_write(fileno(outstr), + sec_write(fileno(outstr), chunk + restart_point, cnt); munmap(chunk, st.st_size); - auth_write(fileno(outstr), NULL, 0); + sec_fflush(outstr); byte_count = cnt; transflag = 0; } @@ -1340,9 +1228,9 @@ send_data(FILE *instr, FILE *outstr) return; } while ((cnt = read(filefd, buf, bufsize)) > 0 && - auth_write(netfd, buf, cnt) == cnt) + sec_write(netfd, buf, cnt) == cnt) byte_count += cnt; - auth_write(netfd, buf, 0); /* to end an encrypted stream */ + sec_fflush(outstr); /* to end an encrypted stream */ transflag = 0; if (cnt != 0) { if (cnt < 0) @@ -1400,7 +1288,7 @@ receive_data(FILE *instr, FILE *outstr) case TYPE_I: case TYPE_L: - while ((cnt = auth_read(fileno(instr), buf, bufsize)) > 0) { + while ((cnt = sec_read(fileno(instr), buf, bufsize)) > 0) { if (write(fileno(outstr), buf, cnt) != cnt) goto file_err; byte_count += cnt; @@ -1419,7 +1307,7 @@ receive_data(FILE *instr, FILE *outstr) { char *p, *q; int cr_flag = 0; - while ((cnt = auth_read(fileno(instr), + while ((cnt = sec_read(fileno(instr), buf + cr_flag, bufsize - cr_flag)) > 0){ byte_count += cnt; @@ -1582,21 +1470,21 @@ __attribute__ ((format (printf, 3, 0))) static void int_reply(int n, char *c, const char *fmt, va_list ap) { - char buf[10240]; - char *p; - p=buf; - if(n){ - snprintf(p, sizeof(buf), "%d%s", n, c); - p+=strlen(p); - } - vsnprintf(p, sizeof(buf) - strlen(p), fmt, ap); - p+=strlen(p); - snprintf(p, sizeof(buf) - strlen(p), "\r\n"); - p+=strlen(p); - auth_printf("%s", buf); - fflush(stdout); - if (debug) - syslog(LOG_DEBUG, "<--- %s- ", buf); + char buf[10240]; + char *p; + p=buf; + if(n){ + snprintf(p, sizeof(buf), "%d%s", n, c); + p+=strlen(p); + } + vsnprintf(p, sizeof(buf) - strlen(p), fmt, ap); + p+=strlen(p); + snprintf(p, sizeof(buf) - strlen(p), "\r\n"); + p+=strlen(p); + sec_fprintf(stdout, "%s", buf); + fflush(stdout); + if (debug) + syslog(LOG_DEBUG, "<--- %s- ", buf); } void @@ -1999,7 +1887,7 @@ send_file_list(char *whichf) } snprintf(buf, sizeof(buf), "%s%s\n", dirname, type == TYPE_A ? "\r" : ""); - auth_write(fileno(dout), buf, strlen(buf)); + sec_write(fileno(dout), buf, strlen(buf)); byte_count += strlen(dirname) + 1; continue; } else if (!S_ISDIR(st.st_mode)) @@ -2036,7 +1924,7 @@ send_file_list(char *whichf) else snprintf(buf, sizeof(buf), "%s%s\n", nbuf, type == TYPE_A ? "\r" : ""); - auth_write(fileno(dout), buf, strlen(buf)); + sec_write(fileno(dout), buf, strlen(buf)); byte_count += strlen(nbuf) + 1; } } @@ -2051,7 +1939,7 @@ send_file_list(char *whichf) transflag = 0; if (dout != NULL){ - auth_write(fileno(dout), buf, 0); /* XXX flush */ + sec_write(fileno(dout), buf, 0); /* XXX flush */ fclose(dout); }