[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[dak/master] Introduce the external_files table



The external_files table is to be used by - for example -
security.d.o: we should export the files table to debian-security
under the disguised name of external_files.

We also introduce the use_extfiles setting, and a new check:
check.ExternalHashesCheck, which will compare the uploaded files
hashes to the external_files table, if that holds an entry for them.

It will only do that though, if the use_extfiles setting is on.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
---
 dak/dakdb/update87.py |   64 +++++++++++++++++++++++++++++++++++++++++++++++++
 dak/update_db.py      |    2 +-
 daklib/archive.py     |    1 +
 daklib/checks.py      |   43 +++++++++++++++++++++++++++++++++
 daklib/config.py      |    3 +-
 5 files changed, 111 insertions(+), 2 deletions(-)
 create mode 100644 dak/dakdb/update87.py

diff --git a/dak/dakdb/update87.py b/dak/dakdb/update87.py
new file mode 100644
index 0000000..8d73dcb
--- /dev/null
+++ b/dak/dakdb/update87.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# coding=utf8
+
+"""
+add external_files table for security
+
+@contact: Debian FTP Master <ftpmaster@debian.org>
+@copyright: 2012 Gergely Nagy <algernon@debian.org>
+@license: GNU General Public License version 2 or later
+"""
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+################################################################################
+
+import psycopg2
+from daklib.dak_exceptions import DBUpdateError
+from daklib.config import Config
+
+statements = [
+"""
+CREATE TABLE external_files (
+    id integer,
+    filename text NOT NULL,
+    size bigint NOT NULL,
+    md5sum text NOT NULL,
+    last_used timestamp with time zone,
+    sha1sum text,
+    sha256sum text,
+    created timestamp with time zone DEFAULT now() NOT NULL,
+    modified timestamp with time zone DEFAULT now() NOT NULL
+);
+""",
+]
+
+################################################################################
+def do_update(self):
+    print __doc__
+    try:
+        cnf = Config()
+
+        c = self.db.cursor()
+
+        for stmt in statements:
+            c.execute(stmt)
+
+        c.execute("UPDATE config SET value = '87' WHERE name = 'db_revision'")
+        self.db.commit()
+
+    except psycopg2.ProgrammingError as msg:
+        self.db.rollback()
+        raise DBUpdateError('Unable to apply sick update 87, rollback issued. Error message: {0}'.format(msg))
diff --git a/dak/update_db.py b/dak/update_db.py
index cf327b0..9dc613a 100755
--- a/dak/update_db.py
+++ b/dak/update_db.py
@@ -46,7 +46,7 @@ from daklib.daklog import Logger
 ################################################################################
 
 Cnf = None
-required_database_schema = 86
+required_database_schema = 87
 
 ################################################################################
 
diff --git a/daklib/archive.py b/daklib/archive.py
index 78df632..577601c 100644
--- a/daklib/archive.py
+++ b/daklib/archive.py
@@ -861,6 +861,7 @@ class ArchiveUpload(object):
                     checks.SignatureCheck,
                     checks.ChangesCheck,
                     checks.HashesCheck,
+                    checks.ExternalHashesCheck,
                     checks.SourceCheck,
                     checks.BinaryCheck,
                     checks.BinaryTimestampCheck,
diff --git a/daklib/checks.py b/daklib/checks.py
index 8111ef7..92f7e12 100644
--- a/daklib/checks.py
+++ b/daklib/checks.py
@@ -45,6 +45,12 @@ class Reject(Exception):
     """exception raised by failing checks"""
     pass
 
+class RejectStupidMaintainerException(Exception):
+    """exception raised by failing the external hashes check"""
+
+    def __str__(self):
+        return "'%s' has mismatching %s from the external files db ('%s' [current] vs '%s' [external])" % self.args[:4]
+
 class Check(object):
     """base class for checks
 
@@ -167,6 +173,43 @@ class HashesCheck(Check):
             for f in source.files.itervalues():
                 f.check(upload.directory)
 
+class ExternalHashesCheck(Check):
+    """Checks hashes in .changes and .dsc against an external database."""
+    def check_single(self, session, f):
+        q = session.execute("SELECT size, md5sum, sha1sum, sha256sum FROM external_files WHERE filename LIKE '%%/%s'" % f.filename)
+        (ext_size, ext_md5sum, ext_sha1sum, ext_sha256sum) = q.fetchone() or (None, None, None, None)
+
+        if not ext_size:
+            return
+
+        if ext_size != f.size:
+            raise RejectStupidMaintainerException(f.filename, 'size', f.size, ext_size))
+
+        if ext_md5sum != f.md5sum:
+            raise RejectStupidMaintainerException(f.filename, 'md5sum', f.md5sum, ext_md5sum)
+
+        if ext_sha1sum != f.sha1sum:
+            raise RejectStupidMaintainerException(f.filename, 'sha1sum', f.sha1sum, ext_sha1sum)
+
+        if ext_sha256sum != f.sha256sum:
+            raise RejectStupidMaintainerException(f.filename, 'sha256sum', f.sha256sum, ext_sha256sum)
+
+    def check(self, upload):
+        cnf = Config()
+
+        if not cnf.use_extfiles:
+            return
+
+        session = upload.session
+        changes = upload.changes
+
+        for f in changes.files.itervalues():
+            self.check_single(session, f)
+        source = changes.source
+        if source is not None:
+            for f in source.files.itervalues():
+                self.check_single(session, f)
+
 class BinaryCheck(Check):
     """Check binary packages for syntax errors."""
     def check(self, upload):
diff --git a/daklib/config.py b/daklib/config.py
index c79582c..6587425 100755
--- a/daklib/config.py
+++ b/daklib/config.py
@@ -120,7 +120,8 @@ class Config(object):
         for field in [('db_revision',      None,       int),
                       ('defaultsuitename', 'unstable', str),
                       ('exportpath',       '',         str),
-                      ('unprivgroup',      None,       str)
+                      ('unprivgroup',      None,       str),
+                      ('use_extfiles',     None,       int)
                       ]:
             setattr(self, 'get_%s' % field[0], lambda s=None, x=field[0], y=field[1], z=field[2]: self.get_db_value(x, y, z))
             setattr(Config, '%s' % field[0], property(fget=getattr(self, 'get_%s' % field[0])))
-- 
1.7.2.5



Reply to: