aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon L. B. Nielsen <simon@FreeBSD.org>2009-01-07 20:17:55 +0000
committerSimon L. B. Nielsen <simon@FreeBSD.org>2009-01-07 20:17:55 +0000
commit636b4dcc16aaafd36ca1dec5ff590cd41b16adcf (patch)
tree104b7219354d9b7836c63c8c5e9c578cb7608cea
parent343d9769a6eb6d6039f02009d366e378660324a7 (diff)
downloadsrc-636b4dcc16aaafd36ca1dec5ff590cd41b16adcf.tar.gz
src-636b4dcc16aaafd36ca1dec5ff590cd41b16adcf.zip
Prevent cross-site forgery attacks on lukemftpd(8) due to splitting
long commands into multiple requests. [09:01] Fix incorrect OpenSSL checks for malformed signatures due to invalid check of return value from EVP_VerifyFinal(), DSA_verify, and DSA_do_verify. [09:02] Security: FreeBSD-SA-09:01.lukemftpd Security: FreeBSD-SA-09:02.openssl Obtained from: NetBSD [SA-09:01] Obtained from: OpenSSL Project [SA-09:02] Approved by: so (simon)
Notes
Notes: svn path=/releng/7.0/; revision=186872
-rw-r--r--UPDATING6
-rw-r--r--contrib/lukemftpd/src/extern.h2
-rw-r--r--contrib/lukemftpd/src/ftpcmd.y39
-rw-r--r--contrib/lukemftpd/src/ftpd.c10
-rw-r--r--crypto/openssl/apps/speed.c2
-rw-r--r--crypto/openssl/apps/spkac.c2
-rw-r--r--crypto/openssl/apps/verify.c3
-rw-r--r--crypto/openssl/apps/x509.c2
-rw-r--r--crypto/openssl/ssl/s2_clnt.c2
-rw-r--r--crypto/openssl/ssl/s2_srvr.c4
-rw-r--r--crypto/openssl/ssl/s3_clnt.c6
-rw-r--r--crypto/openssl/ssl/s3_srvr.c2
-rw-r--r--crypto/openssl/ssl/ssltest.c2
-rw-r--r--sys/conf/newvers.sh2
14 files changed, 59 insertions, 25 deletions
diff --git a/UPDATING b/UPDATING
index ea621dbaaa3f..ebeddb3d6c1b 100644
--- a/UPDATING
+++ b/UPDATING
@@ -8,6 +8,12 @@ Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before running
portupgrade.
+20090107: p8 FreeBSD-SA-09:01.lukemftpd, FreeBSD-SA-09:02.openssl
+ Prevent cross-site forgery attacks on lukemftpd(8) due to splitting
+ long commands into multiple requests. [09:01]
+
+ Fix incorrect OpenSSL checks for malformed signatures. [09:02]
+
20081223: p7 FreeBSD-SA-08:12.ftpd, FreeBSD-SA-08:13.protosw
Prevent cross-site forgery attacks on ftpd(8) due to splitting
long commands into multiple requests. [08:12]
diff --git a/contrib/lukemftpd/src/extern.h b/contrib/lukemftpd/src/extern.h
index 2d0210600d29..771fbb89ccff 100644
--- a/contrib/lukemftpd/src/extern.h
+++ b/contrib/lukemftpd/src/extern.h
@@ -139,7 +139,7 @@ void feat(void);
void format_path(char *, const char *);
int ftpd_pclose(FILE *);
FILE *ftpd_popen(char *[], const char *, int);
-char *getline(char *, int, FILE *);
+int getline(char *, int, FILE *);
void init_curclass(void);
void logxfer(const char *, off_t, const char *, const char *,
const struct timeval *, const char *);
diff --git a/contrib/lukemftpd/src/ftpcmd.y b/contrib/lukemftpd/src/ftpcmd.y
index 804a26b2b49a..3f3e950111d0 100644
--- a/contrib/lukemftpd/src/ftpcmd.y
+++ b/contrib/lukemftpd/src/ftpcmd.y
@@ -1363,8 +1363,12 @@ lookup(struct tab *p, const char *cmd)
/*
* getline - a hacked up version of fgets to ignore TELNET escape codes.
+ * `s' is the buffer to read into.
+ * `n' is the 1 less than the size of the buffer, to allow trailing NUL
+ * `iop' is the FILE to read from.
+ * Returns 0 on success, -1 on EOF, -2 if the command was too long.
*/
-char *
+int
getline(char *s, int n, FILE *iop)
{
int c;
@@ -1379,7 +1383,7 @@ getline(char *s, int n, FILE *iop)
if (ftpd_debug)
syslog(LOG_DEBUG, "command: %s", s);
tmpline[0] = '\0';
- return(s);
+ return(0);
}
if (c == 0)
tmpline[0] = '\0';
@@ -1418,11 +1422,25 @@ getline(char *s, int n, FILE *iop)
}
}
*cs++ = c;
- if (--n <= 0 || c == '\n')
+ if (--n <= 0) {
+ /*
+ * If command doesn't fit into buffer, discard the
+ * rest of the command and indicate truncation.
+ * This prevents the command to be split up into
+ * multiple commands.
+ */
+ if (ftpd_debug)
+ syslog(LOG_DEBUG,
+ "command too long, last char: %d", c);
+ while (c != '\n' && (c = getc(iop)) != EOF)
+ continue;
+ return (-2);
+ }
+ if (c == '\n')
break;
}
if (c == EOF && cs == s)
- return (NULL);
+ return (-1);
*cs++ = '\0';
if (ftpd_debug) {
if ((curclass.type != CLASS_GUEST &&
@@ -1444,7 +1462,7 @@ getline(char *s, int n, FILE *iop)
syslog(LOG_DEBUG, "command: %.*s", len, s);
}
}
- return (s);
+ return (0);
}
void
@@ -1458,15 +1476,20 @@ ftp_handle_line(char *cp)
void
ftp_loop(void)
{
+ int ret;
while (1) {
(void) alarm(curclass.timeout);
- if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
+ ret = getline(cbuf, sizeof(cbuf)-1, stdin);
+ (void) alarm(0);
+ if (ret == -1) {
reply(221, "You could at least say goodbye.");
dologout(0);
+ } else if (ret == -2) {
+ reply(500, "Command too long.");
+ } else {
+ ftp_handle_line(cbuf);
}
- (void) alarm(0);
- ftp_handle_line(cbuf);
}
/*NOTREACHED*/
}
diff --git a/contrib/lukemftpd/src/ftpd.c b/contrib/lukemftpd/src/ftpd.c
index 50a88545fe1d..afdd5173fa80 100644
--- a/contrib/lukemftpd/src/ftpd.c
+++ b/contrib/lukemftpd/src/ftpd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ftpd.c,v 1.176 2006/05/09 20:18:06 mrg Exp $ */
+/* $NetBSD: ftpd.c,v 1.187 2008/09/13 03:30:35 lukem Exp $ */
/*
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
@@ -2896,6 +2896,7 @@ static int
handleoobcmd()
{
char *cp;
+ int ret;
if (!urgflag)
return (0);
@@ -2904,9 +2905,14 @@ handleoobcmd()
if (!transflag)
return (0);
cp = tmpline;
- if (getline(cp, sizeof(tmpline), stdin) == NULL) {
+ ret = getline(cp, sizeof(tmpline)-1, stdin);
+ if (ret == -1) {
reply(221, "You could at least say goodbye.");
dologout(0);
+ } else if (ret == -2) {
+ /* Ignore truncated command */
+ /* XXX: abort xfer with "500 command too long", & return 1 ? */
+ return 0;
}
/*
* Manually parse OOB commands, because we can't
diff --git a/crypto/openssl/apps/speed.c b/crypto/openssl/apps/speed.c
index 7858aee76ed3..4af171d5f888 100644
--- a/crypto/openssl/apps/speed.c
+++ b/crypto/openssl/apps/speed.c
@@ -2038,7 +2038,7 @@ int MAIN(int argc, char **argv)
{
ret=RSA_verify(NID_md5_sha1, buf,36, buf2,
rsa_num, rsa_key[j]);
- if (ret == 0)
+ if (ret <= 0)
{
BIO_printf(bio_err,
"RSA verify failure\n");
diff --git a/crypto/openssl/apps/spkac.c b/crypto/openssl/apps/spkac.c
index 0191d0a783f7..01fe4062521a 100644
--- a/crypto/openssl/apps/spkac.c
+++ b/crypto/openssl/apps/spkac.c
@@ -285,7 +285,7 @@ bad:
pkey = NETSCAPE_SPKI_get_pubkey(spki);
if(verify) {
i = NETSCAPE_SPKI_verify(spki, pkey);
- if(i) BIO_printf(bio_err, "Signature OK\n");
+ if (i > 0) BIO_printf(bio_err, "Signature OK\n");
else {
BIO_printf(bio_err, "Signature Failure\n");
ERR_print_errors(bio_err);
diff --git a/crypto/openssl/apps/verify.c b/crypto/openssl/apps/verify.c
index 9ff32cb06832..20cc9e354cd3 100644
--- a/crypto/openssl/apps/verify.c
+++ b/crypto/openssl/apps/verify.c
@@ -266,7 +266,7 @@ static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X
ret=0;
end:
- if (i)
+ if (i > 0)
{
fprintf(stdout,"OK\n");
ret=1;
@@ -367,4 +367,3 @@ static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
ERR_clear_error();
return(ok);
}
-
diff --git a/crypto/openssl/apps/x509.c b/crypto/openssl/apps/x509.c
index 5f61eb5c467a..f0fa9d78aab1 100644
--- a/crypto/openssl/apps/x509.c
+++ b/crypto/openssl/apps/x509.c
@@ -1144,7 +1144,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
/* NOTE: this certificate can/should be self signed, unless it was
* a certificate request in which case it is not. */
X509_STORE_CTX_set_cert(&xsc,x);
- if (!reqfile && !X509_verify_cert(&xsc))
+ if (!reqfile && X509_verify_cert(&xsc) <= 0)
goto end;
if (!X509_check_private_key(xca,pkey))
diff --git a/crypto/openssl/ssl/s2_clnt.c b/crypto/openssl/ssl/s2_clnt.c
index ce60de630a7a..6c7ef68f2660 100644
--- a/crypto/openssl/ssl/s2_clnt.c
+++ b/crypto/openssl/ssl/s2_clnt.c
@@ -1044,7 +1044,7 @@ int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
i=ssl_verify_cert_chain(s,sk);
- if ((s->verify_mode != SSL_VERIFY_NONE) && (!i))
+ if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0))
{
SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
goto err;
diff --git a/crypto/openssl/ssl/s2_srvr.c b/crypto/openssl/ssl/s2_srvr.c
index 27d71a2e0952..e2cba0b29057 100644
--- a/crypto/openssl/ssl/s2_srvr.c
+++ b/crypto/openssl/ssl/s2_srvr.c
@@ -1054,7 +1054,7 @@ static int request_certificate(SSL *s)
i=ssl_verify_cert_chain(s,sk);
- if (i) /* we like the packet, now check the chksum */
+ if (i > 0) /* we like the packet, now check the chksum */
{
EVP_MD_CTX ctx;
EVP_PKEY *pkey=NULL;
@@ -1083,7 +1083,7 @@ static int request_certificate(SSL *s)
EVP_PKEY_free(pkey);
EVP_MD_CTX_cleanup(&ctx);
- if (i)
+ if (i > 0)
{
if (s->session->peer != NULL)
X509_free(s->session->peer);
diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c
index 278be82294cd..e52e9cadc9f5 100644
--- a/crypto/openssl/ssl/s3_clnt.c
+++ b/crypto/openssl/ssl/s3_clnt.c
@@ -883,7 +883,7 @@ int ssl3_get_server_certificate(SSL *s)
}
i=ssl_verify_cert_chain(s,sk);
- if ((s->verify_mode != SSL_VERIFY_NONE) && (!i)
+ if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)
#ifndef OPENSSL_NO_KRB5
&& (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK))
!= (SSL_aKRB5|SSL_kKRB5)
@@ -1368,7 +1368,7 @@ int ssl3_get_key_exchange(SSL *s)
EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,param,param_len);
- if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey))
+ if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
{
/* bad signature */
al=SSL_AD_DECRYPT_ERROR;
@@ -1386,7 +1386,7 @@ int ssl3_get_key_exchange(SSL *s)
EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,param,param_len);
- if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey))
+ if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
{
/* bad signature */
al=SSL_AD_DECRYPT_ERROR;
diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c
index 9414cf09fb64..38ab68203829 100644
--- a/crypto/openssl/ssl/s3_srvr.c
+++ b/crypto/openssl/ssl/s3_srvr.c
@@ -2481,7 +2481,7 @@ int ssl3_get_client_certificate(SSL *s)
else
{
i=ssl_verify_cert_chain(s,sk);
- if (!i)
+ if (i <= 0)
{
al=ssl_verify_alarm_type(s->verify_result);
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED);
diff --git a/crypto/openssl/ssl/ssltest.c b/crypto/openssl/ssl/ssltest.c
index 517657c0240d..41dafbb91ca3 100644
--- a/crypto/openssl/ssl/ssltest.c
+++ b/crypto/openssl/ssl/ssltest.c
@@ -2072,7 +2072,7 @@ static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
if (cb_arg->proxy_auth)
{
- if (ok)
+ if (ok > 0)
{
const char *cond_end = NULL;
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index ca43749c830b..6d9318c67f6c 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="7.0"
-BRANCH="RELEASE-p7"
+BRANCH="RELEASE-p8"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi