Ticket URL: https://fedorahosted.org/koji/ticket/119


$ diff -u ./koji-1.6.0/hub/kojihub.py /usr/share/koji-hub/kojihub.py 
--- ./koji-1.6.0/hub/kojihub.py 2010-12-16 16:13:17.000000000 -0500
+++ /usr/share/koji-hub/kojihub.py      2011-12-04 20:17:40.460047608 -0500
@@ -51,6 +51,86 @@
 import zipfile
 from koji.context import context
 
+import hashlib
+import struct
+
+def sigsha2(fn, cm=None):
+       # http://www.iagora.com/~espel/rpm2cpio
+       
+       nel = 0
+       f = open(fn, "r")
+       
+       rpm = f.read(96)
+       if (len(rpm) != 96):
+               #print("error reading lead 96.0")
+               return cm
+       nel += len(rpm)
+       
+       # http://perldoc.perl.org/functions/pack.html
+       # http://docs.python.org/library/struct.html
+       
+       (magic, major, minor, rest) = struct.unpack(">LBB90s", rpm)
+       
+       if (magic != 0xedabeedb):
+               #print("incorrect lead magic")
+               return cm
+       
+       if ((major != 3) and (major != 4)):
+               #print("incorrect lead major")
+               return cm
+       
+       # http://docs.python.org/library/stdtypes.html
+       
+       while (1):
+               pos = nel
+               rpm = f.read(16)
+               if (len(rpm) != 16):
+                       #print("error reading header 16.0")
+                       return cm
+               nel += len(rpm)
+               (smagic, rest) = struct.unpack(">H14s", rpm)
+               if ((smagic == 0x1f8b) or (smagic == 0x425a) or (smagic == 
0xfd37)):
+                       break
+               if (pos & 0x7):
+                       pos += 7
+                       pos &= (~0x7)
+                       f.seek(pos, 0)
+                       nel = pos
+                       rpm = f.read(16)
+                       if (len(rpm) != 16):
+                               #print("error reading header 16.1")
+                               return cm
+                       nel += len(rpm)
+               left = (len(rpm) - 16)
+               (magic, data, sections, bytes, rest) = struct.unpack(">4L" + 
str(left) + "s", rpm)
+               if (magic != 0x8eade801):
+                       #print("incorrect header magic")
+                       return cm
+               # beg custom
+               f.seek(pos + 16, 0)
+               tmp = f.read((16 * sections) + bytes)
+               head = (rpm + tmp)
+               # end custom
+               pos += 16
+               pos += (16 * sections)
+               pos += bytes
+               f.seek(pos, 0)
+               nel = pos
+       
+       while (1):
+               tmp = f.read(16384)
+               if (not tmp):
+                       break
+               rpm += tmp
+       
+       f.close()
+       md5hex = hashlib.md5(head + rpm).hexdigest()
+       
+       if ((cm != None) and (cm != md5hex)):
+               #print("sigmd5 mis-match")
+               return cm
+       
+       return hashlib.sha256(head + rpm).hexdigest()
 
 logger = logging.getLogger('koji.hub')
 
@@ -4092,12 +4172,13 @@
             raise koji.GenericError, "srpm mismatch for %s: %s (expected %s)" \
                     % (fn,basename,srpmname)
 
+    hdr_md5 = hdr[rpm.RPMTAG_SIGMD5]
     #add rpminfo entry
     rpminfo['id'] = _singleValue("""SELECT nextval('rpminfo_id_seq')""")
     rpminfo['build'] = buildinfo
     rpminfo['build_id'] = buildinfo['id']
     rpminfo['size'] = os.path.getsize(fn)
