author J.C. Jones <>
Wed, 01 Feb 2017 15:21:04 -0700
changeset 395063 ad5adacd8e14472b0abcf9065efbcc96d5a859c4
parent 325755 8383cfab2abc957c2e4eeeed7f9147a6c71cc9d8
child 410925 34b11112f0e3b342c149295ea8e8eac01cdf646c
permissions -rw-r--r--
Bug 1260318 - Scope U2F Soft Tokens to a single AppID r=qdot,rbarnes This change includes the FIDO "App ID" as part of the function used to generate the wrapping key used in the NSS-based U2F soft token, cryptographically binding the "Key Handle" to the site that Key Handle is intended for. This is a breaking change with existing registered U2F keys, but since our soft token is hidden behind a pref, it does not attempt to be backward-compatible. - Updated for rbarnes' and qdot's reviews comments. Thanks! - Made more strict in size restrictions, and added a version field to help us be this strict. - Bugfix for an early unprotected buffer use (Thanks again rbarnes!) - Fix a sneaky memory leak re: CryptoBuffer.ToSECItem MozReview-Commit-ID: Jf6gNPauT4Y

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at

import errno
import logging
import os
import sys
import time

HERE = os.path.abspath(os.path.dirname(__file__))
sys.path.append(os.path.join(HERE, '..', 'python', 'requests'))
import requests

# Server to which to submit telemetry data

def submit_telemetry_data(statedir):

    # No data to work with anyway
    outgoing = os.path.join(statedir, 'telemetry', 'outgoing')
    if not os.path.isdir(outgoing):
        return 0

    submitted = os.path.join(statedir, 'telemetry', 'submitted')
    except OSError as e:
        if e.errno != errno.EEXIST:

    session = requests.Session()
    for filename in os.listdir(outgoing):
        path = os.path.join(outgoing, filename)
        if os.path.isdir(path) or not path.endswith('.json'):
        with open(path, 'r') as f:
            data =
                r =, data=data,
                                 headers={'Content-Type': 'application/json'})
            except Exception as e:
                logging.error('Exception posting to telemetry '
                              'server: %s' % str(e))
            # TODO: some of these errors are likely not recoverable, as
            # written, we'll retry indefinitely
            if r.status_code != 200:
                logging.error('Error posting to telemetry: %s %s' %
                              (r.status_code, r.text))

        os.rename(os.path.join(outgoing, filename),
                  os.path.join(submitted, filename))


    # Discard submitted data that is >= 30 days old
    now = time.time()
    for filename in os.listdir(submitted):
        ctime = os.stat(os.path.join(submitted, filename)).st_ctime
        if now - ctime >= 60*60*24*30:
            os.remove(os.path.join(submitted, filename))

    return 0

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('usage: python <statedir>')
    statedir = sys.argv[1]
    logging.basicConfig(filename=os.path.join(statedir, 'telemetry', 'telemetry.log'),
                        format='%(asctime)s %(message)s')