|
@ -8,7 +8,7 @@ var assert = require('assert').ok; |
|
|
|
|
|
|
|
|
var debug; |
|
|
var debug; |
|
|
if (process.env.NODE_DEBUG && /tls/.test(process.env.NODE_DEBUG)) { |
|
|
if (process.env.NODE_DEBUG && /tls/.test(process.env.NODE_DEBUG)) { |
|
|
debug = function() { util.error.apply(this, arguments); }; |
|
|
debug = function(a) { console.error("TLS: ", a); }; |
|
|
} else { |
|
|
} else { |
|
|
debug = function() { }; |
|
|
debug = function() { }; |
|
|
} |
|
|
} |
|
@ -38,6 +38,7 @@ util.inherits(CryptoStream, stream.Stream); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CryptoStream.prototype.write = function(data /* , encoding, cb */) { |
|
|
CryptoStream.prototype.write = function(data /* , encoding, cb */) { |
|
|
|
|
|
debug('CryptoStream.prototype.write called with <<<<' + data.toString() + '>>>'); |
|
|
if (!this.writable) { |
|
|
if (!this.writable) { |
|
|
throw new Error('CryptoStream is not writable'); |
|
|
throw new Error('CryptoStream is not writable'); |
|
|
} |
|
|
} |
|
@ -69,13 +70,13 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CryptoStream.prototype.pause = function() { |
|
|
CryptoStream.prototype.pause = function() { |
|
|
debug('paused cleartext'); |
|
|
debug('paused ' + (this == this.pair.cleartext ? 'cleartext' : 'encrypted')); |
|
|
this._writeState = false; |
|
|
this._writeState = false; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CryptoStream.prototype.resume = function() { |
|
|
CryptoStream.prototype.resume = function() { |
|
|
debug('resumed cleartext'); |
|
|
debug('resume ' + (this == this.pair.cleartext ? 'cleartext' : 'encrypted')); |
|
|
this._writeState = true; |
|
|
this._writeState = true; |
|
|
this.pair._cycle(); |
|
|
this.pair._cycle(); |
|
|
}; |
|
|
}; |
|
@ -220,6 +221,8 @@ CryptoStream.prototype._push = function() { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.pair._maybeInitFinished(); |
|
|
|
|
|
|
|
|
if (chunkBytes >= 0) { |
|
|
if (chunkBytes >= 0) { |
|
|
bytesRead += chunkBytes; |
|
|
bytesRead += chunkBytes; |
|
|
} |
|
|
} |
|
@ -238,6 +241,8 @@ CryptoStream.prototype._push = function() { |
|
|
|
|
|
|
|
|
var chunk = pool.slice(0, bytesRead); |
|
|
var chunk = pool.slice(0, bytesRead); |
|
|
|
|
|
|
|
|
|
|
|
debug('emit "data" called with <<<<' + chunk.toString() + '>>>'); |
|
|
|
|
|
|
|
|
if (this._decoder) { |
|
|
if (this._decoder) { |
|
|
var string = this._decoder.write(chunk); |
|
|
var string = this._decoder.write(chunk); |
|
|
if (string.length) this.emit('data', string); |
|
|
if (string.length) this.emit('data', string); |
|
@ -279,7 +284,7 @@ CryptoStream.prototype._pull = function() { |
|
|
if (tmp === END_OF_FILE) { |
|
|
if (tmp === END_OF_FILE) { |
|
|
// Sending EOF
|
|
|
// Sending EOF
|
|
|
if (this === this.pair.encrypted) { |
|
|
if (this === this.pair.encrypted) { |
|
|
debug('end encrypted'); |
|
|
debug('end encrypted ' + this.pair.fd); |
|
|
this.pair.cleartext._destroyAfterPush = true; |
|
|
this.pair.cleartext._destroyAfterPush = true; |
|
|
} else { |
|
|
} else { |
|
|
// CleartextStream
|
|
|
// CleartextStream
|
|
@ -306,6 +311,8 @@ CryptoStream.prototype._pull = function() { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.pair._maybeInitFinished(); |
|
|
|
|
|
|
|
|
if (rv === 0 || rv < 0) { |
|
|
if (rv === 0 || rv < 0) { |
|
|
this._pending.unshift(tmp); |
|
|
this._pending.unshift(tmp); |
|
|
this._pendingCallbacks.unshift(cb); |
|
|
this._pendingCallbacks.unshift(cb); |
|
@ -489,16 +496,25 @@ SecurePair.prototype._cycle = function() { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var established = this._secureEstablished; |
|
|
|
|
|
|
|
|
this.encrypted._pull(); |
|
|
this.encrypted._pull(); |
|
|
this.cleartext._pull(); |
|
|
this.cleartext._pull(); |
|
|
this.cleartext._push(); |
|
|
this.cleartext._push(); |
|
|
this.encrypted._push(); |
|
|
this.encrypted._push(); |
|
|
|
|
|
|
|
|
|
|
|
if (!established && this._secureEstablished) { |
|
|
|
|
|
// If we were not established but now we are, let's cycle again.
|
|
|
|
|
|
this._cycle(); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SecurePair.prototype._maybeInitFinished = function() { |
|
|
if (this._ssl && !this._secureEstablished && this._ssl.isInitFinished()) { |
|
|
if (this._ssl && !this._secureEstablished && this._ssl.isInitFinished()) { |
|
|
this._secureEstablished = true; |
|
|
this._secureEstablished = true; |
|
|
debug('secure established'); |
|
|
debug('secure established'); |
|
|
this.emit('secure'); |
|
|
this.emit('secure'); |
|
|
this._cycle(); |
|
|
|
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
@ -766,6 +782,7 @@ function pipe(pair, socket) { |
|
|
pair.encrypted.pipe(socket); |
|
|
pair.encrypted.pipe(socket); |
|
|
socket.pipe(pair.encrypted); |
|
|
socket.pipe(pair.encrypted); |
|
|
|
|
|
|
|
|
|
|
|
pair.fd = socket.fd; |
|
|
var cleartext = pair.cleartext; |
|
|
var cleartext = pair.cleartext; |
|
|
cleartext.socket = socket; |
|
|
cleartext.socket = socket; |
|
|
cleartext.encrypted = pair.encrypted; |
|
|
cleartext.encrypted = pair.encrypted; |
|
|