Ejemplo n.º 1
0
def uploadfile(baseurl,
               filename,
               format_,
               token,
               nonce,
               cert,
               method=requests.post):
    """Uploads file (given by `filename`) to server at `baseurl`.

    `sesson_key` and `nonce` are string values that get passed as POST
    parameters.
    """
    filehash = sha1sum(filename)
    files = {'filedata': open(filename, 'rb')}

    payload = {
        'sha1': filehash,
        'filename': os.path.basename(filename),
        'token': token,
        'nonce': nonce,
    }

    return method("%s/sign/%s" % (baseurl, format_),
                  files=files,
                  data=payload,
                  verify=cert)
Ejemplo n.º 2
0
def check_cached_fn(options, cached_fn, filehash, filename, dest):
    log.debug("%s: checking cache", filehash)
    if os.path.exists(cached_fn):
        log.info("%s: exists in the cache; copying to %s", filehash, dest)
        tmpfile = dest + '.tmp'
        safe_copyfile(cached_fn, tmpfile)
        newhash = sha1sum(tmpfile)
        overwrite_file(tmpfile, dest)
        log.info("%s: OK", filehash)
        # See if we should re-sign NSS
        if options.nsscmd and filehash != newhash and \
                os.path.exists(os.path.splitext(filename)[0] + ".chk"):
            cmd = '%s "%s"' % (options.nsscmd, dest)
            log.info("Regenerating .chk file")
            log.debug("Running %s", cmd)
            check_call(cmd, shell=True)
        return True
Ejemplo n.º 3
0
def uploadfile(baseurl, filename, format_, token, nonce, cert, method=requests.post):
    """Uploads file (given by `filename`) to server at `baseurl`.

    `sesson_key` and `nonce` are string values that get passed as POST
    parameters.
    """
    filehash = sha1sum(filename)
    files = {'filedata': open(filename, 'rb')}

    payload = {
        'sha1': filehash,
        'filename': os.path.basename(filename),
        'token': token,
        'nonce': nonce,
    }

    return method("%s/sign/%s" % (baseurl, format_), files=files, data=payload, verify=cert)
Ejemplo n.º 4
0
def check_cached_fn(options, cached_fn, filehash, filename, dest):
    log.debug("%s: checking cache", filehash)
    if os.path.exists(cached_fn):
        log.info("%s: exists in the cache; copying to %s", filehash, dest)
        tmpfile = dest + '.tmp'
        safe_copyfile(cached_fn, tmpfile)
        newhash = sha1sum(tmpfile)
        overwrite_file(tmpfile, dest)
        log.info("%s: OK", filehash)
        # See if we should re-sign NSS
        if options.nsscmd and filehash != newhash and \
                os.path.exists(os.path.splitext(filename)[0] + ".chk"):
            cmd = '%s "%s"' % (options.nsscmd, dest)
            log.info("Regenerating .chk file")
            log.debug("Running %s", cmd)
            check_call(cmd, shell=True)
        return True
Ejemplo n.º 5
0
def remote_signfile(options, urls, filename, fmt, token, dest=None):
    filehash = sha1sum(filename)
    if dest is None:
        dest = filename

    parent_dir = os.path.dirname(os.path.abspath(dest))
    if not os.path.exists(parent_dir):
        os.makedirs(parent_dir)

    # Check the cache
    cached_fn = None
    if options.cachedir:
        cached_fn = os.path.join(options.cachedir, fmt, filehash)
        result = check_cached_fn(options, cached_fn, filehash, filename, dest)
        if result:
            return True

    errors = 0
    pendings = 0
    max_errors = 5
    # It takes the server ~60s to respond to an attempting to get a signed file
    # We want to give up after about 5 minutes, so 60*5 = 5 tries.
    max_pending_tries = 5
    url = None
    while True:
        if pendings >= max_pending_tries:
            log.error("%s: giving up after %i tries", filehash, pendings)
            # If we've given up on the current server, try a different one!
            url = urls.pop(0)
            urls.append(url)
            errors += 1
            # Pendings needs to be reset to give the next server a fair shake.
            pendings = 0
        if errors >= max_errors:
            log.error("%s: giving up after %i tries", filehash, errors)
            return False
        # Try to get a previously signed copy of this file
        try:
            url = urls[0]
            log.info("%s: processing %s on %s", filehash, filename, url)
            r = getfile(url, filehash, fmt, options.cert)
            r.raise_for_status()
            responsehash = r.headers['X-SHA1-Digest']
            tmpfile = dest + '.tmp'
            with open(tmpfile, 'wb') as fd:
                for chunk in r.iter_content(1024 ** 2):
                    fd.write(chunk)
            newhash = sha1sum(tmpfile)
            if newhash != responsehash:
                log.warn(
                    "%s: hash mismatch; trying to download again", filehash)
                os.unlink(tmpfile)
                errors += 1
                continue
            overwrite_file(tmpfile, dest)
            log.info("%s: OK", filehash)
            # See if we should re-sign NSS
            if options.nsscmd and filehash != responsehash and \
                    os.path.exists(os.path.splitext(filename)[0] + ".chk"):
                cmd = '%s "%s"' % (options.nsscmd, dest)
                log.info("Regenerating .chk file")
                log.debug("Running %s", cmd)
                check_call(cmd, shell=True)

            # Possibly write to our cache
            if options.cachedir:
                if not os.path.exists(options.cachedir):
                    log.debug("Creating %s", options.cachedir)
                    os.makedirs(options.cachedir)
                log.info("Copying %s to cache %s", dest, cached_fn)
                safe_copyfile(dest, cached_fn)
            break
        except requests.HTTPError:
            try:
                if 'X-Pending' in r.headers:
                    log.debug("%s: pending; try again in a bit", filehash)
                    time.sleep(15)
                    pendings += 1
                    continue
            except Exception:
                raise

            errors += 1

            # That didn't work...so let's upload it
            log.info("%s: uploading for signing", filehash)
            try:
                try:
                    nonce = open(options.noncefile, 'rb').read()
                except IOError:
                    nonce = ""
                r = uploadfile(url, filename, fmt, token, nonce, options.cert)
                r.raise_for_status()
                nonce = r.headers['X-Nonce']
                if six.PY3 and isinstance(nonce, six.text_type):
                    nonce = nonce.encode('utf-8')
                open(options.noncefile, 'wb').write(nonce)
            except requests.RequestException as e:
                log.exception("%s: error uploading file for signing: %s",
                              filehash, str(e))
                urls.pop(0)
                urls.append(url)
            time.sleep(1)
            continue
        except (requests.RequestException, KeyError):
            # Try again in a little while
            log.exception("%s: connection error; trying again soon", filehash)
            # Move the current url to the back
            urls.pop(0)
            urls.append(url)
            time.sleep(1)
            errors += 1
            continue
    return True
 def testCopyFile(self, tmpdir):
     tmp = os.path.join(tmpdir.strpath, "t")
     safe_copyfile(__file__, tmp)
     assert sha1sum(__file__) == sha1sum(tmp)
     assert os.stat(__file__).st_mode == os.stat(tmp).st_mode
     assert int(os.stat(__file__).st_mtime) == int(os.stat(tmp).st_mtime)
 def testSha1sum(self):
     h = hashlib.new('sha1')
     h.update(open(__file__, 'rb').read())
     assert sha1sum(__file__) == h.hexdigest()
