You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
3.7 KiB

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