]> granicus.if.org Git - apache/blobdiff - support/htdbm.c
Fix integer overflow in ap_pregsub. This can be triggered e.g.
[apache] / support / htdbm.c
index 5ad14c088b2c3ecda3f0d7025833dc3a17eb0d10..f9a02bd49cd323bf9dda642cd1b5410ae5c52ebf 100644 (file)
@@ -1,9 +1,9 @@
-/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
- * applicable.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -48,6 +48,9 @@
 #include "apr_xlate.h"
 #endif /*APR_CHARSET_EBCDIC*/
 
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 #if APR_HAVE_CRYPT_H
 #include <crypt.h>
 #endif
@@ -66,7 +69,7 @@
 #define ALG_APMD5 1
 #define ALG_APSHA 2
 
-#if APR_HAVE_CRYPT_H
+#if (!(defined(WIN32) || defined(NETWARE)))
 #define ALG_CRYPT 3
 #endif
 
@@ -216,7 +219,7 @@ static apr_status_t htdbm_del(htdbm_t *htdbm)
 static apr_status_t htdbm_verify(htdbm_t *htdbm)
 {
     apr_datum_t key, val;
-    char pwd[MAX_STRING_LEN] = {0};
+    char *pwd;
     char *rec, *cmnt;
 
     key.dptr = htdbm->username;
@@ -228,9 +231,9 @@ static apr_status_t htdbm_verify(htdbm_t *htdbm)
     rec = apr_pstrndup(htdbm->pool, val.dptr, val.dsize);
     cmnt = strchr(rec, ':');
     if (cmnt)
-        strncpy(pwd, rec, cmnt - rec);
+        pwd = apr_pstrndup(htdbm->pool, rec, cmnt - rec);
     else
-        strcpy(pwd, rec);
+        pwd = apr_pstrdup(htdbm->pool, rec);
     return apr_password_validate(htdbm->userpass, pwd);
 }
 
@@ -238,8 +241,7 @@ static apr_status_t htdbm_list(htdbm_t *htdbm)
 {
     apr_status_t rv;
     apr_datum_t key, val;
-    char *rec, *cmnt;
-    char kb[MAX_STRING_LEN];
+    char *cmnt;
     int i = 0;
 
     rv = apr_dbm_firstkey(htdbm->dbm, &key);
@@ -247,24 +249,19 @@ static apr_status_t htdbm_list(htdbm_t *htdbm)
         fprintf(stderr, "Empty database -- %s\n", htdbm->filename);
         return APR_ENOENT;
     }
-    rec = apr_pcalloc(htdbm->pool, HUGE_STRING_LEN);
-
     fprintf(stderr, "Dumping records from database -- %s\n", htdbm->filename);
-    fprintf(stderr, "    %-32sComment\n", "Username");
+    fprintf(stderr, "    %-32s Comment\n", "Username");
     while (key.dptr != NULL) {
         rv = apr_dbm_fetch(htdbm->dbm, key, &val);
         if (rv != APR_SUCCESS) {
             fprintf(stderr, "Failed getting data from %s\n", htdbm->filename);
             return APR_EGENERAL;
         }
-        strncpy(kb, key.dptr, key.dsize);
-        kb[key.dsize] = '\0';
-        fprintf(stderr, "    %-32s", kb);
-        strncpy(rec, val.dptr, val.dsize);
-        rec[val.dsize] = '\0';
-        cmnt = strchr(rec, ':');
+        /* Note: we don't store \0-terminators on our dbm data */
+        fprintf(stderr, "    %-32.*s", (int)key.dsize, key.dptr);
+        cmnt = memchr(val.dptr, ':', val.dsize);
         if (cmnt)
-            fprintf(stderr, "%s", cmnt + 1);
+            fprintf(stderr, " %.*s", (int)(val.dptr+val.dsize - (cmnt+1)), cmnt + 1);
         fprintf(stderr, "\n");
         rv = apr_dbm_nextkey(htdbm->dbm, &key);
         if (rv != APR_SUCCESS)
@@ -308,13 +305,17 @@ static apr_status_t htdbm_make(htdbm_t *htdbm)
         case ALG_PLAIN:
             /* XXX this len limitation is not in sync with any HTTPd len. */
             apr_cpystrn(cpw,htdbm->userpass,sizeof(cpw));
+#if (!(defined(WIN32) || defined(NETWARE)))
+            fprintf(stderr, "Warning: Plain text passwords aren't supported by the "
+                    "server on this platform!\n");
+#endif
         break;
-#if APR_HAVE_CRYPT_H
+#if (!(defined(WIN32) || defined(NETWARE)))
         case ALG_CRYPT:
             (void) srand((int) time((time_t *) NULL));
             to64(&salt[0], rand(), 8);
             salt[8] = '\0';
-            apr_cpystrn(cpw, (char *)crypt(htdbm->userpass, salt), sizeof(cpw) - 1);
+            apr_cpystrn(cpw, crypt(htdbm->userpass, salt), sizeof(cpw) - 1);
             fprintf(stderr, "CRYPT is now deprecated, use MD5 instead!\n");
 #endif
         default:
@@ -340,7 +341,7 @@ static apr_status_t htdbm_valid_username(htdbm_t *htdbm)
 static void htdbm_usage(void)
 {
 
-#if APR_HAVE_CRYPT_H
+#if (!(defined(WIN32) || defined(NETWARE)))
 #define CRYPT_OPTION "d"
 #else
 #define CRYPT_OPTION ""
@@ -360,7 +361,7 @@ static void htdbm_usage(void)
     fprintf(stderr, "   -c   Create a new database.\n");
     fprintf(stderr, "   -n   Don't update database; display results on stdout.\n");
     fprintf(stderr, "   -m   Force MD5 encryption of the password (default).\n");
-#if APR_HAVE_CRYPT_H
+#if (!(defined(WIN32) || defined(NETWARE)))
     fprintf(stderr, "   -d   Force CRYPT encryption of the password (now deprecated).\n");
 #endif
     fprintf(stderr, "   -p   Do not encrypt the password (plaintext).\n");
@@ -467,7 +468,7 @@ int main(int argc, const char * const argv[])
             case 's':
                 h->alg = ALG_APSHA;
                 break;
-#if APR_HAVE_CRYPT_H
+#if (!(defined(WIN32) || defined(NETWARE)))
             case 'd':
                 h->alg = ALG_CRYPT;
                 break;
@@ -531,7 +532,7 @@ int main(int argc, const char * const argv[])
     switch (cmd) {
         case HTDBM_VERIFY:
             if ((rv = htdbm_verify(h)) != APR_SUCCESS) {
-                if(rv == APR_ENOENT) {
+                if (APR_STATUS_IS_ENOENT(rv)) {
                     fprintf(stderr, "The user '%s' could not be found in database\n", h->username);
                     exit(ERR_BADUSER);
                 }