summaryrefslogtreecommitdiff
path: root/security/krb5-17/files/patch-ai
diff options
context:
space:
mode:
authorJacques Vidrine <nectar@FreeBSD.org>2001-04-27 18:15:00 +0000
committerJacques Vidrine <nectar@FreeBSD.org>2001-04-27 18:15:00 +0000
commit3f37ef937e3037bce4883eae08c2c55cb79f803e (patch)
tree2e8315f3fcbd9194f98219d16d078cabed72c1ce /security/krb5-17/files/patch-ai
parentadd diveintopython (diff)
Security fix:
``Buffer overflows exist in the FTP daemon included with MIT krb5.'' See <URL:http://web.mit.edu/kerberos/www/advisories/ftpbuf.txt> and <URL:http://web.mit.edu/kerberos/www/advisories/ftpbuf_122_patch.txt>. Obtained from: MIT Kerberos mailing list
Notes
Notes: svn path=/head/; revision=41971
Diffstat (limited to 'security/krb5-17/files/patch-ai')
-rw-r--r--security/krb5-17/files/patch-ai276
1 files changed, 273 insertions, 3 deletions
diff --git a/security/krb5-17/files/patch-ai b/security/krb5-17/files/patch-ai
index ddfff3d3aff9..634db6cdec73 100644
--- a/security/krb5-17/files/patch-ai
+++ b/security/krb5-17/files/patch-ai
@@ -1,6 +1,6 @@
---- appl/gssftp/ftpd/ftpd.c.orig Wed Sep 1 13:38:40 1999
-+++ appl/gssftp/ftpd/ftpd.c Sat Sep 25 10:25:04 1999
-@@ -477,7 +477,13 @@
+--- appl/gssftp/ftpd/ftpd.c.orig Wed Feb 28 16:06:45 2001
++++ appl/gssftp/ftpd/ftpd.c Fri Apr 27 10:18:01 2001
+@@ -485,7 +485,13 @@
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
@@ -15,3 +15,273 @@
addrlen = sizeof (his_addr);
if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
+@@ -761,7 +767,16 @@
+ int result;
+ #ifdef GSSAPI
+ if (auth_type && strcmp(auth_type, "GSSAPI") == 0) {
++ int len;
+ authorized = ftpd_gss_userok(&client_name, name) == 0;
++ len = sizeof("GSSAPI user is not authorized as "
++ "; Password required.")
++ + strlen(client_name.value)
++ + strlen(name);
++ if (len >= sizeof(buf)) {
++ syslog(LOG_ERR, "user: username too long");
++ name = "[username too long]";
++ }
+ sprintf(buf, "GSSAPI user %s is%s authorized as %s",
+ client_name.value, authorized ? "" : " not",
+ name);
+@@ -772,7 +787,18 @@
+ #endif /* GSSAPI */
+ #ifdef KRB5_KRB4_COMPAT
+ if (auth_type && strcmp(auth_type, "KERBEROS_V4") == 0) {
++ int len;
+ authorized = kuserok(&kdata,name) == 0;
++ len = sizeof("Kerberos user .@ is not authorized as "
++ "; Password required.")
++ + strlen(kdata.pname)
++ + strlen(kdata.pinst)
++ + strlen(kdata.prealm)
++ + strlen(name);
++ if (len >= sizeof(buf)) {
++ syslog(LOG_ERR, "user: username too long");
++ name = "[username too long]";
++ }
+ sprintf(buf, "Kerberos user %s%s%s@%s is%s authorized as %s",
+ kdata.pname, *kdata.pinst ? "." : "",
+ kdata.pinst, kdata.prealm,
+@@ -1179,6 +1205,11 @@
+ } else {
+ char line[FTP_BUFSIZ];
+
++ if (strlen(cmd) + strlen(name) + 1 >= sizeof(line)) {
++ syslog(LOG_ERR, "retrieve: filename too long");
++ reply(501, "filename too long");
++ return;
++ }
+ (void) sprintf(line, cmd, name), name = line;
+ fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
+ st.st_size = -1;
+@@ -1417,6 +1448,10 @@
+ return (file);
+ }
+
++/*
++ * XXX callers need to limit total length of output string to
++ * FTP_BUFSIZ
++ */
+ #ifdef STDARG
+ secure_error(char *fmt, ...)
+ #else
+@@ -1616,13 +1651,19 @@
+ {
+ char line[FTP_BUFSIZ];
+ FILE *fin;
+- int c;
++ int c, n;
+ char str[FTP_BUFSIZ], *p;
+
++ if (strlen(filename) + sizeof("/bin/ls -lgA ")
++ >= sizeof(line)) {
++ reply(501, "filename too long");
++ return;
++ }
+ (void) sprintf(line, "/bin/ls -lgA %s", filename);
+ fin = ftpd_popen(line, "r");
+ lreply(211, "status of %s:", filename);
+ p = str;
++ n = 0;
+ while ((c = getc(fin)) != EOF) {
+ if (c == '\n') {
+ if (ferror(stdout)){
+@@ -1639,7 +1680,16 @@
+ *p = '\0';
+ reply(0, "%s", str);
+ p = str;
+- } else *p++ = c;
++ n = 0;
++ } else {
++ *p++ = c;
++ n++;
++ if (n >= sizeof(str)) {
++ reply(551, "output line too long");
++ (void) ftpd_pclose(fin);
++ return;
++ }
++ }
+ }
+ if (p != str) {
+ *p = '\0';
+@@ -1723,6 +1773,10 @@
+
+ char cont_char = ' ';
+
++/*
++ * XXX callers need to limit total length of output string to
++ * FTP_BUFSIZ bytes for now.
++ */
+ #ifdef STDARG
+ reply(int n, char *fmt, ...)
+ #else
+@@ -1744,22 +1798,32 @@
+ #endif
+
+ if (auth_type) {
+- char in[FTP_BUFSIZ], out[FTP_BUFSIZ];
++ /*
++ * Deal with expansion in mk_{safe,priv},
++ * radix_encode, gss_seal, plus slop.
++ */
++ char in[FTP_BUFSIZ*3/2], out[FTP_BUFSIZ*3/2];
+ int length, kerror;
+ if (n) sprintf(in, "%d%c", n, cont_char);
+ else in[0] = '\0';
+ strncat(in, buf, sizeof (in) - strlen(in) - 1);
+ #ifdef KRB5_KRB4_COMPAT
+ if (strcmp(auth_type, "KERBEROS_V4") == 0) {
+- if ((length = clevel == PROT_P ?
+- krb_mk_priv((unsigned char *)in,
+- (unsigned char *)out,
+- strlen(in), schedule, &kdata.session,
+- &ctrl_addr, &his_addr)
+- : krb_mk_safe((unsigned char *)in,
+- (unsigned char *)out,
+- strlen(in), &kdata.session,
+- &ctrl_addr, &his_addr)) == -1) {
++ if (clevel == PROT_P)
++ length = krb_mk_priv((unsigned char *)in,
++ (unsigned char *)out,
++ strlen(in),
++ schedule, &kdata.session,
++ &ctrl_addr,
++ &his_addr);
++ else
++ length = krb_mk_safe((unsigned char *)in,
++ (unsigned char *)out,
++ strlen(in),
++ &kdata.session,
++ &ctrl_addr,
++ &his_addr);
++ if (length == -1) {
+ syslog(LOG_ERR,
+ "krb_mk_%s failed for KERBEROS_V4",
+ clevel == PROT_P ? "priv" : "safe");
+@@ -1803,13 +1867,16 @@
+ }
+ #endif /* GSSAPI */
+ /* Other auth types go here ... */
+- if (kerror = radix_encode(out, in, &length, 0)) {
++ 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)) {
+ syslog(LOG_ERR, "Couldn't encode reply (%s)",
+ radix_error(kerror));
+ fputs(in,stdout);
+ } else
+- printf("%s%c%s", clevel == PROT_P ? "632" : "631",
+- n ? cont_char : '-', in);
++ printf("%s%c%s", clevel == PROT_P ? "632" : "631",
++ n ? cont_char : '-', in);
+ } else {
+ if (n) printf("%d%c", n, cont_char);
+ fputs(buf, stdout);
+@@ -1822,6 +1889,10 @@
+ }
+ }
+
++/*
++ * XXX callers need to limit total length of output string to
++ * FTP_BUFSIZ
++ */
+ #ifdef STDARG
+ lreply(int n, char *fmt, ...)
+ #else
+@@ -1866,7 +1937,8 @@
+
+ if (cp = strchr(cbuf,'\n'))
+ *cp = '\0';
+- reply(500, "'%s': command not understood.", cbuf);
++ reply(500, "'%.*s': command not understood.",
++ FTP_BUFSIZ - sizeof("'': command not understood."), cbuf);
+ }
+
+ delete_file(name)
+@@ -2143,7 +2215,21 @@
+ int code;
+ char *string;
+ {
+- reply(code, "%s: %s.", string, strerror(errno));
++ char *err_string;
++ size_t extra_len;
++ err_string = strerror(errno);
++ if (err_string == NULL)
++ err_string = "(unknown error)";
++ extra_len = strlen(err_string) + sizeof("(truncated): .");
++ /*
++ * XXX knows about FTP_BUFSIZ in reply()
++ */
++ if (strlen(string) + extra_len > FTP_BUFSIZ) {
++ reply(code, "(truncated)%.*s: %s.",
++ FTP_BUFSIZ - extra_len, string, err_string);
++ } else {
++ reply(code, "%s: %s.", string, err_string);
++ }
+ }
+
+ auth(type)
+@@ -2226,6 +2312,10 @@
+ secure_error("ADAT: krb_mk_safe failed");
+ return(0);
+ }
++ if (length >= (FTP_BUFSIZ - sizeof("ADAT=")) / 4 * 3) {
++ secure_error("ADAT: reply too long");
++ return(0);
++ }
+ if (kerror = radix_encode(out_buf, buf, &length, 0)) {
+ secure_error("Couldn't encode ADAT reply (%s)",
+ radix_error(kerror));
+@@ -2360,6 +2450,16 @@
+ }
+
+ if (out_tok.length) {
++ if (out_tok.length >= ((FTP_BUFSIZ - sizeof("ADAT="))
++ / 4 * 3)) {
++ secure_error("ADAT: reply too long");
++ syslog(LOG_ERR, "ADAT: reply too long");
++ (void) gss_release_cred(&stat_min, &server_creds);
++ if (ret_flags & GSS_C_DELEG_FLAG)
++ (void) gss_release_cred(&stat_min,
++ &deleg_creds);
++ return(0);
++ }
+ if (kerror = radix_encode(out_tok.value, gbuf, &out_tok.length, 0)) {
+ secure_error("Couldn't encode ADAT reply (%s)",
+ radix_error(kerror));
+@@ -2458,6 +2558,9 @@
+ * n>=0 on success
+ * -1 on error
+ * -2 on security error
++ *
++ * XXX callers need to limit total length of output string to
++ * FTP_BUFSIZ
+ */
+ #ifdef STDARG
+ secure_fprintf(FILE *stream, char *fmt, ...)
+@@ -2575,6 +2678,15 @@
+ dir->d_name[2] == '\0')
+ continue;
+
++ if (strlen(dirname) + strlen(dir->d_name)
++ + 1 /* slash */
++ + 2 /* CRLF */
++ + 1 > sizeof(nbuf)) {
++ syslog(LOG_ERR,
++ "send_file_list: pathname too long");
++ ret = -2; /* XXX */
++ goto data_err;
++ }
+ sprintf(nbuf, "%s/%s", dirname, dir->d_name);
+
+ /*