-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
121 lines (102 loc) · 3.27 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import fs from 'fs'
import util from 'util'
import EventEmitter from 'events'
import Docker from 'dockerode'
import ssh2 from 'ssh2'
import NodeRSA from 'node-rsa'
const docker = new Docker()
// Generate a temporary, throwaway private key.
const key = new NodeRSA({b: 1024})
const privKey = key.exportKey('pkcs1-private-pem')
const TIMEOUT = 100000
new ssh2.Server({
hostKeys: [ privKey ],
banner: "Welcome!",
ident: "ssh-sandboxes",
}, (client) => {
console.log("Client connected!")
client.on('authentication', (ctx) => {
// Blindly accept all connections. Only one per IP address allowed, though.
ctx.accept()
}).on('ready', () => {
console.log('Client authenticated!')
client.on('session', function(accept, reject) {
console.log('Client wants new session')
var session = accept()
session.once('pty', (accept, reject, info) => {
accept()
})
session.once('shell', (accept, reject) => {
console.log('Client wants a shell!')
let container = null
// Accept the connection and get a bidirectional stream.
const stream = accept()
var cleanupStream = function() {
if (stream.timeoutId) {
clearTimeout(stream.timeoutId)
}
if (container) {
container.remove({force: true}, function(err, data) {
if (err) {
console.log('Error removing container %s: %s', container.id, err)
}
console.log('Removed container')
})
}
}
docker.createContainer({
Cmd: '/bin/bash',
Image: 'ubuntu:latest',
OpenStdin: true,
Tty: true
}, function (err, newContainer) {
if (err) {
console.log(err)
closeStream()
return
}
container = newContainer
container.attach({
stream: true, stdin: true, stdout: true, stderr: true
}, function (err, ttyStream) {
console.log("Attached to container " + newContainer.id)
// Attach output streams to client stream.
ttyStream.pipe(stream);
// Attach client stream to stdin of container
stream.pipe(ttyStream);
// Start the container
newContainer.start((err, data) => {
if (err) {
console.error('Unable to start container', err)
closeStream()
return
}
console.log("Container started!")
})
})
})
const onTimeout = function () {
console.log('Closing session due to timeout')
stream.close()
}
stream.on('data', function(chunk) {
// Reset timeout
if (stream.timeoutId) {
clearTimeout(stream.timeoutId)
}
stream.timeoutId = setTimeout(onTimeout, TIMEOUT)
})
stream.on('end', () => {
console.log('Stream disconnected!')
cleanupStream()
})
})
})
}).on('abort', () => {
console.log('Client aborted!')
}).on('end', () => {
console.log('Client disconnected!')
})
}).listen(0, '0.0.0.0', function() {
console.log('Listening on port ' + this.address().port)
})