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@lists.fedoraproject.org