Giter Club home page Giter Club logo

node-sshpk-agent's Introduction

sshpk-agent

A library for using the ssh-agent protocol, written to leverage the modern node Streams API and use sshpk objects. Supports most client operations (including key add/remove), but agent support is coming. Re-uses socket connections where possible for lower latency operation.

Install

npm install sshpk-agent

Examples

var agent = require('sshpk-agent');
var sshpk = require('sshpk');

var client = new agent.Client();

/* Add a new key to the agent */
var pk = sshpk.parsePrivateKey(fs.readFileSync('id_rsa'), 'pem');
client.addKey(pk, function (err) {
  ...
});

/* List all the keys stored in the agent */
var key;
client.listKeys(function (err, keys) {
  if (err)
    return;
  /* keys is an array of sshpk.Key objects */
  key = keys[0];
});

/* Sign some data with a key */
var data = 'foobar';
client.sign(key, data, function (err, signature) {
  /* signature is an sshpk.Signature object */
  ...
  /* to find out what hash algorithm the agent used -- it chooses for you */
  var algo = signature.hashAlgorithm;
  ...
});

Usage

new Client([options]);

Creates a new ssh-agent client.

Parameters

  • options -- optional Object, containing properties:
    • socketPath -- an optional String, path to the UNIX socket to reach the SSH agent via. If not specified, defaults to process.env['SSH_AUTH_SOCK']
    • timeout -- an optional Number, milliseconds to wait for the agent to respond to a request before returning error. Defaults to 2000.

Client#listKeys([options, ]callback);

Retrieves a list of all keys stored in the agent.

Parameters

  • options -- optional Object, containg properties:
    • timeout -- an optional Number, overrides the constructor timeout just for this request
  • callback -- function (error, keys) with arguments:
    • error -- null if no error, otherwise an instance of Error or its subclasses
    • keys -- Array of sshpk.Key objects, the available public keys

Client#listCertificates([options, ]callback);

Retrieves a list of all certificates stored in the agent.

Parameters

  • options -- optional Object, containg properties:
    • timeout -- an optional Number, overrides the constructor timeout just for this request
  • callback -- function (error, keys) with arguments:
    • error -- null if no error, otherwise an instance of Error or its subclasses
    • keys -- Array of sshpk.Certificate objects, the available certificates

Client#sign(key, data[, options], callback);

Uses a key stored in the agent to sign some data.

Parameters

  • key -- an Object, instance of sshpk.Key, key to sign with
  • data -- a Buffer or String, data to be signed
  • options -- optional Object, containing properties:
    • timeout -- an optional Number, overrides the constructor timeout just for this request
  • callback -- function (error, signature) with arguments:
    • error -- null if no error, otherwise instance of Error
    • signature -- an Object, instance of sshpk.Signature

Client#createSelfSignedCertificate(subject, key, options, cb)

Uses a key stored in the agent to create a self-signed certificate for that key. The certificate can be read back in both OpenSSH and X.509 formats.

Parameters

  • subject -- an Identity, the subject of the certificate
  • key -- an Object, instance of sshpk.Key, key to sign with and the subject key
  • options -- an Object, additional options, with keys:
    • lifetime -- optional Number, lifetime of the certificate from now in seconds
    • validFrom, validUntil -- optional Dates, beginning and end of certificate validity period. If given, lifetime will be ignored.
    • serial -- optional Buffer, the serial number of the certificate
    • purposes -- optional Array of String, X.509 key usage restrictions
  • callback -- function (error, certificate), with arguments:
    • error -- null if no error, otherwise instance of Error
    • certificate -- an Object, instance of sshpk.Certificate

Client#createCertificate(subject, subjectKey, issuer, key, options, cb)

Uses a key stored in the agent to create and sign a certificate for some other key (not necessarily in the agent). The certificate can be read back in both OpenSSH and X.509 formats.

Parameters

  • subject -- an Identity, the subject of the certificate
  • subjectKey -- an Object, instance of sshpk.Key, key of the subject entity (does not have to reside in the agent)
  • issuer -- an Identity, the issuer of the certificate
  • key -- an Object, instance of sshpk.Key, key to sign with (must be in the agent, and match up with the issuer identity)
  • options -- an Object, additional options, with keys:
    • lifetime -- optional Number, lifetime of the certificate from now in seconds
    • validFrom, validUntil -- optional Dates, beginning and end of certificate validity period. If given, lifetime will be ignored.
    • serial -- optional Buffer, the serial number of the certificate
    • purposes -- optional Array of String, X.509 key usage restrictions
  • callback -- function (error, certificate), with arguments:
    • error -- null if no error, otherwise instance of Error
    • certificate -- an Object, instance of sshpk.Certificate

Client#addKey(privkey[, options], callback);

Adds a new private key to the agent.

Parameters

  • privkey -- an Object, instance of sshpk.PrivateKey, key to add
  • options -- optional Object, containing properties:
    • expires -- optional Number, seconds until this key expires. If not given, key will last indefinitely. Expiry is handled by the agent itself.
    • timeout -- optional Number, overrides the constructor timeout
  • callback -- function (error) with arguments:
    • error -- null if no error, otherwise instance of Error

Client#addCertificate(cert, privkey[, options], callback);

Adds a new certificate and private key pair to the agent.

Parameters

  • cert -- an Object, instance of sshpk.Certificate, cert to add
  • privkey -- an Object, instance of sshpk.PrivateKey, subject private key of the certificate
  • options -- optional Object, containing properties:
    • expires -- optional Number, seconds until this key expires. If not given, key will last indefinitely. Expiry is handled by the agent itself.
    • timeout -- optional Number, overrides the constructor timeout
  • callback -- function (error) with arguments:
    • error -- null if no error, otherwise instance of Error

Client#removeKey(key[, options], callback);

Removes a private key from the agent.

Parameters

  • key -- an Object, instance of sshpk.Key, key to remove
  • options -- optional Object, containing properties:
    • timeout -- an optional Number, overrides the constructor timeout just for this request
  • callback -- function (error) with arguments:
    • error -- null if no error, otherwise instance of Error

Client#removeAllKeys([options, ]callback);

Removes all private keys from the agent.

Parameters

  • options -- optional Object, containing properties:
    • timeout -- an optional Number, overrides the constructor timeout just for this request
  • callback -- function (error) with arguments:
    • error -- null if no error, otherwise instance of Error

Client#lock(password[, options], callback);

Locks the agent with a password, causing it to respond with failure to all requests (except a request to list keys, which always returns an empty list), until unlocked with the same password.

Parameters

  • password -- a String, password to be required to unlock the agent
  • options -- optional Object, containing properties:
    • timeout -- an optional Number, overrides the constructor timeout just for this request
  • callback -- function (error) with arguments:
    • error -- null if no error, otherwise instance of Error

Client#unlock(password[, options], callback);

Unlocks an agent that has been previously locked. The given password must match the password used to lock the agent.

Parameters

  • password -- a String, password to unlock the agent
  • options -- optional Object, containing properties:
    • timeout -- an optional Number, overrides the constructor timeout just for this request
  • callback -- function (error) with arguments:
    • error -- null if no error, otherwise instance of Error

Client#listExtensions(callback);

Requests the "query" extension (see draft-miller-ssh-agent-00) from the agent to list what agent protocol extensions are supported. These are returned as a list of Strings.

Parameters

  • callback -- function (error, extensions) with arguments:
  • error -- null if no error, otherwise instance of Error
  • extensions -- Array of String, supported extensions

node-sshpk-agent's People

Contributors

arekinath avatar bahamat avatar cburroughs avatar trentm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-sshpk-agent's Issues

Support sshpk 1.14.x and higher

After the changes to Ed25519 key formatting in sshpk 1.14.0 it's necessary to update sshpk-agent to take the new naming into account.

agent extension payloads are not strings

The current specification for the "extension request" frame in protocol.js uses writeBuffer() for the extension payload (in the data field). This was based on a misunderstanding in an early version of the IETF draft-miller-ssh-agent- document. The implementation of extensions in OpenSSH shows that the byte[] type following the extension name is in fact just raw bytes defined by the extension, not a length-prefixed string/buffer like we have implemented it.

This stuff isn't really public API of this module at the moment, but I've written at least a few tools that pin exact versions of it to get at the extension bits to make requests. It would be nice to fix it up in the lib (and maybe add some better public API for using agent extensions?)

single use key

Is there a way to make a key "single-use"? I want the key to be removed as soon as ssh-agent is contacted by the client to use a key, and automatically remove itself from the key chain.

sshpk-agent fails to parse ed25519 keys

Using sshpk-agent in conjunction with node-smartdc, node-manta and node-triton, if I have my ed25519 key loaded into the agent it can't parse the data returned form ssh-agent.. This is compounded by the fact that my keys are encrypted so it can't fall back to the disk file.

Uncaught, unspecified "error" event

If ssh-agent is not running properly, sshpk-agent generates following error message.

Sat Jun 24 2017 13:30:06 GMT+0000 (UTC) - error: Sat, 24 Jun 2017 13:30:06 GMT uncaughtException: Uncaught, unspecified "error" event. (undefined)
 Sat Jun 24 2017 13:30:06 GMT+0000 (UTC) - error: Error: Uncaught, unspecified "error" event. (undefined)
     at Client.emit (events.js:163:17)
     at Immediate.<anonymous> (/app/node_modules/sshpk-agent/lib/client-fsm.js:313:9)
     at runCallback (timers.js:649:20)
     at tryOnImmediate (timers.js:622:5)
     at processImmediate [as _immediateCallback] (timers.js:594:5)

It should generate a better error message - something that indicates that ssh-agent is broken.

Can't catch exception

Hello.

Our app is crashing with this exception

2021-01-14T17:43:04.006Z [amaretti] error: uncaughtException: Error while connecting to socket: /tmp/0.11251921150910493.0.5478394110224416.0.9537569972344819.ssh-agent.sock: connect ENOENT /tmp/0.11251921150910493.0.5478394110224416.0.9537569972344819.ssh-agent.sock
VError: Error while connecting to socket: /tmp/0.11251921150910493.0.5478394110224416.0.9537569972344819.ssh-agent.sock: connect ENOENT /tmp/0.11251921150910493.0.5478394110224416.0.9537569972344819.ssh-agent.sock
    at Socket.<anonymous> (/app/node_modules/sshpk-agent/lib/client-fsm.js:291:25)
    at Socket.emit (events.js:198:13)
    at emitErrorNT (internal/streams/destroy.js:91:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)

I am trying to find a way to properly handle this condition, but it looks like the exception is thrown inside a nested callback and I can't seem to simply wrap the code with try/catch.. For example, the following doesn't work.

try {
    let client = new sshagent.Client({socketPath: auth_sock});
    client.addKey(key, err=>{
        cb(err, agent, client, auth_sock, key);
    });
} catch (err) {
    cb(err);
}

When the error occurs, the catch() block will never gets called. Is there a way to prevent sshpk-agent from crashing?

unexpected AgentProtocolError exception

I had a program run into this uncaught exception:

events.js:72
        throw er; // Unhandled 'error' event
              ^
AgentProtocolError: Data received from SSH agent could not be decoded: Out of order frame received: identities-answer
    at AgentDecodeStream.<anonymous> (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/lib/client.js:475:24)
    at AgentDecodeStream.emit (events.js:92:17)
    at emitReadable_ (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/node_modules/readable-stream/lib/_stream_readable.js:464:10)
    at emitReadable (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/node_modules/readable-stream/lib/_stream_readable.js:458:7)
    at readableAddChunk (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/node_modules/readable-stream/lib/_stream_readable.js:210:11)
    at AgentDecodeStream.Readable.push (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/node_modules/readable-stream/lib/_stream_readable.js:163:10)
    at AgentDecodeStream.Transform.push (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/node_modules/readable-stream/lib/_stream_transform.js:133:32)
    at AgentDecodeStream._transform (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/lib/protocol-streams.js:216:9)
    at AgentDecodeStream.Transform._read (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/node_modules/readable-stream/lib/_stream_transform.js:172:10)
    at AgentDecodeStream.Transform._write (/home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin/node_modules/manta/node_modules/smartdc-auth/node_modules/sshpk-agent/node_modules/readable-stream/lib/_stream_transform.js:160:12)

