Guest User

Untitled

a guest
Oct 20th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.54 KB | None | 0 0
  1. require "cgi"
  2.  
  3. class AkamaiTokenConfig
  4. attr_accessor :window, :session_id, :data, :salt, :field_delimiter, :early_url_encoding, :ip
  5. attr_reader :start_time, :hash_strategy, :acl, :url
  6.  
  7. def initialize(config={})
  8. @ip = config[:ip]
  9. self.start_time = config[:start_time]
  10. self.acl = config[:acl]
  11. self.url = config[:url]
  12. self.hash_strategy = config[:hash_strategy] || :sha256
  13. self.key = config[:key] || "aabbccddeeff00112233445566778899"
  14.  
  15. @window = config[:window] || 300
  16. @session_id = config[:session_id]
  17. @data = config[:data]
  18. @salt = config[:salt]
  19. @field_delimiter = config[:field_delimiter] || "~"
  20. @early_url_encoding = config[:early_url_encoding] || true
  21. end
  22.  
  23. def encode(value)
  24. @early_url_encoding ? CGI.escape(value) : value
  25. end
  26.  
  27. def start_time=(value)
  28. return if value.nil?
  29. raise "start_time out of range" if value < 0 || value > 4294967295
  30. @start_time = value
  31. end
  32.  
  33. # hexlify and unhexlify, respectively
  34. def key=(value)
  35. @key = AkamaiToken.hexlify(value)
  36. end
  37.  
  38. def key
  39. AkamaiToken.unhexlify(@key)
  40. end
  41.  
  42. def hash_strategy=(value)
  43. raise "Invalid hash strategy" if ![:md5, :sha1, :sha256].include?(value)
  44. @hash_strategy = value
  45. end
  46.  
  47. def acl=(value)
  48. return if value.nil?
  49. raise "ACL and URL cannot both be set at the same time" if !@url.nil?
  50. @acl = value
  51. end
  52.  
  53. def url=(value)
  54. return if value.nil?
  55. raise "ACL and URL cannot both be set at the same time" if !@acl.nil?
  56. @url = value
  57. end
  58.  
  59. def start_time_field
  60. fieldify("st", @start_time)
  61. end
  62.  
  63. def expiration_field
  64. time = @start_time || Time.now.to_i
  65. expiration = time + @window
  66. fieldify("exp", expiration)
  67. end
  68.  
  69. def acl_field
  70. @url.nil? ? fieldify("acl", encode(@acl || "/*")) : ""
  71. end
  72.  
  73. def url_field
  74. @acl.nil? ? fieldify("url", encode(@url)) : ""
  75. end
  76.  
  77. def ip_field
  78. @ip ? fieldify("ip", encode(@ip)) : ""
  79. end
  80.  
  81. def session_field
  82. @session_id ? fieldify("id", encode(@session_id)) : ""
  83. end
  84.  
  85. def data_field
  86. @data ? fieldify("data", encode(@data)) : ""
  87. end
  88.  
  89. def salt_field
  90. @salt ? fieldify("salt", encode(@salt)) : ""
  91. end
  92.  
  93. def fieldify(key, value)
  94. "#{key}=#{value}"
  95. end
  96. end
  97.  
  98. class AkamaiToken
  99. HASH_STRATEGY = { :sha1 => OpenSSL::Digest::SHA1, :sha256 => OpenSSL::Digest::SHA256,
  100. :md5 => OpenSSL::Digest::MD5 }
  101. def initialize(debug=false)
  102. @debug = debug
  103. end
  104.  
  105. def self.hexlify(value)
  106. value.unpack("C*").map { |byte| "%02X" % byte }.join("")
  107. end
  108.  
  109. def self.unhexlify(value)
  110. [value].pack("H*")
  111. end
  112.  
  113. def join_fields(fields, delimiter)
  114. fields.reject { |field| field == "" }.join(delimiter)
  115. end
  116.  
  117. def generate_token(token_config)
  118. # sanity check
  119. if (!token_config.acl && !token_config.url) || (token_config.acl && token_config.url)
  120. raise "Must specify either an ACL or a URL but not both"
  121. end
  122.  
  123. # determine values for hashing
  124. t = token_config
  125. mtoken = join_fields([t.ip_field, t.start_time_field, t.expiration_field, t.acl_field, t.session_field,
  126. t.data_field], t.field_delimiter)
  127. mtoken_digest = join_fields([mtoken, t.url_field, t.salt_field], t.field_delimiter)
  128.  
  129. encoded_key = AkamaiToken.hexlify(token_config.key)
  130.  
  131. hmac = OpenSSL::HMAC::digest(HASH_STRATEGY[token_config.hash_strategy].new, encoded_key, mtoken_digest)
  132. encoded_hmac = AkamaiToken.hexlify(hmac)
  133.  
  134. if @debug
  135. puts "SIGNING VALUE: #{mtoken_digest}"
  136. puts "PRODUCES: #{encoded_hmac}"
  137. end
  138. "#{join_fields([mtoken, "hmac"], token_config.field_delimiter)}=#{encoded_hmac}"
  139. end
  140. end
Add Comment
Please, Sign In to add comment