Ejemplo n.º 8
0
def remote_signfile(options, urls, filename, fmt, token, dest=None):
    filehash = sha1sum(filename)
    if dest is None:
        dest = filename

    parent_dir = os.path.dirname(os.path.abspath(dest))
    if not os.path.exists(parent_dir):
        os.makedirs(parent_dir)

    # Check the cache
    cached_fn = None
    if options.cachedir:
        cached_fn = os.path.join(options.cachedir, fmt, filehash)
        result = check_cached_fn(options, cached_fn, filehash, filename, dest)
        if result:
            return True

    errors = 0
    pendings = 0
    max_errors = 5
    # It takes the server ~60s to respond to an attempting to get a signed file
    # We want to give up after about 5 minutes, so 60*5 = 5 tries.
    max_pending_tries = 5
    url = None
    while True:
        if pendings >= max_pending_tries:
            log.error("%s: giving up after %i tries", filehash, pendings)
            # If we've given up on the current server, try a different one!
            url = urls.pop(0)
            urls.append(url)
            errors += 1
            # Pendings needs to be reset to give the next server a fair shake.
            pendings = 0
        if errors >= max_errors:
            log.error("%s: giving up after %i tries", filehash, errors)
            return False
        # Try to get a previously signed copy of this file
        try:
            url = urls[0]
            log.info("%s: processing %s on %s", filehash, filename, url)
            r = getfile(url, filehash, fmt, options.cert)
            r.raise_for_status()
            responsehash = r.headers['X-SHA1-Digest']
            tmpfile = dest + '.tmp'
            with open(tmpfile, 'wb') as fd:
                for chunk in r.iter_content(1024**2):
                    fd.write(chunk)
            newhash = sha1sum(tmpfile)
            if newhash != responsehash:
                log.warn("%s: hash mismatch; trying to download again",
                         filehash)
                os.unlink(tmpfile)
                errors += 1
                continue
            overwrite_file(tmpfile, dest)
            log.info("%s: OK", filehash)
            # See if we should re-sign NSS
            if options.nsscmd and filehash != responsehash and \
                    os.path.exists(os.path.splitext(filename)[0] + ".chk"):
                cmd = '%s "%s"' % (options.nsscmd, dest)
                log.info("Regenerating .chk file")
                log.debug("Running %s", cmd)
                check_call(cmd, shell=True)

            # Possibly write to our cache
            if options.cachedir:
                if not os.path.exists(options.cachedir):
                    log.debug("Creating %s", options.cachedir)
                    os.makedirs(options.cachedir)
                log.info("Copying %s to cache %s", dest, cached_fn)
                safe_copyfile(dest, cached_fn)
            break
        except requests.HTTPError:
            try:
                if 'X-Pending' in r.headers:
                    log.debug("%s: pending; try again in a bit", filehash)
                    time.sleep(15)
                    pendings += 1
                    continue
            except Exception:
                raise

            errors += 1

            # That didn't work...so let's upload it
            log.info("%s: uploading for signing", filehash)
            try:
                try:
                    nonce = open(options.noncefile, 'rb').read()
                except IOError:
                    nonce = ""
                r = uploadfile(url, filename, fmt, token, nonce, options.cert)
                r.raise_for_status()
                nonce = r.headers['X-Nonce']
                if six.PY3 and isinstance(nonce, six.text_type):
                    nonce = nonce.encode('utf-8')
                open(options.noncefile, 'wb').write(nonce)
            except requests.RequestException as e:
                log.exception("%s: error uploading file for signing: %s",
                              filehash, str(e))
                urls.pop(0)
                urls.append(url)
            time.sleep(1)
            continue
        except (requests.RequestException, KeyError):
            # Try again in a little while
            log.exception("%s: connection error; trying again soon", filehash)
            # Move the current url to the back
            urls.pop(0)
            urls.append(url)
            time.sleep(1)
            errors += 1
            continue
    return True