]>
Commit | Line | Data |
---|---|---|
c7287a3c | 1 | #!/usr/bin/env python |
b642cd44 | 2 | |
c6e4b225 PH |
3 | import sys, os |
4 | import json, hashlib | |
b642cd44 | 5 | |
c6e4b225 PH |
6 | try: |
7 | import urllib.request as compat_urllib_request | |
8 | except ImportError: # Python 2 | |
9 | import urllib2 as compat_urllib_request | |
37cd9f52 | 10 | |
c6e4b225 PH |
11 | def rsa_verify(message, signature, key): |
12 | from struct import pack | |
13 | from hashlib import sha256 | |
14 | from sys import version_info | |
15 | def b(x): | |
16 | if version_info[0] == 2: return x | |
17 | else: return x.encode('latin1') | |
18 | assert(type(message) == type(b(''))) | |
19 | block_size = 0 | |
20 | n = key[0] | |
21 | while n: | |
22 | block_size += 1 | |
23 | n >>= 8 | |
24 | signature = pow(int(signature, 16), key[1], key[0]) | |
25 | raw_bytes = [] | |
26 | while signature: | |
27 | raw_bytes.insert(0, pack("B", signature & 0xFF)) | |
28 | signature >>= 8 | |
29 | signature = (block_size - len(raw_bytes)) * b('\x00') + b('').join(raw_bytes) | |
30 | if signature[0:2] != b('\x00\x01'): return False | |
31 | signature = signature[2:] | |
32 | if not b('\x00') in signature: return False | |
33 | signature = signature[signature.index(b('\x00'))+1:] | |
34 | if not signature.startswith(b('\x30\x31\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20')): return False | |
35 | signature = signature[19:] | |
36 | if signature != sha256(message).digest(): return False | |
37 | return True | |
37cd9f52 | 38 | |
c6e4b225 PH |
39 | sys.stderr.write(u'Hi! We changed distribution method and now youtube-dl needs to update itself one more time.\n') |
40 | sys.stderr.write(u'This will only happen once. Simply press enter to go on. Sorry for the trouble!\n') | |
41 | sys.stderr.write(u'From now on, get the binaries from http://rg3.github.io/youtube-dl/download.html, not from the git repository.\n\n') | |
37cd9f52 | 42 | |
c6e4b225 PH |
43 | try: |
44 | raw_input() | |
45 | except NameError: # Python 3 | |
46 | input() | |
37cd9f52 | 47 | |
c6e4b225 PH |
48 | filename = sys.argv[0] |
49 | ||
50 | UPDATE_URL = "http://rg3.github.io/youtube-dl/update/" | |
51 | VERSION_URL = UPDATE_URL + 'LATEST_VERSION' | |
52 | JSON_URL = UPDATE_URL + 'versions.json' | |
53 | UPDATES_RSA_KEY = (0x9d60ee4d8f805312fdb15a62f87b95bd66177b91df176765d13514a0f1754bcd2057295c5b6f1d35daa6742c3ffc9a82d3e118861c207995a8031e151d863c9927e304576bc80692bc8e094896fcf11b66f3e29e04e3a71e9a11558558acea1840aec37fc396fb6b65dc81a1c4144e03bd1c011de62e3f1357b327d08426fe93, 65537) | |
54 | ||
55 | if not os.access(filename, os.W_OK): | |
56 | sys.exit('ERROR: no write permissions on %s' % filename) | |
57 | ||
58 | try: | |
59 | versions_info = compat_urllib_request.urlopen(JSON_URL).read().decode('utf-8') | |
60 | versions_info = json.loads(versions_info) | |
61 | except: | |
62 | sys.exit(u'ERROR: can\'t obtain versions info. Please try again later.') | |
63 | if not 'signature' in versions_info: | |
64 | sys.exit(u'ERROR: the versions file is not signed or corrupted. Aborting.') | |
65 | signature = versions_info['signature'] | |
66 | del versions_info['signature'] | |
67 | if not rsa_verify(json.dumps(versions_info, sort_keys=True).encode('utf-8'), signature, UPDATES_RSA_KEY): | |
68 | sys.exit(u'ERROR: the versions file signature is invalid. Aborting.') | |
69 | ||
70 | version = versions_info['versions'][versions_info['latest']] | |
71 | ||
72 | try: | |
73 | urlh = compat_urllib_request.urlopen(version['bin'][0]) | |
74 | newcontent = urlh.read() | |
75 | urlh.close() | |
76 | except (IOError, OSError) as err: | |
77 | sys.exit('ERROR: unable to download latest version') | |
78 | ||
79 | newcontent_hash = hashlib.sha256(newcontent).hexdigest() | |
80 | if newcontent_hash != version['bin'][1]: | |
81 | sys.exit(u'ERROR: the downloaded file hash does not match. Aborting.') | |
82 | ||
83 | try: | |
84 | with open(filename, 'wb') as outf: | |
85 | outf.write(newcontent) | |
86 | except (IOError, OSError) as err: | |
87 | sys.exit('ERROR: unable to overwrite current version') | |
88 | ||
89 | sys.stderr.write(u'Done! Now you can run youtube-dl.\n') |