-    rpminfo['payloadhash'] = koji.hex_string(hdr[rpm.RPMTAG_SIGMD5])
+    rpminfo['payloadhash'] = sigsha2(fn, koji.hex_string(hdr_md5))
     rpminfo['brootid'] = brootid
 
     koji.plugin.run_callbacks('preImport', type='rpm', rpm=rpminfo, 
build=buildinfo,
@@ -4539,7 +4620,9 @@
     if not os.path.isdir(builddir):
         raise koji.GenericError, "No such directory: %s" % builddir
     rawhdr = koji.RawHeader(sighdr)
-    sigmd5 = koji.hex_string(rawhdr.get(koji.RPM_SIGTAG_MD5))
+    rpm_path = "%s/%s" % (builddir, koji.pathinfo.rpm(rinfo))
+    hdr_md5 = rawhdr.get(koji.RPM_SIGTAG_MD5)
+    sigmd5 = sigsha2(rpm_path, koji.hex_string(hdr_md5))
     if sigmd5 == rinfo['payloadhash']:
         # note: payloadhash is a misnomer, that field is populated with sigmd5.
         sigkey = rawhdr.get(koji.RPM_SIGTAG_GPG)
@@ -4554,7 +4637,7 @@
         # we need to pull that differently as well
         rpm_path = "%s/%s" % (builddir, koji.pathinfo.rpm(rinfo))
         sigmd5, sigkey = _scan_sighdr(sighdr, rpm_path)
-        sigmd5 = koji.hex_string(sigmd5)
+        sigmd5 = sigsha2(rpm_path, koji.hex_string(sigmd5))
         if sigmd5 != rinfo['payloadhash']:
             nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % rinfo
             raise koji.GenericError, "wrong md5 for %s: %s" % (nvra, sigmd5)


$ koji list-tagged main-builds nledd
Build                                     Tag                   Built by
----------------------------------------  --------------------  ----------------
nledd-2.52-7.fc15                         main-builds           admin


$ su - koji -c "psql -c \"select name,payloadhash from rpminfo where name LIKE 
'nledd%';\""
      name       |                           payloadhash                        
    
-----------------+------------------------------------------------------------------
 nledd           | 
a6f6f123dde44e0967e30b016c8a60ad6c32575a4dd4c83ef779b3bdcebf0279
 nledd           | 
988e2594303acc3c7a1e15bbf1ca621cd626f21faff24c24365c68551f48af3a
 nledd-debuginfo | 
d9b6bf6a7d76f4f6cb966f3353f5d48075bd89184fe74e8a32c155dfd9abd402
(3 rows)


# Main Source Code Addition


import hashlib
import struct


def sigsha2(fn, cm=None):
        # http://www.iagora.com/~espel/rpm2cpio
        
        nel = 0
        f = open(fn, "r")
        
        rpm = f.read(96)
        if (len(rpm) != 96):
                #print("error reading lead 96.0")
                return cm
        nel += len(rpm)
        
        # http://perldoc.perl.org/functions/pack.html
        # http://docs.python.org/library/struct.html
        
        (magic, major, minor, rest) = struct.unpack(">LBB90s", rpm)
        
        if (magic != 0xedabeedb):
                #print("incorrect lead magic")
                return cm
        
        if ((major != 3) and (major != 4)):
                #print("incorrect lead major")
                return cm
        
        # http://docs.python.org/library/stdtypes.html
        
        while (1):
                pos = nel
                rpm = f.read(16)
                if (len(rpm) != 16):
                        #print("error reading header 16.0")
                        return cm
                nel += len(rpm)
                (smagic, rest) = struct.unpack(">H14s", rpm)
                if ((smagic == 0x1f8b) or (smagic == 0x425a) or (smagic == 
0xfd37)):
                        break
                if (pos & 0x7):
                        pos += 7
                        pos &= (~0x7)
                        f.seek(pos, 0)
                        nel = pos
                        rpm = f.read(16)
                        if (len(rpm) != 16):
                                #print("error reading header 16.1")
                                return cm
                        nel += len(rpm)
                left = (len(rpm) - 16)
                (magic, data, sections, bytes, rest) = struct.unpack(">4L" + 
str(left) + "s", rpm)
                if (magic != 0x8eade801):
                        #print("incorrect header magic")
                        return cm
                # beg custom
                f.seek(pos + 16, 0)
                tmp = f.read((16 * sections) + bytes)
                head = (rpm + tmp)
                # end custom
                pos += 16
                pos += (16 * sections)
                pos += bytes
                f.seek(pos, 0)
                nel = pos
        
        while (1):
                tmp = f.read(16384)
                if (not tmp):
                        break
                rpm += tmp
        
        f.close()
        md5hex = hashlib.md5(head + rpm).hexdigest()
        
        if ((cm != None) and (cm != md5hex)):
                #print("sigmd5 mis-match")
                return cm
        
        return hashlib.sha256(head + rpm).hexdigest()


--
buildsys mailing list
[email protected]
https://admin.fedoraproject.org/mailman/listinfo/buildsys

Reply via email to