freezerwatch 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (314) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/CODE_OF_CONDUCT.md +13 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +40 -0
  7. data/Rakefile +1 -0
  8. data/bin/console +14 -0
  9. data/bin/freezerwatch +9 -0
  10. data/bin/setup +7 -0
  11. data/freezerwatch.gemspec +23 -0
  12. data/lib/freezerwatch.rb +5 -0
  13. data/lib/freezerwatch/version.rb +3 -0
  14. data/node_modules/.bin/freezerwatch +139 -0
  15. data/node_modules/freezerwatch/.npmignore +3 -0
  16. data/node_modules/freezerwatch/.ruby-version +1 -0
  17. data/node_modules/freezerwatch/Gemfile +4 -0
  18. data/node_modules/freezerwatch/Gemfile.lock +79 -0
  19. data/node_modules/freezerwatch/LICENSE +23 -0
  20. data/node_modules/freezerwatch/README.md +41 -0
  21. data/node_modules/freezerwatch/Rakefile +13 -0
  22. data/node_modules/freezerwatch/freezerwatch.js +139 -0
  23. data/node_modules/freezerwatch/metrics/bigfiles_high_water_mark +1 -0
  24. data/node_modules/freezerwatch/metrics/cane_high_water_mark +1 -0
  25. data/node_modules/freezerwatch/metrics/flay_high_water_mark +1 -0
  26. data/node_modules/freezerwatch/metrics/flog_high_water_mark +1 -0
  27. data/node_modules/freezerwatch/metrics/punchlist_high_water_mark +2 -0
  28. data/node_modules/freezerwatch/metrics/reek_high_water_mark +1 -0
  29. data/node_modules/freezerwatch/metrics/rubocop_high_water_mark +1 -0
  30. data/node_modules/freezerwatch/node_modules/async/.jshintrc +25 -0
  31. data/node_modules/freezerwatch/node_modules/async/.travis.yml +6 -0
  32. data/node_modules/freezerwatch/node_modules/async/CHANGELOG.md +65 -0
  33. data/node_modules/freezerwatch/node_modules/async/LICENSE +19 -0
  34. data/node_modules/freezerwatch/node_modules/async/README.md +1803 -0
  35. data/node_modules/freezerwatch/node_modules/async/bower.json +43 -0
  36. data/node_modules/freezerwatch/node_modules/async/component.json +17 -0
  37. data/node_modules/freezerwatch/node_modules/async/coverage/base.css +182 -0
  38. data/node_modules/freezerwatch/node_modules/async/coverage/index.html +73 -0
  39. data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/base.css +182 -0
  40. data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/index.html +73 -0
  41. data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/lib/async.js.html +3900 -0
  42. data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/lib/index.html +73 -0
  43. data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/prettify.css +1 -0
  44. data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/prettify.js +1 -0
  45. data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  46. data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/sorter.js +156 -0
  47. data/node_modules/freezerwatch/node_modules/async/coverage/lcov.info +1452 -0
  48. data/node_modules/freezerwatch/node_modules/async/coverage/lib/async.js.html +3597 -0
  49. data/node_modules/freezerwatch/node_modules/async/coverage/lib/index.html +73 -0
  50. data/node_modules/freezerwatch/node_modules/async/coverage/prettify.css +1 -0
  51. data/node_modules/freezerwatch/node_modules/async/coverage/prettify.js +1 -0
  52. data/node_modules/freezerwatch/node_modules/async/coverage/sort-arrow-sprite.png +0 -0
  53. data/node_modules/freezerwatch/node_modules/async/coverage/sorter.js +156 -0
  54. data/node_modules/freezerwatch/node_modules/async/lib/async.js +1191 -0
  55. data/node_modules/freezerwatch/node_modules/async/nyc_output/5074.json +1 -0
  56. data/node_modules/freezerwatch/node_modules/async/package.json +96 -0
  57. data/node_modules/freezerwatch/node_modules/async/support/sync-package-managers.js +53 -0
  58. data/node_modules/freezerwatch/node_modules/lacrosse/.npmignore +15 -0
  59. data/node_modules/freezerwatch/node_modules/lacrosse/Client.js +60 -0
  60. data/node_modules/freezerwatch/node_modules/lacrosse/Device.js +38 -0
  61. data/node_modules/freezerwatch/node_modules/lacrosse/DeviceRawReadStream.js +36 -0
  62. data/node_modules/freezerwatch/node_modules/lacrosse/DeviceSingleRawReadStream.js +29 -0
  63. data/node_modules/freezerwatch/node_modules/lacrosse/DeviceStream.js +35 -0
  64. data/node_modules/freezerwatch/node_modules/lacrosse/LICENSE +23 -0
  65. data/node_modules/freezerwatch/node_modules/lacrosse/README.md +25 -0
  66. data/node_modules/freezerwatch/node_modules/lacrosse/index.js +1 -0
  67. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/.npmignore +2 -0
  68. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/.travis.yml +12 -0
  69. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/LICENSE +55 -0
  70. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/README.md +364 -0
  71. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/index.js +156 -0
  72. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/lib/copy.js +8 -0
  73. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/lib/debug.js +7 -0
  74. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/lib/getSafe.js +34 -0
  75. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/lib/optional.js +5 -0
  76. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/.bin/uuid +26 -0
  77. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/aws-sign2/LICENSE +55 -0
  78. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/aws-sign2/README.md +4 -0
  79. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/aws-sign2/index.js +202 -0
  80. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/aws-sign2/package.json +46 -0
  81. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/forever-agent/LICENSE +55 -0
  82. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/forever-agent/README.md +4 -0
  83. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/forever-agent/index.js +119 -0
  84. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/forever-agent/package.json +45 -0
  85. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/License +19 -0
  86. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/Readme.md +175 -0
  87. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/lib/form_data.js +351 -0
  88. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/.travis.yml +5 -0
  89. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/LICENSE +19 -0
  90. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/README.md +1647 -0
  91. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/bower.json +38 -0
  92. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/component.json +16 -0
  93. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js +1123 -0
  94. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/package.json +84 -0
  95. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/support/sync-package-managers.js +53 -0
  96. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/License +19 -0
  97. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md +132 -0
  98. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js +188 -0
  99. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore +2 -0
  100. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License +19 -0
  101. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile +7 -0
  102. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md +154 -0
  103. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js +99 -0
  104. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json +42 -0
  105. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js +6 -0
  106. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js +38 -0
  107. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js +21 -0
  108. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js +14 -0
  109. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js +48 -0
  110. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js +15 -0
  111. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js +18 -0
  112. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js +13 -0
  113. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js +13 -0
  114. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js +7 -0
  115. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json +60 -0
  116. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/package.json +80 -0
  117. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/.npmignore +18 -0
  118. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/.travis.yml +5 -0
  119. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/LICENSE +24 -0
  120. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/Makefile +10 -0
  121. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/README.md +627 -0
  122. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/example/usage.js +78 -0
  123. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/images/hawk.png +0 -0
  124. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/images/logo.png +0 -0
  125. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/index.js +1 -0
  126. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/browser.js +485 -0
  127. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/client.js +367 -0
  128. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/crypto.js +111 -0
  129. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/index.js +15 -0
  130. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/server.js +524 -0
  131. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/utils.js +183 -0
  132. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/.npmignore +18 -0
  133. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/.travis.yml +5 -0
  134. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/LICENSE +24 -0
  135. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/Makefile +11 -0
  136. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/README.md +6 -0
  137. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/images/boom.png +0 -0
  138. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/index.js +1 -0
  139. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/lib/index.js +207 -0
  140. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/package.json +64 -0
  141. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/test/index.js +245 -0
  142. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/.npmignore +18 -0
  143. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/.travis.yml +5 -0
  144. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/LICENSE +24 -0
  145. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/Makefile +11 -0
  146. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/README.md +6 -0
  147. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/index.js +1 -0
  148. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/lib/index.js +68 -0
  149. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/package.json +65 -0
  150. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/test/index.js +101 -0
  151. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/.npmignore +18 -0
  152. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/.travis.yml +5 -0
  153. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/LICENSE +33 -0
  154. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/Makefile +10 -0
  155. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/README.md +436 -0
  156. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/images/hoek.png +0 -0
  157. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/index.js +1 -0
  158. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/lib/escape.js +132 -0
  159. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/lib/index.js +585 -0
  160. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/package.json +70 -0
  161. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/escaper.js +86 -0
  162. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/index.js +1078 -0
  163. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test1.js +1 -0
  164. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test2.js +1 -0
  165. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test3.js +1 -0
  166. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/.npmignore +18 -0
  167. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/.travis.yml +5 -0
  168. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/LICENSE +24 -0
  169. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/Makefile +11 -0
  170. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/README.md +68 -0
  171. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/examples/offset.js +16 -0
  172. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/examples/time.js +25 -0
  173. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/index.js +1 -0
  174. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js +409 -0
  175. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/package.json +65 -0
  176. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/test/index.js +359 -0
  177. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/package.json +70 -0
  178. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/browser.js +771 -0
  179. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/client.js +206 -0
  180. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/crypto.js +86 -0
  181. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/index.js +316 -0
  182. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/message.js +246 -0
  183. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/readme.js +98 -0
  184. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/server.js +686 -0
  185. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/uri.js +456 -0
  186. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/utils.js +120 -0
  187. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/.dir-locals.el +6 -0
  188. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/.npmignore +7 -0
  189. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/LICENSE +18 -0
  190. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/README.md +79 -0
  191. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/http_signing.md +296 -0
  192. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/index.js +26 -0
  193. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/parser.js +304 -0
  194. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/signer.js +178 -0
  195. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/util.js +304 -0
  196. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/verify.js +42 -0
  197. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/.npmignore +2 -0
  198. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/LICENSE +19 -0
  199. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/README.md +50 -0
  200. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/errors.js +13 -0
  201. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/index.js +27 -0
  202. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/reader.js +267 -0
  203. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/types.js +36 -0
  204. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/writer.js +317 -0
  205. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/index.js +20 -0
  206. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/package.json +63 -0
  207. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/tst/ber/reader.test.js +172 -0
  208. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/tst/ber/writer.test.js +296 -0
  209. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/assert-plus/README.md +126 -0
  210. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/assert-plus/assert.js +245 -0
  211. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/assert-plus/package.json +45 -0
  212. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/.npmignore +1 -0
  213. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/CHANGELOG +78 -0
  214. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/LICENSE +24 -0
  215. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/README +82 -0
  216. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/README.old +298 -0
  217. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/ctf.js +245 -0
  218. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/ctio.js +1485 -0
  219. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/ctype.js +944 -0
  220. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/man/man3ctype/ctio.3ctype +241 -0
  221. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/package.json +42 -0
  222. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/tools/jsl.conf +129 -0
  223. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/tools/jsstyle +839 -0
  224. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/package.json +72 -0
  225. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/.npmignore +1 -0
  226. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/CHANGELOG.md +14 -0
  227. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/LICENSE +15 -0
  228. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/Makefile +35 -0
  229. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/README.md +52 -0
  230. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/package.json +68 -0
  231. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/stringify.js +27 -0
  232. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/test/mocha.opts +2 -0
  233. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/test/stringify_test.js +246 -0
  234. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/LICENSE +19 -0
  235. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/README.md +66 -0
  236. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/mime.js +114 -0
  237. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/package.json +57 -0
  238. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/test.js +84 -0
  239. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/types/mime.types +1588 -0
  240. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/types/node.types +77 -0
  241. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/.npmignore +2 -0
  242. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/LICENSE.md +21 -0
  243. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/README.md +243 -0
  244. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/README.md +53 -0
  245. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu +174 -0
  246. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/bench.sh +34 -0
  247. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c +34 -0
  248. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js +84 -0
  249. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/bin/uuid +26 -0
  250. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/bower.json +23 -0
  251. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/component.json +18 -0
  252. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/package.json +65 -0
  253. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/test/compare_v1.js +63 -0
  254. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/test/test.html +17 -0
  255. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/test/test.js +228 -0
  256. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/uuid.js +247 -0
  257. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/LICENSE +55 -0
  258. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/README.md +4 -0
  259. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/index.js +43 -0
  260. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/package.json +48 -0
  261. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/test.js +49 -0
  262. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/.gitmodules +6 -0
  263. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/.npmignore +7 -0
  264. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/Readme.md +58 -0
  265. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/index.js +366 -0
  266. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/package.json +55 -0
  267. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/.jshintrc +72 -0
  268. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/.npmignore +3 -0
  269. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/LICENSE +78 -0
  270. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/README.md +380 -0
  271. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/generate-pubsuffix.js +230 -0
  272. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/lib/cookie.js +947 -0
  273. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/lib/memstore.js +102 -0
  274. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/lib/pubsuffix.js +69 -0
  275. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/node_modules/punycode/LICENSE-MIT.txt +20 -0
  276. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/node_modules/punycode/README.md +176 -0
  277. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/node_modules/punycode/package.json +81 -0
  278. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/node_modules/punycode/punycode.js +530 -0
  279. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/package.json +63 -0
  280. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/public-suffix.txt +5229 -0
  281. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/test.js +1340 -0
  282. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tunnel-agent/LICENSE +55 -0
  283. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tunnel-agent/README.md +4 -0
  284. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tunnel-agent/index.js +227 -0
  285. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tunnel-agent/package.json +45 -0
  286. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/package.json +74 -0
  287. data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/request.js +1244 -0
  288. data/node_modules/freezerwatch/node_modules/lacrosse/package.json +34 -0
  289. data/node_modules/freezerwatch/node_modules/optparse/README.md +163 -0
  290. data/node_modules/freezerwatch/node_modules/optparse/TODO +1 -0
  291. data/node_modules/freezerwatch/node_modules/optparse/examples/browser-test.html +75 -0
  292. data/node_modules/freezerwatch/node_modules/optparse/examples/nodejs-test.js +86 -0
  293. data/node_modules/freezerwatch/node_modules/optparse/lib/optparse.js +309 -0
  294. data/node_modules/freezerwatch/node_modules/optparse/package.json +46 -0
  295. data/node_modules/freezerwatch/node_modules/optparse/seed.yml +5 -0
  296. data/node_modules/freezerwatch/node_modules/osenv/.npmignore +13 -0
  297. data/node_modules/freezerwatch/node_modules/osenv/.travis.yml +9 -0
  298. data/node_modules/freezerwatch/node_modules/osenv/LICENSE +15 -0
  299. data/node_modules/freezerwatch/node_modules/osenv/README.md +63 -0
  300. data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-homedir/index.js +24 -0
  301. data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-homedir/license +21 -0
  302. data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-homedir/package.json +70 -0
  303. data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-homedir/readme.md +33 -0
  304. data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-tmpdir/index.js +25 -0
  305. data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-tmpdir/license +21 -0
  306. data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-tmpdir/package.json +70 -0
  307. data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-tmpdir/readme.md +36 -0
  308. data/node_modules/freezerwatch/node_modules/osenv/osenv.js +72 -0
  309. data/node_modules/freezerwatch/node_modules/osenv/package.json +76 -0
  310. data/node_modules/freezerwatch/node_modules/osenv/test/unix.js +71 -0
  311. data/node_modules/freezerwatch/node_modules/osenv/test/windows.js +74 -0
  312. data/node_modules/freezerwatch/node_modules/osenv/x.tap +39 -0
  313. data/node_modules/freezerwatch/package.json +37 -0
  314. metadata +384 -0
