freezerwatch 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +40 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/freezerwatch +9 -0
- data/bin/setup +7 -0
- data/freezerwatch.gemspec +23 -0
- data/lib/freezerwatch.rb +5 -0
- data/lib/freezerwatch/version.rb +3 -0
- data/node_modules/.bin/freezerwatch +139 -0
- data/node_modules/freezerwatch/.npmignore +3 -0
- data/node_modules/freezerwatch/.ruby-version +1 -0
- data/node_modules/freezerwatch/Gemfile +4 -0
- data/node_modules/freezerwatch/Gemfile.lock +79 -0
- data/node_modules/freezerwatch/LICENSE +23 -0
- data/node_modules/freezerwatch/README.md +41 -0
- data/node_modules/freezerwatch/Rakefile +13 -0
- data/node_modules/freezerwatch/freezerwatch.js +139 -0
- data/node_modules/freezerwatch/metrics/bigfiles_high_water_mark +1 -0
- data/node_modules/freezerwatch/metrics/cane_high_water_mark +1 -0
- data/node_modules/freezerwatch/metrics/flay_high_water_mark +1 -0
- data/node_modules/freezerwatch/metrics/flog_high_water_mark +1 -0
- data/node_modules/freezerwatch/metrics/punchlist_high_water_mark +2 -0
- data/node_modules/freezerwatch/metrics/reek_high_water_mark +1 -0
- data/node_modules/freezerwatch/metrics/rubocop_high_water_mark +1 -0
- data/node_modules/freezerwatch/node_modules/async/.jshintrc +25 -0
- data/node_modules/freezerwatch/node_modules/async/.travis.yml +6 -0
- data/node_modules/freezerwatch/node_modules/async/CHANGELOG.md +65 -0
- data/node_modules/freezerwatch/node_modules/async/LICENSE +19 -0
- data/node_modules/freezerwatch/node_modules/async/README.md +1803 -0
- data/node_modules/freezerwatch/node_modules/async/bower.json +43 -0
- data/node_modules/freezerwatch/node_modules/async/component.json +17 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/base.css +182 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/index.html +73 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/base.css +182 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/index.html +73 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/lib/async.js.html +3900 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/lib/index.html +73 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/prettify.css +1 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/prettify.js +1 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov-report/sorter.js +156 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lcov.info +1452 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lib/async.js.html +3597 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/lib/index.html +73 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/prettify.css +1 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/prettify.js +1 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/sort-arrow-sprite.png +0 -0
- data/node_modules/freezerwatch/node_modules/async/coverage/sorter.js +156 -0
- data/node_modules/freezerwatch/node_modules/async/lib/async.js +1191 -0
- data/node_modules/freezerwatch/node_modules/async/nyc_output/5074.json +1 -0
- data/node_modules/freezerwatch/node_modules/async/package.json +96 -0
- data/node_modules/freezerwatch/node_modules/async/support/sync-package-managers.js +53 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/.npmignore +15 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/Client.js +60 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/Device.js +38 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/DeviceRawReadStream.js +36 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/DeviceSingleRawReadStream.js +29 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/DeviceStream.js +35 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/LICENSE +23 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/README.md +25 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/index.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/.npmignore +2 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/.travis.yml +12 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/LICENSE +55 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/README.md +364 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/index.js +156 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/lib/copy.js +8 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/lib/debug.js +7 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/lib/getSafe.js +34 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/lib/optional.js +5 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/.bin/uuid +26 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/aws-sign2/LICENSE +55 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/aws-sign2/README.md +4 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/aws-sign2/index.js +202 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/aws-sign2/package.json +46 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/forever-agent/LICENSE +55 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/forever-agent/README.md +4 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/forever-agent/index.js +119 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/forever-agent/package.json +45 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/License +19 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/Readme.md +175 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/lib/form_data.js +351 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/.travis.yml +5 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/LICENSE +19 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/README.md +1647 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/bower.json +38 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/component.json +16 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js +1123 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/package.json +84 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/async/support/sync-package-managers.js +53 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/License +19 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md +132 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js +188 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json +60 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/form-data/package.json +80 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/.npmignore +18 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/.travis.yml +5 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/LICENSE +24 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/Makefile +10 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/README.md +627 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/example/usage.js +78 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/images/hawk.png +0 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/images/logo.png +0 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/index.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/browser.js +485 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/client.js +367 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/crypto.js +111 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/index.js +15 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/server.js +524 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/lib/utils.js +183 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/.npmignore +18 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/.travis.yml +5 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/LICENSE +24 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/Makefile +11 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/README.md +6 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/images/boom.png +0 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/index.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/lib/index.js +207 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/package.json +64 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/boom/test/index.js +245 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/.npmignore +18 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/.travis.yml +5 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/LICENSE +24 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/Makefile +11 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/README.md +6 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/index.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/lib/index.js +68 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/package.json +65 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/cryptiles/test/index.js +101 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/.npmignore +18 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/.travis.yml +5 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/LICENSE +33 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/Makefile +10 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/README.md +436 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/images/hoek.png +0 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/index.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/lib/escape.js +132 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/lib/index.js +585 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/package.json +70 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/escaper.js +86 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/index.js +1078 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test1.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test2.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test3.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/.npmignore +18 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/.travis.yml +5 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/LICENSE +24 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/Makefile +11 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/README.md +68 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/examples/offset.js +16 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/examples/time.js +25 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/index.js +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js +409 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/package.json +65 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/node_modules/sntp/test/index.js +359 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/package.json +70 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/browser.js +771 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/client.js +206 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/crypto.js +86 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/index.js +316 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/message.js +246 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/readme.js +98 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/server.js +686 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/uri.js +456 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/test/utils.js +120 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/.dir-locals.el +6 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/.npmignore +7 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/LICENSE +18 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/README.md +79 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/http_signing.md +296 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/index.js +26 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/parser.js +304 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/signer.js +178 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/util.js +304 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/lib/verify.js +42 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/.npmignore +2 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/LICENSE +19 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/README.md +50 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/errors.js +13 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/index.js +27 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/reader.js +267 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/types.js +36 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/ber/writer.js +317 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/lib/index.js +20 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/package.json +63 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/tst/ber/reader.test.js +172 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/asn1/tst/ber/writer.test.js +296 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/assert-plus/README.md +126 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/assert-plus/assert.js +245 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/assert-plus/package.json +45 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/.npmignore +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/CHANGELOG +78 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/LICENSE +24 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/README +82 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/README.old +298 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/ctf.js +245 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/ctio.js +1485 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/ctype.js +944 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/man/man3ctype/ctio.3ctype +241 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/package.json +42 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/tools/jsl.conf +129 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/node_modules/ctype/tools/jsstyle +839 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/http-signature/package.json +72 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/.npmignore +1 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/CHANGELOG.md +14 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/LICENSE +15 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/Makefile +35 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/README.md +52 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/package.json +68 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/stringify.js +27 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/test/mocha.opts +2 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/json-stringify-safe/test/stringify_test.js +246 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/LICENSE +19 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/README.md +66 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/mime.js +114 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/package.json +57 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/test.js +84 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/types/mime.types +1588 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/mime/types/node.types +77 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/.npmignore +2 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/LICENSE.md +21 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/README.md +243 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/README.md +53 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu +174 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/bench.sh +34 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c +34 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js +84 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/bin/uuid +26 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/bower.json +23 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/component.json +18 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/package.json +65 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/test/compare_v1.js +63 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/test/test.html +17 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/test/test.js +228 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/node-uuid/uuid.js +247 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/LICENSE +55 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/README.md +4 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/index.js +43 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/package.json +48 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/oauth-sign/test.js +49 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/.gitmodules +6 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/.npmignore +7 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/Readme.md +58 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/index.js +366 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/qs/package.json +55 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/.jshintrc +72 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/.npmignore +3 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/LICENSE +78 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/README.md +380 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/generate-pubsuffix.js +230 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/lib/cookie.js +947 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/lib/memstore.js +102 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/lib/pubsuffix.js +69 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/node_modules/punycode/LICENSE-MIT.txt +20 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/node_modules/punycode/README.md +176 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/node_modules/punycode/package.json +81 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/node_modules/punycode/punycode.js +530 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/package.json +63 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/public-suffix.txt +5229 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tough-cookie/test.js +1340 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tunnel-agent/LICENSE +55 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tunnel-agent/README.md +4 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tunnel-agent/index.js +227 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/tunnel-agent/package.json +45 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/package.json +74 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/request.js +1244 -0
- data/node_modules/freezerwatch/node_modules/lacrosse/package.json +34 -0
- data/node_modules/freezerwatch/node_modules/optparse/README.md +163 -0
- data/node_modules/freezerwatch/node_modules/optparse/TODO +1 -0
- data/node_modules/freezerwatch/node_modules/optparse/examples/browser-test.html +75 -0
- data/node_modules/freezerwatch/node_modules/optparse/examples/nodejs-test.js +86 -0
- data/node_modules/freezerwatch/node_modules/optparse/lib/optparse.js +309 -0
- data/node_modules/freezerwatch/node_modules/optparse/package.json +46 -0
- data/node_modules/freezerwatch/node_modules/optparse/seed.yml +5 -0
- data/node_modules/freezerwatch/node_modules/osenv/.npmignore +13 -0
- data/node_modules/freezerwatch/node_modules/osenv/.travis.yml +9 -0
- data/node_modules/freezerwatch/node_modules/osenv/LICENSE +15 -0
- data/node_modules/freezerwatch/node_modules/osenv/README.md +63 -0
- data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-homedir/index.js +24 -0
- data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-homedir/license +21 -0
- data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-homedir/package.json +70 -0
- data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-homedir/readme.md +33 -0
- data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-tmpdir/index.js +25 -0
- data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-tmpdir/license +21 -0
- data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-tmpdir/package.json +70 -0
- data/node_modules/freezerwatch/node_modules/osenv/node_modules/os-tmpdir/readme.md +36 -0
- data/node_modules/freezerwatch/node_modules/osenv/osenv.js +72 -0
- data/node_modules/freezerwatch/node_modules/osenv/package.json +76 -0
- data/node_modules/freezerwatch/node_modules/osenv/test/unix.js +71 -0
- data/node_modules/freezerwatch/node_modules/osenv/test/windows.js +74 -0
- data/node_modules/freezerwatch/node_modules/osenv/x.tap +39 -0
- data/node_modules/freezerwatch/package.json +37 -0
- 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,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
|
+
}
|
data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/LICENSE
ADDED
@@ -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.
|
data/node_modules/freezerwatch/node_modules/lacrosse/node_modules/request/node_modules/hawk/Makefile
ADDED
@@ -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).
|