I only saw it once, despite a few tries. I'm using Node v0.10.32, and here's the whole "npm ls" output:

[email protected] /home/dap/manta-marlin/build/proto/root/opt/smartdc/marlin
├── [email protected] (git+ssh://[email protected]:joyent/aperture-config.git#82560607fcb516ebaee82709f532c12bcb4db09d)
├── [email protected]
├─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├── [email protected]
├─┬ [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ └─┬ [email protected]
│   ├─┬ [email protected]
│   │ ├── [email protected]
│   │ ├── [email protected]
│   │ └── [email protected]
│   └─┬ [email protected]
│     └── [email protected]
├── [email protected]
├─┬ [email protected] (git+ssh://[email protected]:joyent/node-libmanta.git#39389b73986b57f18dbee546ea723de2dd90c9b4)
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected] (git+ssh://[email protected]:joyent/node-moray.git#b8e1defd349de40cc4c33502f8b13da73c513a91)
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │   └─┬ [email protected]
│ │ │ │     ├─┬ [email protected]
│ │ │ │     │ └── [email protected]
│ │ │ │     ├── [email protected]
│ │ │ │     ├─┬ [email protected]
│ │ │ │     │ └─┬ [email protected]
│ │ │ │     │   ├── [email protected]
│ │ │ │     │   └── [email protected]
│ │ │ │     └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected] (git+ssh://[email protected]/mcavage/node-fast.git#806645590ce3ef01ff698ffc5ee4f420cbadfae4)
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├─┬ [email protected]
│ └─┬ [email protected]
│   ├── [email protected]
│   ├── [email protected]
│   ├── [email protected]
│   ├── [email protected]
│   ├── [email protected]
│   └── [email protected]
├─┬ [email protected] (git+ssh://[email protected]:joyent/node-mahi.git#38efe35bf5b9abe75dee385ac14f13280dbca3d5)
│ ├─┬ [email protected] (git+ssh://[email protected]:joyent/node-aperture.git#016977f02142eedcd6a0d3fefaed071dd1fe71ba)
│ │ ├── [email protected] (git://github.com/mcavage/node-assert-plus.git#b5794c3197f2a4df9d8ef6ad04a34149ac0e5403)
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├─┬ [email protected] (git+ssh://[email protected]:joyent/node-manta.git#b73bd468735954baeb3d0b9127ee5c7588cb4fec)
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │   └─┬ [email protected]
│ │ │ │     ├─┬ [email protected]
│ │ │ │     │ └── [email protected]
│ │ │ │     ├── [email protected]
│ │ │ │     ├─┬ [email protected]
│ │ │ │     │ └─┬ [email protected]
│ │ │ │     │   ├── [email protected]
│ │ │ │     │   └── [email protected]
│ │ │ │     └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   └── [email protected]
│ │ └─┬ [email protected]
│ │   ├─┬ [email protected]
│ │   │ ├── [email protected]
│ │   │ ├── [email protected]
│ │   │ └── [email protected]
│ │   └─┬ [email protected]
│ │     └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   └─┬ [email protected]
│ │ │     ├─┬ [email protected]
│ │ │     │ └── [email protected]
│ │ │     ├─┬ [email protected]
│ │ │     │ └─┬ [email protected]
│ │ │     │   ├── [email protected]
│ │ │     │   └── [email protected]
│ │ │     └── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├─┬ [email protected] (git+ssh://[email protected]:davepacheco/manta-compute-bin.git#2f30cf9ecf3a1e2f057a320a63671a9e9c385a5d)
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │   ├── [email protected]
│ │   ├── [email protected]
│ │   ├── [email protected]
│ │   ├── [email protected]
│ │   ├── [email protected]
│ │   └── [email protected]
│ ├─┬ [email protected] (git+ssh://[email protected]:joyent/node-manta.git#b73bd468735954baeb3d0b9127ee5c7588cb4fec)
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │   └─┬ [email protected]
│ │ │ │ │     ├─┬ [email protected]
│ │ │ │ │     │ └── [email protected]
│ │ │ │ │     ├── [email protected]
│ │ │ │ │     ├─┬ [email protected]
│ │ │ │ │     │ └─┬ [email protected]
│ │ │ │ │     │   ├── [email protected]
│ │ │ │ │     │   └── [email protected]
│ │ │ │ │     └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │   ├── [email protected]
│ │ │ │   ├── [email protected]
│ │ │ │   ├── [email protected]
│ │ │ │   ├── [email protected]
│ │ │ │   ├── [email protected]
│ │ │ │   └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   ├─┬ [email protected]
│ │ │   │ ├── [email protected]
│ │ │   │ ├── [email protected]
│ │ │   │ └── [email protected]
│ │ │   └─┬ [email protected]
│ │ │     └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │   └─┬ [email protected]
│ │ │ │     ├─┬ [email protected]
│ │ │ │     │ └── [email protected]
│ │ │ │     ├─┬ [email protected]
│ │ │ │     │ └─┬ [email protected]
│ │ │ │     │   ├── [email protected]
│ │ │ │     │   └── [email protected]
│ │ │ │     └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   └── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected] (git+ssh://[email protected]:joyent/node-moray.git#b8e1defd349de40cc4c33502f8b13da73c513a91)
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   └─┬ [email protected]
│ │ │     ├─┬ [email protected]
│ │ │     │ └── [email protected]
│ │ │     ├── [email protected]
│ │ │     ├─┬ [email protected]
│ │ │     │ └─┬ [email protected]
│ │ │     │   ├── [email protected]
│ │ │     │   └── [email protected]
│ │ │     └── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected] (git+ssh://[email protected]/mcavage/node-fast.git#806645590ce3ef01ff698ffc5ee4f420cbadfae4)
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├── [email protected]
├─┬ [email protected] (git+ssh://[email protected]:joyent/node-sdc-clients.git#ad24d7f70159f71ebed1c1f6cdf4d388044f3865)
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   └─┬ [email protected]
│ │ │     ├─┬ [email protected]
│ │ │     │ └── [email protected]
│ │ │     ├── [email protected]
│ │ │     ├─┬ [email protected]
│ │ │     │ └─┬ [email protected]
│ │ │     │   ├── [email protected]
│ │ │     │   └── [email protected]
│ │ │     └── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected] (git://github.com/joyent/node-restify.git#fd5d5b55f12bca7dd3c3a4adf1e15c89d4b41010)
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │   └─┬ [email protected]
│ │ │ │     ├─┬ [email protected]
│ │ │ │     │ └── [email protected]
│ │ │ │     ├── [email protected]
│ │ │ │     ├─┬ [email protected]
│ │ │ │     │ └─┬ [email protected]
│ │ │ │     │   ├── [email protected]
│ │ │ │     │   └── [email protected]
│ │ │ │     └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   ├── [email protected]
│ │ │   └── [email protected]
│ │ └─┬ [email protected]
│ │   ├─┬ [email protected]
│ │   │ ├── [email protected]
│ │   │ ├── [email protected]
│ │   │ └── [email protected]
│ │   └─┬ [email protected]
│ │     └── [email protected]
│ ├─┬ [email protected] (git://github.com/joyent/node-ufds.git#a7c674b76696fe7ab0fff1e2486f20d3af6a0d1a)
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected] (git://github.com/mcavage/node-ldapjs.git#aed6d2b043715e1a37c45a6293935c25c023ebce)
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   ├─┬ [email protected]
│ │ │   │ ├── [email protected]
│ │ │   │ ├── [email protected]
│ │ │   │ └── [email protected]
│ │ │   └─┬ [email protected]
│ │ │     └── [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├─┬ [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
└─┬ [email protected]
  └─┬ [email protected]
    └── [email protected]

Simplify protocol parser code

The current code is unnecessarily abstracted, with lots of structs and extra functions in the way of just parsing the data. We should make it look more like the DNS parsing logic in mname, for example.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.