summaryrefslogtreecommitdiff
path: root/node_modules/needle/lib/auth.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/needle/lib/auth.js')
-rw-r--r--node_modules/needle/lib/auth.js110
1 files changed, 110 insertions, 0 deletions
diff --git a/node_modules/needle/lib/auth.js b/node_modules/needle/lib/auth.js
new file mode 100644
index 0000000..b7ed4ca
--- /dev/null
+++ b/node_modules/needle/lib/auth.js
@@ -0,0 +1,110 @@
+var createHash = require('crypto').createHash;
+
+function get_header(header, credentials, opts) {
+ var type = header.split(' ')[0],
+ user = credentials[0],
+ pass = credentials[1];
+
+ if (type == 'Digest') {
+ return digest.generate(header, user, pass, opts.method, opts.path);
+ } else if (type == 'Basic') {
+ return basic(user, pass);
+ }
+}
+
+////////////////////
+// basic
+
+function md5(string) {
+ return createHash('md5').update(string).digest('hex');
+}
+
+function basic(user, pass) {
+ var str = typeof pass == 'undefined' ? user : [user, pass].join(':');
+ return 'Basic ' + Buffer.from(str).toString('base64');
+}
+
+////////////////////
+// digest
+// logic inspired from https://github.com/simme/node-http-digest-client
+
+var digest = {};
+
+digest.parse_header = function(header) {
+ var challenge = {},
+ matches = header.match(/([a-z0-9_-]+)="?([a-z0-9=\/\.@\s-]+)"?/gi);
+
+ for (var i = 0, l = matches.length; i < l; i++) {
+ var parts = matches[i].split('='),
+ key = parts.shift(),
+ val = parts.join('=').replace(/^"/, '').replace(/"$/, '');
+
+ challenge[key] = val;
+ }
+
+ return challenge;
+}
+
+digest.update_nc = function(nc) {
+ var max = 99999999;
+ nc++;
+
+ if (nc > max)
+ nc = 1;
+
+ var padding = new Array(8).join('0') + '';
+ nc = nc + '';
+ return padding.substr(0, 8 - nc.length) + nc;
+}
+
+digest.generate = function(header, user, pass, method, path) {
+
+ var nc = 1,
+ cnonce = null,
+ challenge = digest.parse_header(header);
+
+ var ha1 = md5(user + ':' + challenge.realm + ':' + pass),
+ ha2 = md5(method.toUpperCase() + ':' + path),
+ resp = [ha1, challenge.nonce];
+
+ if (typeof challenge.qop === 'string') {
+ cnonce = md5(Math.random().toString(36)).substr(0, 8);
+ nc = digest.update_nc(nc);
+ resp = resp.concat(nc, cnonce);
+ }
+
+ resp = resp.concat(challenge.qop, ha2);
+
+ var params = {
+ uri : path,
+ realm : challenge.realm,
+ nonce : challenge.nonce,
+ username : user,
+ response : md5(resp.join(':'))
+ }
+
+ if (challenge.qop) {
+ params.qop = challenge.qop;
+ }
+
+ if (challenge.opaque) {
+ params.opaque = challenge.opaque;
+ }
+
+ if (cnonce) {
+ params.nc = nc;
+ params.cnonce = cnonce;
+ }
+
+ header = []
+ for (var k in params)
+ header.push(k + '="' + params[k] + '"')
+
+ return 'Digest ' + header.join(', ');
+}
+
+module.exports = {
+ header : get_header,
+ basic : basic,
+ digest : digest.generate
+}