@@ -0,0 +1,15 @@
1
+ var common = require('../common');
2
+ var assert = common.assert;
3
+ var fake = common.fake.create();
4
+ var DelayedStream = common.DelayedStream;
5
+ var Stream = require('stream').Stream;
6
+
7
+ (function testHandleSourceErrors() {
8
+ var source = new Stream();
9
+ var delayedStream = DelayedStream.create(source, {pauseStream: false});
10
+
11
+ // We deal with this by attaching a no-op listener to 'error' on the source
12
+ // when creating a new DelayedStream. This way error events on the source
13
+ // won't throw.
14
+ source.emit('error', new Error('something went wrong'));
15
+ })();
@@ -0,0 +1,18 @@
1
+ var common = require('../common');
2
+ var assert = common.assert;
3
+ var fake = common.fake.create();
4
+ var DelayedStream = common.DelayedStream;
5
+ var Stream = require('stream').Stream;
6
+
7
+ (function testMaxDataSize() {
8
+ var source = new Stream();
9
+ var delayedStream = DelayedStream.create(source, {maxDataSize: 1024, pauseStream: false});
10
+
11
+ source.emit('data', new Buffer(1024));
12
+
13
+ fake
14
+ .expect(delayedStream, 'emit')
15
+ .withArg(1, 'error');
16
+ source.emit('data', new Buffer(1));
17
+ fake.verify();
18
+ })();
@@ -0,0 +1,13 @@
1
+ var common = require('../common');
2
+ var assert = common.assert;
3
+ var fake = common.fake.create();
4
+ var DelayedStream = common.DelayedStream;
5
+ var Stream = require('stream').Stream;
6
+
7
+ (function testPipeReleases() {
8
+ var source = new Stream();
9
+ var delayedStream = DelayedStream.create(source, {pauseStream: false});
10
+
11
+ fake.expect(delayedStream, 'resume');
12
+ delayedStream.pipe(new Stream());
13
+ })();
@@ -0,0 +1,13 @@
1
+ var common = require('../common');
2
+ var assert = common.assert;
3
+ var fake = common.fake.create();
4
+ var DelayedStream = common.DelayedStream;
5
+ var Stream = require('stream').Stream;
6
+
7
+ (function testProxyReadableProperty() {
8
+ var source = new Stream();
9
+ var delayedStream = DelayedStream.create(source, {pauseStream: false});
10
+
11
+ source.readable = fake.value('source.readable');
12
+ assert.strictEqual(delayedStream.readable, source.readable);
13
+ })();
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ var far = require('far').create();
3
+
4
+ far.add(__dirname);
5
+ far.include(/test-.*\.js$/);
6
+
7
+ far.execute();
@@ -0,0 +1,60 @@
1
+ {
2
+ "author": {
3
+ "name": "Felix Geisendörfer",
4
+ "email": "felix@debuggable.com",
5
+ "url": "http://debuggable.com/"
6
+ },
7
+ "name": "combined-stream",
8
+ "description": "A stream that emits multiple other streams one after another.",
9
+ "version": "0.0.7",
10
+ "homepage": "https://github.com/felixge/node-combined-stream",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git://github.com/felixge/node-combined-stream.git"
14
+ },
15
+ "main": "./lib/combined_stream",
16
+ "scripts": {
17
+ "test": "node test/run.js"
18
+ },
19
+ "engines": {
20
+ "node": ">= 0.8"
21
+ },
22
+ "dependencies": {
23
+ "delayed-stream": "0.0.5"
24
+ },
25
+ "devDependencies": {
26
+ "far": "~0.0.7"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/felixge/node-combined-stream/issues"
30
+ },
31
+ "_id": "combined-stream@0.0.7",
32
+ "dist": {
33
+ "shasum": "0137e657baa5a7541c57ac37ac5fc07d73b4dc1f",
34
+ "tarball": "http://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz"
35
+ },
36
+ "_from": "combined-stream@>=0.0.4 <0.1.0",
37
+ "_npmVersion": "1.4.3",
38
+ "_npmUser": {
39
+ "name": "felixge",
40
+ "email": "felix@debuggable.com"
41
+ },
42
+ "maintainers": [
43
+ {
44
+ "name": "felixge",
45
+ "email": "felix@debuggable.com"
46
+ },
47
+ {
48
+ "name": "celer",
49
+ "email": "celer@scrypt.net"
50
+ },
51
+ {
52
+ "name": "alexindigo",
53
+ "email": "iam@alexindigo.com"
54
+ }
55
+ ],
56
+ "directories": {},
57
+ "_shasum": "0137e657baa5a7541c57ac37ac5fc07d73b4dc1f",
58
+ "_resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
59
+ "readme": "ERROR: No README data found!"
60
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "author": {
3
+ "name": "Felix Geisendörfer",
4
+ "email": "felix@debuggable.com",
5
+ "url": "http://debuggable.com/"
6
+ },
7
+ "name": "form-data",
8
+ "description": "A module to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.",
9
+ "version": "0.1.4",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git://github.com/felixge/node-form-data.git"
13
+ },
14
+ "main": "./lib/form_data",
15
+ "scripts": {
16
+ "test": "node test/run.js"
17
+ },
18
+ "engines": {
19
+ "node": ">= 0.8"
20
+ },
21
+ "dependencies": {
22
+ "combined-stream": "~0.0.4",
23
+ "mime": "~1.2.11",
24
+ "async": "~0.9.0"
25
+ },
26
+ "licenses": [
27
+ {
28
+ "type": "MIT",
29
+ "url": "https://raw.github.com/felixge/node-form-data/master/License"
30
+ }
31
+ ],
32
+ "devDependencies": {
33
+ "fake": "~0.2.2",
34
+ "far": "~0.0.7",
35
+ "formidable": "~1.0.14",
36
+ "request": "~2.36.0"
37
+ },
38
+ "gitHead": "5f5f4809ea685f32658809fa0f13d7eface0e45a",
39
+ "bugs": {
40
+ "url": "https://github.com/felixge/node-form-data/issues"
41
+ },
42
+ "homepage": "https://github.com/felixge/node-form-data",
43
+ "_id": "form-data@0.1.4",
44
+ "_shasum": "91abd788aba9702b1aabfa8bc01031a2ac9e3b12",
45
+ "_from": "form-data@>=0.1.0 <0.2.0",
46
+ "_npmVersion": "1.4.14",
47
+ "_npmUser": {
48
+ "name": "alexindigo",
49
+ "email": "iam@alexindigo.com"
50
+ },
51
+ "maintainers": [
52
+ {
53
+ "name": "felixge",
54
+ "email": "felix@debuggable.com"
55
+ },
56
+ {
57
+ "name": "idralyuk",
58
+ "email": "igor@buran.us"
59
+ },
60
+ {
61
+ "name": "alexindigo",
62
+ "email": "iam@alexindigo.com"
63
+ },
64
+ {
65
+ "name": "mikeal",
66
+ "email": "mikeal.rogers@gmail.com"
67
+ },
68
+ {
69
+ "name": "celer",
70
+ "email": "dtyree77@gmail.com"
71
+ }
72
+ ],
73
+ "dist": {
74
+ "shasum": "91abd788aba9702b1aabfa8bc01031a2ac9e3b12",
75
+ "tarball": "http://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz"
76
+ },
77
+ "directories": {},
78
+ "_resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz",
79
+ "readme": "ERROR: No README data found!"
80
+ }
@@ -0,0 +1,18 @@
1
+ .idea
2
+ *.iml
3
+ npm-debug.log
4
+ dump.rdb
5
+ node_modules
6
+ results.tap
7
+ results.xml
8
+ npm-shrinkwrap.json
9
+ config.json
10
+ .DS_Store
11
+ */.DS_Store
12
+ */*/.DS_Store
13
+ ._*
14
+ */._*
15
+ */*/._*
16
+ coverage.*
17
+ lib-cov
18
+
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2012-2013, Eran Hammer.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of Eran Hammer nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL ERAN HAMMER BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,10 @@
1
+ test:
2
+ @node node_modules/lab/bin/lab
3
+ test-cov:
4
+ @node node_modules/lab/bin/lab -r threshold -t 100
5
+ test-cov-html:
6
+ @node node_modules/lab/bin/lab -r html -o coverage.html
7
+ complexity:
8
+ @node node_modules/complexity-report/src/cli.js -o complexity.md -f markdown lib
9
+
10
+ .PHONY: test test-cov test-cov-html complexity
@@ -0,0 +1,627 @@
1
+ ![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png)
2
+
3
+ <img align="right" src="https://raw.github.com/hueniverse/hawk/master/images/logo.png" /> **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial
4
+ HTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz).
5
+
6
+ Current version: **1.0**
7
+
8
+ [![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk)
9
+
10
+ # Table of Content
11
+
12
+ - [**Introduction**](#introduction)
13
+ - [Replay Protection](#replay-protection)
14
+ - [Usage Example](#usage-example)
15
+ - [Protocol Example](#protocol-example)
16
+ - [Payload Validation](#payload-validation)
17
+ - [Response Payload Validation](#response-payload-validation)
18
+ - [Browser Support and Considerations](#browser-support-and-considerations)
19
+ <p></p>
20
+ - [**Single URI Authorization**](#single-uri-authorization)
21
+ - [Usage Example](#bewit-usage-example)
22
+ <p></p>
23
+ - [**Security Considerations**](#security-considerations)
24
+ - [MAC Keys Transmission](#mac-keys-transmission)
25
+ - [Confidentiality of Requests](#confidentiality-of-requests)
26
+ - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers)
27
+ - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)
28
+ - [Entropy of Keys](#entropy-of-keys)
29
+ - [Coverage Limitations](#coverage-limitations)
30
+ - [Future Time Manipulation](#future-time-manipulation)
31
+ - [Client Clock Poisoning](#client-clock-poisoning)
32
+ - [Bewit Limitations](#bewit-limitations)
33
+ - [Host Header Forgery](#host-header-forgery)
34
+ <p></p>
35
+ - [**Frequently Asked Questions**](#frequently-asked-questions)
36
+ <p></p>
37
+ - [**Acknowledgements**](#acknowledgements)
38
+
39
+ # Introduction
40
+
41
+ **Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with
42
+ partial cryptographic verification of the request and response, covering the HTTP method, request URI, host,
43
+ and optionally the request payload.
44
+
45
+ Similar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of
46
+ client credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme,
47
+ the key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is
48
+ included in its place.
49
+
50
+ However, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of
51
+ replay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less
52
+ "chattiness" (interaction with the server).
53
+
54
+ Also unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because
55
+ the client and server must both have access to the key material in the clear.
56
+
57
+ The primary design goals of this scheme are to:
58
+ * simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources,
59
+ * secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where
60
+ to send an authenticated request), and
61
+ * avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client
62
+ failure to validate the server's identity as part of its TLS handshake.
63
+
64
+ In addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using
65
+ a query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk).
66
+
67
+ The **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server,
68
+ which is beyond the scope of this module. Typically, the shared credentials are established via an initial
69
+ TLS-protected phase or derived from some other shared confidential information available to both the client
70
+ and the server.
71
+
72
+
73
+ ## Replay Protection
74
+
75
+ Without replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more
76
+ than once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when
77
+ making requests. This gives the server enough information to prevent replay attacks.
78
+
79
+ The nonce is generated by the client, and is a string unique across all requests with the same timestamp and
80
+ key identifier combination.
81
+
82
+ The timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards
83
+ are rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks.
84
+ By default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in
85
+ practice translates to a maximum of 2 minutes as the skew can be positive or negative).
86
+
87
+ Using a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client
88
+ clock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types
89
+ (e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response
90
+ to a bad timestamp.
91
+
92
+ There is no expectation that the client will adjust its system clock to match the server (in fact, this would be a
93
+ potential attack vector). Instead, the client only uses the server's time to calculate an offset used only
94
+ for communications with that particular server. The protocol rewards clients with synchronized clocks by reducing
95
+ the number of round trips required to authenticate the first request.
96
+
97
+
98
+ ## Usage Example
99
+
100
+ Server code:
101
+
102
+ ```javascript
103
+ var Http = require('http');
104
+ var Hawk = require('hawk');
105
+
106
+
107
+ // Credentials lookup function
108
+
109
+ var credentialsFunc = function (id, callback) {
110
+
111
+ var credentials = {
112
+ key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
113
+ algorithm: 'sha256',
114
+ user: 'Steve'
115
+ };
116
+
117
+ return callback(null, credentials);
118
+ };
119
+
120
+ // Create HTTP server
121
+
122
+ var handler = function (req, res) {
123
+
124
+ // Authenticate incoming request
125
+
126
+ Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
127
+
128
+ // Prepare response
129
+
130
+ var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!');
131
+ var headers = { 'Content-Type': 'text/plain' };
132
+
133
+ // Generate Server-Authorization response header
134
+
135
+ var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] });
136
+ headers['Server-Authorization'] = header;
137
+
138
+ // Send the response back
139
+
140
+ res.writeHead(!err ? 200 : 401, headers);
141
+ res.end(payload);
142
+ });
143
+ };
144
+
145
+ // Start server
146
+
147
+ Http.createServer(handler).listen(8000, 'example.com');
148
+ ```
149
+
150
+ Client code:
151
+
152
+ ```javascript
153
+ var Request = require('request');
154
+ var Hawk = require('hawk');
155
+
156
+
157
+ // Client credentials
158
+
159
+ var credentials = {
160
+ id: 'dh37fgj492je',
161
+ key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
162
+ algorithm: 'sha256'
163
+ }
164
+
165
+ // Request options
166
+
167
+ var requestOptions = {
168
+ uri: 'http://example.com:8000/resource/1?b=1&a=2',
169
+ method: 'GET',
170
+ headers: {}
171
+ };
172
+
173
+ // Generate Authorization request header
174
+
175
+ var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });
176
+ requestOptions.headers.Authorization = header.field;
177
+
178
+ // Send authenticated request
179
+
180
+ Request(requestOptions, function (error, response, body) {
181
+
182
+ // Authenticate the server's response
183
+
184
+ var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body });
185
+
186
+ // Output results
187
+
188
+ console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)'));
189
+ });
190
+ ```
191
+
192
+ **Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local
193
+ machine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method.
194
+
195
+ ```javascript
196
+ Hawk.sntp.start();
197
+ ```
198
+
199
+
200
+ ## Protocol Example
201
+
202
+ The client attempts to access a protected resource without authentication, sending the following HTTP request to
203
+ the resource server:
204
+
205
+ ```
206
+ GET /resource/1?b=1&a=2 HTTP/1.1
207
+ Host: example.com:8000
208
+ ```
209
+
210
+ The resource server returns an authentication challenge.
211
+
212
+ ```
213
+ HTTP/1.1 401 Unauthorized
214
+ WWW-Authenticate: Hawk
215
+ ```
216
+
217
+ The client has previously obtained a set of **Hawk** credentials for accessing resources on the "http://example.com/"
218
+ server. The **Hawk** credentials issued to the client include the following attributes:
219
+
220
+ * Key identifier: dh37fgj492je
221
+ * Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn
222
+ * Algorithm: sha256
223
+
224
+ The client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1,
225
+ 1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline
226
+ character):
227
+
228
+ ```
229
+ hawk.1.header
230
+ 1353832234
231
+ j4h3g2
232
+ GET
233
+ /resource/1?b=1&a=2
234
+ example.com
235
+ 8000
236
+
237
+ some-app-ext-data
238
+
239
+ ```
240
+
241
+ The request MAC is calculated using HMAC with the specified hash algorithm "sha256" and the key over the normalized request string.
242
+ The result is base64-encoded to produce the request MAC:
243
+
244
+ ```
245
+ 6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=
246
+ ```
247
+
248
+ The client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using
249
+ the HTTP `Authorization` request header field:
250
+
251
+ ```
252
+ GET /resource/1?b=1&a=2 HTTP/1.1
253
+ Host: example.com:8000
254
+ Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="
255
+ ```
256
+
257
+ The server validates the request by calculating the request MAC again based on the request received and verifies the validity
258
+ and scope of the **Hawk** credentials. If valid, the server responds with the requested resource.
259
+
260
+
261
+ ### Payload Validation
262
+
263
+ **Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash
264
+ using the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character):
265
+ * `hawk.1.payload`
266
+ * the content-type in lowercase, without any parameters (e.g. `application/json`)
267
+ * the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability)
268
+
269
+ For example:
270
+
271
+ * Payload: `Thank you for flying Hawk`
272
+ * Content Type: `text/plain`
273
+ * Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=`
274
+
275
+ Results in the following input to the payload hash function (newline terminated values):
276
+
277
+ ```
278
+ hawk.1.payload
279
+ text/plain
280
+ Thank you for flying Hawk
281
+
282
+ ```
283
+
284
+ Which produces the following hash value:
285
+
286
+ ```
287
+ Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=
288
+ ```
289
+
290
+ The client constructs the normalized request string (newline terminated values):
291
+
292
+ ```
293
+ hawk.1.header
294
+ 1353832234
295
+ j4h3g2
296
+ POST
297
+ /resource/1?a=1&b=2
298
+ example.com
299
+ 8000
300
+ Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=
301
+ some-app-ext-data
302
+
303
+ ```
304
+
305
+ Then calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data,
306
+ and request MAC, with the request using the HTTP `Authorization` request header field:
307
+
308
+ ```
309
+ POST /resource/1?a=1&b=2 HTTP/1.1
310
+ Host: example.com:8000
311
+ Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw="
312
+ ```
313
+
314
+ It is up to the server if and when it validates the payload for any given request, based solely on it's security policy
315
+ and the nature of the data included.
316
+
317
+ If the payload is available at the time of authentication, the server uses the hash value provided by the client to construct
318
+ the normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value
319
+ with the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash.
320
+
321
+ However, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed
322
+ at a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value
323
+ provided by the client after validating the MAC.
324
+
325
+ It is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value
326
+ included in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided
327
+ by the client, the payload may be modified by an attacker.
328
+
329
+
330
+ ## Response Payload Validation
331
+
332
+ **Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the
333
+ client to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header
334
+ as a response header using the exact same syntax as the `Authorization` request header field.
335
+
336
+ The header is contructed using the same process as the client's request header. The server uses the same credentials and other
337
+ artifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with
338
+ new values based on the server response. The rest as identical to those used by the client.
339
+
340
+ The result MAC digest is included with the optional `hash` and `ext` values:
341
+
342
+ ```
343
+ Server-Authorization: Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"
344
+ ```
345
+
346
+
347
+ ## Browser Support and Considerations
348
+
349
+ A browser script is provided for including using a `<script>` tag in [lib/browser.js](/lib/browser.js).
350
+
351
+ **Hawk** relies on the _Server-Authorization_ and _WWW-Authenticate_ headers in its response to communicate with the client.
352
+ Therefore, in case of CORS requests, it is important to consider sending _Access-Control-Expose-Headers_ with the value
353
+ _"WWW-Authenticate, Server-Authorization"_ on each response from your server. As explained in the
354
+ [specifications](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header), it will indicate that these headers
355
+ can safely be accessed by the client (using getResponseHeader() on the XmlHttpRequest object). Otherwise you will be met with a
356
+ ["simple response header"](http://www.w3.org/TR/cors/#simple-response-header) which excludes these fields and would prevent the
357
+ Hawk client from authenticating the requests.You can read more about the why and how in this
358
+ [article](http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server)
359
+
360
+
361
+ # Single URI Authorization
362
+
363
+ There are cases in which limited and short-term access to a protected resource is granted to a third party which does not
364
+ have access to the shared credentials. For example, displaying a protected image on a web page accessed by anyone. **Hawk**
365
+ provides limited support for such URIs in the form of a _bewit_ - a URI query parameter appended to the request URI which contains
366
+ the necessary credentials to authenticate the request.
367
+
368
+ Because of the significant security risks involved in issuing such access, bewit usage is purposely limited only to GET requests
369
+ and for a finite period of time. Both the client and server can issue bewit credentials, however, the server should not use the same
370
+ credentials as the client to maintain clear traceability as to who issued which credentials.
371
+
372
+ In order to simplify implementation, bewit credentials do not support single-use policy and can be replayed multiple times within
373
+ the granted access timeframe.
374
+
375
+
376
+ ## Bewit Usage Example
377
+
378
+ Server code:
379
+
380
+ ```javascript
381
+ var Http = require('http');
382
+ var Hawk = require('hawk');
383
+
384
+
385
+ // Credentials lookup function
386
+
387
+ var credentialsFunc = function (id, callback) {
388
+
389
+ var credentials = {
390
+ key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
391
+ algorithm: 'sha256'
392
+ };
393
+
394
+ return callback(null, credentials);
395
+ };
396
+
397
+ // Create HTTP server
398
+
399
+ var handler = function (req, res) {
400
+
401
+ Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
402
+
403
+ res.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' });
404
+ res.end(!err ? 'Access granted' : 'Shoosh!');
405
+ });
406
+ };
407
+
408
+ Http.createServer(handler).listen(8000, 'example.com');
409
+ ```
410
+
411
+ Bewit code generation:
412
+
413
+ ```javascript
414
+ var Request = require('request');
415
+ var Hawk = require('hawk');
416
+
417
+
418
+ // Client credentials
419
+
420
+ var credentials = {
421
+ id: 'dh37fgj492je',
422
+ key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
423
+ algorithm: 'sha256'
424
+ }
425
+
426
+ // Generate bewit
427
+
428
+ var duration = 60 * 5; // 5 Minutes
429
+ var bewit = Hawk.uri.getBewit('http://example.com:8080/resource/1?b=1&a=2', { credentials: credentials, ttlSec: duration, ext: 'some-app-data' });
430
+ var uri = 'http://example.com:8000/resource/1?b=1&a=2' + '&bewit=' + bewit;
431
+ ```
432
+
433
+
434
+ # Security Considerations
435
+
436
+ The greatest sources of security risks are usually found not in **Hawk** but in the policies and procedures surrounding its use.
437
+ Implementers are strongly encouraged to assess how this module addresses their security requirements. This section includes
438
+ an incomplete list of security considerations that must be reviewed and understood before deploying **Hawk** on the server.
439
+ Many of the protections provided in **Hawk** depends on whether and how they are used.
440
+
441
+ ### MAC Keys Transmission
442
+
443
+ **Hawk** does not provide any mechanism for obtaining or transmitting the set of shared credentials required. Any mechanism used
444
+ to obtain **Hawk** credentials must ensure that these transmissions are protected using transport-layer mechanisms such as TLS.
445
+
446
+ ### Confidentiality of Requests
447
+
448
+ While **Hawk** provides a mechanism for verifying the integrity of HTTP requests, it provides no guarantee of request
449
+ confidentiality. Unless other precautions are taken, eavesdroppers will have full access to the request content. Servers should
450
+ carefully consider the types of data likely to be sent as part of such requests, and employ transport-layer security mechanisms
451
+ to protect sensitive resources.
452
+
453
+ ### Spoofing by Counterfeit Servers
454
+
455
+ **Hawk** provides limited verification of the server authenticity. When receiving a response back from the server, the server
456
+ may choose to include a response `Server-Authorization` header which the client can use to verify the response. However, it is up to
457
+ the server to determine when such measure is included, to up to the client to enforce that policy.
458
+
459
+ A hostile party could take advantage of this by intercepting the client's requests and returning misleading or otherwise
460
+ incorrect responses. Service providers should consider such attacks when developing services using this protocol, and should
461
+ require transport-layer security for any requests where the authenticity of the resource server or of server responses is an issue.
462
+
463
+ ### Plaintext Storage of Credentials
464
+
465
+ The **Hawk** key functions the same way passwords do in traditional authentication systems. In order to compute the request MAC,
466
+ the server must have access to the key in plaintext form. This is in contrast, for example, to modern operating systems, which
467
+ store only a one-way hash of user credentials.
468
+
469
+ If an attacker were to gain access to these keys - or worse, to the server's database of all such keys - he or she would be able
470
+ to perform any action on behalf of any resource owner. Accordingly, it is critical that servers protect these keys from unauthorized
471
+ access.
472
+
473
+ ### Entropy of Keys
474
+
475
+ Unless a transport-layer security protocol is used, eavesdroppers will have full access to authenticated requests and request
476
+ MAC values, and will thus be able to mount offline brute-force attacks to recover the key used. Servers should be careful to
477
+ assign keys which are long enough, and random enough, to resist such attacks for at least the length of time that the **Hawk**
478
+ credentials are valid.
479
+
480
+ For example, if the credentials are valid for two weeks, servers should ensure that it is not possible to mount a brute force
481
+ attack that recovers the key in less than two weeks. Of course, servers are urged to err on the side of caution, and use the
482
+ longest key reasonable.
483
+
484
+ It is equally important that the pseudo-random number generator (PRNG) used to generate these keys be of sufficiently high
485
+ quality. Many PRNG implementations generate number sequences that may appear to be random, but which nevertheless exhibit
486
+ patterns or other weaknesses which make cryptanalysis or brute force attacks easier. Implementers should be careful to use
487
+ cryptographically secure PRNGs to avoid these problems.
488
+
489
+ ### Coverage Limitations
490
+
491
+ The request MAC only covers the HTTP `Host` header and optionally the `Content-Type` header. It does not cover any other headers
492
+ which can often affect how the request body is interpreted by the server. If the server behavior is influenced by the presence
493
+ or value of such headers, an attacker can manipulate the request headers without being detected. Implementers should use the
494
+ `ext` feature to pass application-specific information via the `Authorization` header which is protected by the request MAC.
495
+
496
+ The response authentication, when performed, only covers the response payload, content-type, and the request information
497
+ provided by the client in it's request (method, resource, timestamp, nonce, etc.). It does not cover the HTTP status code or
498
+ any other response header field (e.g. Location) which can affect the client's behaviour.
499
+
500
+ ### Future Time Manipulation
501
+
502
+ The protocol relies on a clock sync between the client and server. To accomplish this, the server informs the client of its
503
+ current time when an invalid timestamp is received.
504
+
505
+ If an attacker is able to manipulate this information and cause the client to use an incorrect time, it would be able to cause
506
+ the client to generate authenticated requests using time in the future. Such requests will fail when sent by the client, and will
507
+ not likely leave a trace on the server (given the common implementation of nonce, if at all enforced). The attacker will then
508
+ be able to replay the request at the correct time without detection.
509
+
510
+ The client must only use the time information provided by the server if:
511
+ * it was delivered over a TLS connection and the server identity has been verified, or
512
+ * the `tsm` MAC digest calculated using the same client credentials over the timestamp has been verified.
513
+
514
+ ### Client Clock Poisoning
515
+
516
+ When receiving a request with a bad timestamp, the server provides the client with its current time. The client must never use
517
+ the time received from the server to adjust its own clock, and must only use it to calculate an offset for communicating with
518
+ that particular server.
519
+
520
+ ### Bewit Limitations
521
+
522
+ Special care must be taken when issuing bewit credentials to third parties. Bewit credentials are valid until expiration and cannot
523
+ be revoked or limited without using other means. Whatever resource they grant access to will be completely exposed to anyone with
524
+ access to the bewit credentials which act as bearer credentials for that particular resource. While bewit usage is limited to GET
525
+ requests only and therefore cannot be used to perform transactions or change server state, it can still be used to expose private
526
+ and sensitive information.
527
+
528
+ ### Host Header Forgery
529
+
530
+ Hawk validates the incoming request MAC against the incoming HTTP Host header. However, unless the optional `host` and `port`
531
+ options are used with `server.authenticate()`, a malicous client can mint new host names pointing to the server's IP address and
532
+ use that to craft an attack by sending a valid request that's meant for another hostname than the one used by the server. Server
533
+ implementors must manually verify that the host header received matches their expectation (or use the options mentioned above).
534
+
535
+ # Frequently Asked Questions
536
+
537
+ ### Where is the protocol specification?
538
+
539
+ If you are looking for some prose explaining how all this works, **this is it**. **Hawk** is being developed as an open source
540
+ project instead of a standard. In other words, the [code](/hueniverse/hawk/tree/master/lib) is the specification. Not sure about
541
+ something? Open an issue!
542
+
543
+ ### Is it done?
544
+
545
+ At if version 0.10.0, **Hawk** is feature-complete. However, until this module reaches version 1.0.0 it is considered experimental
546
+ and is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions
547
+ and suggestions.
548
+
549
+ ### Where can I find **Hawk** implementations in other languages?
550
+
551
+ **Hawk**'s only reference implementation is provided in JavaScript as a node.js module. However, others are actively porting it to other
552
+ platforms. There is already a [PHP](https://github.com/alexbilbie/PHP-Hawk),
553
+ [.NET](https://github.com/pcibraro/hawknet), and [JAVA](https://github.com/wealdtech/hawk) libraries available. The full list
554
+ is maintained [here](https://github.com/hueniverse/hawk/issues?labels=port). Please add an issue if you are working on another
555
+ port. A cross-platform test-suite is in the works.
556
+
557
+ ### Why isn't the algorithm part of the challenge or dynamically negotiated?
558
+
559
+ The algorithm used is closely related to the key issued as different algorithms require different key sizes (and other
560
+ requirements). While some keys can be used for multiple algorithm, the protocol is designed to closely bind the key and algorithm
561
+ together as part of the issued credentials.
562
+
563
+ ### Why is Host and Content-Type the only headers covered by the request MAC?
564
+
565
+ It is really hard to include other headers. Headers can be changed by proxies and other intermediaries and there is no
566
+ well-established way to normalize them. Many platforms change the case of header field names and values. The only
567
+ straight-forward solution is to include the headers in some blob (say, base64 encoded JSON) and include that with the request,
568
+ an approach taken by JWT and other such formats. However, that design violates the HTTP header boundaries, repeats information,
569
+ and introduces other security issues because firewalls will not be aware of these "hidden" headers. In addition, any information
570
+ repeated must be compared to the duplicated information in the header and therefore only moves the problem elsewhere.
571
+
572
+ ### Why not just use HTTP Digest?
573
+
574
+ Digest requires pre-negotiation to establish a nonce. This means you can't just make a request - you must first send
575
+ a protocol handshake to the server. This pattern has become unacceptable for most web services, especially mobile
576
+ where extra round-trip are costly.
577
+
578
+ ### Why bother with all this nonce and timestamp business?
579
+
580
+ **Hawk** is an attempt to find a reasonable, practical compromise between security and usability. OAuth 1.0 got timestamp
581
+ and nonces halfway right but failed when it came to scalability and consistent developer experience. **Hawk** addresses
582
+ it by requiring the client to sync its clock, but provides it with tools to accomplish it.
583
+
584
+ In general, replay protection is a matter of application-specific threat model. It is less of an issue on a TLS-protected
585
+ system where the clients are implemented using best practices and are under the control of the server. Instead of dropping
586
+ replay protection, **Hawk** offers a required time window and an optional nonce verification. Together, it provides developers
587
+ with the ability to decide how to enforce their security policy without impacting the client's implementation.
588
+
589
+ ### What are `app` and `dlg` in the authorization header and normalized mac string?
590
+
591
+ The original motivation for **Hawk** was to replace the OAuth 1.0 use cases. This included both a simple client-server mode which
592
+ this module is specifically designed for, and a delegated access mode which is being developed separately in
593
+ [Oz](https://github.com/hueniverse/oz). In addition to the **Hawk** use cases, Oz requires another attribute: the application id `app`.
594
+ This provides binding between the credentials and the application in a way that prevents an attacker from tricking an application
595
+ to use credentials issued to someone else. It also has an optional 'delegated-by' attribute `dlg` which is the application id of the
596
+ application the credentials were directly issued to. The goal of these two additions is to allow Oz to utilize **Hawk** directly,
597
+ but with the additional security of delegated credentials.
598
+
599
+ ### What is the purpose of the static strings used in each normalized MAC input?
600
+
601
+ When calculating a hash or MAC, a static prefix (tag) is added. The prefix is used to prevent MAC values from being
602
+ used or reused for a purpose other than what they were created for (i.e. prevents switching MAC values between a request,
603
+ response, and a bewit use cases). It also protects against expliots created after a potential change in how the protocol
604
+ creates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it
605
+ can create an exploit opportunity for cases where the nonce is similar in format to a timestamp.
606
+
607
+ ### Does **Hawk** have anything to do with OAuth?
608
+
609
+ Short answer: no.
610
+
611
+ **Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent
612
+ incompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it
613
+ to authenticate simple client-server transactions (i.e. two-legged). As you can guess, the OAuth working group is still hard
614
+ at work to produce more garbage.
615
+
616
+ **Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case
617
+ of delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](https://github.com/hueniverse/oz).
618
+
619
+
620
+ # Acknowledgements
621
+
622
+ **Hawk** is a derivative work of the [HTTP MAC Authentication Scheme](http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05) proposal
623
+ co-authored by Ben Adida, Adam Barth, and Eran Hammer, which in turn was based on the OAuth 1.0 community specification.
624
+
625
+ Special thanks to Ben Laurie for his always insightful feedback and advice.
626
+
627
+ The **Hawk** logo was created by [Chris Carrasco](http://chriscarrasco.com).