def main(): parser = OptionParser(usage=__doc__, prog='wapt-signpackage') parser.add_option( "-c", "--certificate", dest="public_key", default='', help= "Path to the PEM RSA certificate to embed identitiy in control. (default: %default)" ) parser.add_option( "-t", "--trusted", dest="trusted_certs", default='', help= "Path to the trusted PEM RSA certificates directory to check control signature. (default: %default)" ) parser.add_option( "-k", "--private-key", dest="private_key", default='', help= "Path to the PEM RSA private key to sign packages. (default: %default)" ) #parser.add_option("-w","--private-key-passwd", dest="private_key_passwd", default='', help="Path to the password of the private key. (default: %default)") parser.add_option( "-l", "--loglevel", dest="loglevel", default=None, type='choice', choices=['debug', 'warning', 'info', 'error', 'critical'], metavar='LOGLEVEL', help="Loglevel (default: warning)") parser.add_option( "-m", "--message-digest", dest="md", default='sha256', help="Message digest type for signatures. (default: %default)") parser.add_option( "-s", "--scan-packages", dest="doscan", default=False, action='store_true', help= "Rescan packages and update local Packages index after signing. (default: %default)" ) parser.add_option("-r", "--remove-setup", dest="removesetup", default=False, action='store_true', help="Remove setup.py. (default: %default)") parser.add_option( "-i", "--inc-release", dest="increlease", default=False, action='store_true', help="Increase release number when building package (default: %default)" ) parser.add_option( "--maturity", dest="set_maturity", default=None, help="Set/change package maturity when signing package. (default: None)" ) parser.add_option( "--target-os", dest="set_target_os", default=None, help= "Set target_os attribute if empty when signing package. (default: None)" ) parser.add_option( "--keep-signature-date", dest="keep_signature_date", default=False, action='store_true', help= "Keep the current package signature date, and file changetime (default: %default)" ) parser.add_option("--if-needed", dest="if_needed", default=False, action='store_true', help="Re-sign package only if needed (default: warning)") (options, args) = parser.parse_args() loglevel = options.loglevel if len(logger.handlers) < 1: hdlr = logging.StreamHandler(sys.stderr) hdlr.setFormatter( logging.Formatter(u'%(asctime)s %(levelname)s %(message)s')) logger.addHandler(hdlr) if loglevel: setloglevel(logger, loglevel) else: setloglevel(logger, 'warning') if len(args) < 1: print(parser.usage) sys.exit(1) if not options.public_key and not options.private_key: print('ERROR: No certificate found or specified') sys.exit(1) if options.private_key and os.path.isfile(options.private_key): key = SSLPrivateKey(options.private_key) else: cert = SSLCertificate(options.public_key or options.private_key) key = cert.matching_key_in_dirs() if not key: print('ERROR: No private key found or specified') sys.exit(1) args = ensure_list(args) signers_bundle = SSLCABundle() signers_bundle.add_certificates_from_pem(pem_filename=options.public_key) trusted_bundle = SSLCABundle() trusted_bundle.add_certificates_from_pem(pem_filename=options.public_key) if options.trusted_certs: trusted_bundle.add_pems(options.trusted_certs, trust_first=True) waptpackages = [] for arg in args: waptpackages.extend(glob.glob(arg)) errors = [] package_dirs = [] for waptpackage in waptpackages: package_dir = os.path.abspath(os.path.dirname(waptpackage)) if not package_dir in package_dirs: package_dirs.append(package_dir) print('Processing %s' % waptpackage) try: sign_needed = False pe = PackageEntry(waptfile=waptpackage) if options.removesetup: if pe.has_file('setup.py'): with pe.as_zipfile(mode='a') as waptfile: waptfile.remove('setup.py') sign_needed = True if not sign_needed and options.if_needed: try: pe.check_control_signature(trusted_bundle=trusted_bundle, signers_bundle=signers_bundle) for md in ensure_list(options.md): if not pe.has_file(pe.get_signature_filename(md)): raise Exception('Missing signature for md %s' % md) logger.info('%s metadata already signed properly' % pe.asrequirement()) sign_needed = False except Exception as e: logger.info('Sign is needed for %s because %s' % (pe.asrequirement(), e)) sign_needed = True if options.increlease: pe.inc_build() sign_needed = True if options.set_maturity is not None and pe.maturity != options.set_maturity: pe.maturity = options.set_maturity logger.info('Setting maturity to %s' % options.set_maturity) sign_needed = True if options.set_target_os is not None and not pe.target_os: pe.target_os = options.set_target_os logger.info('Setting target_os to %s' % options.set_target_os) sign_needed = True if not options.if_needed or sign_needed: pe.sign_package( private_key=key, certificate=signers_bundle.certificates(), mds=ensure_list(options.md), keep_signature_date=options.keep_signature_date) pe.md5sum = md5_for_file(os.path.join(package_dir, pe.filename)) newfn = pe.make_package_filename() if newfn != pe.filename: newfn_path = os.path.join(package_dir, newfn) if not os.path.isfile(newfn_path): print( u"Renaming file from %s to %s to match new package's properties" % (pe.filename, newfn)) shutil.move(os.path.join(package_dir, pe.filename), newfn_path) else: print( 'WARNING: unable to rename file from %s to %s because target already exists' % (pe.filename, newfn)) print('Done') except Exception as e: print(u'Error: %s' % ensure_unicode(e.message)) errors.append([waptpackage, repr(e)]) if options.doscan: for package_dir in package_dirs: if os.path.isfile(os.path.join(package_dir, 'Packages')): print(u'Launching the update of Packages index in %s ...' % ensure_unicode(package_dir)) repo = WaptLocalRepo(package_dir) repo.update_packages_index(canonical_filenames=True) print('Done') else: print( "Don't forget to rescan your repository with wapt-scanpackages -r -f %s" % os.path.dirname(waptpackages[0])) if errors: print('Package not processed properly: ') for fn, error in errors: print(u'%s : %s' % (fn, error)) sys.exit(1) else: sys.exit(0)