@@ -2,6 +2,7 @@ package bridge
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"io"
7
8
"net"
@@ -11,6 +12,9 @@ import (
11
12
"time"
12
13
13
14
"github.com/avast/retry-go"
15
+ "github.com/gofiber/fiber/v2"
16
+ "github.com/limanmys/render-engine/app/models"
17
+ "github.com/limanmys/render-engine/internal/liman"
14
18
"github.com/limanmys/render-engine/pkg/logger"
15
19
"github.com/phayes/freeport"
16
20
"golang.org/x/crypto/ssh"
@@ -301,8 +305,30 @@ func (t *Tunnel) String() string {
301
305
return fmt .Sprintf ("%s@%s | %s %s %s" , t .user , t .hostAddr , left , mode , right )
302
306
}
303
307
308
+ func CreateTunnelInternalKey (c * fiber.Ctx ) (int , error ) {
309
+ credentials , err := liman .GetCredentials (& models.User {
310
+ ID : c .Locals ("user_id" ).(string ),
311
+ }, & models.Server {
312
+ ID : c .FormValue ("server_id" ),
313
+ })
314
+ if err != nil {
315
+ return 0 , err
316
+ }
317
+
318
+ port , err := CreateTunnel (
319
+ c .FormValue ("remote_host" ),
320
+ c .FormValue ("remote_port" ),
321
+ credentials .Username ,
322
+ credentials .Key ,
323
+ credentials .Port ,
324
+ credentials .Type ,
325
+ )
326
+
327
+ return port , err
328
+ }
329
+
304
330
// CreateTunnel starts a new tunnel instance and sets it into TunnelPool
305
- func CreateTunnel (remoteHost , remotePort , username , password , sshPort string ) int {
331
+ func CreateTunnel (remoteHost , remotePort , username , password , sshPort , connType string ) ( int , error ) {
306
332
// Creating a tunnel cannot exceed 25 seconds
307
333
ch := make (chan int )
308
334
time .AfterFunc (25 * time .Second , func () {
@@ -315,7 +341,7 @@ func CreateTunnel(remoteHost, remotePort, username, password, sshPort string) in
315
341
// Check if existing tunnel started, if not wait until starts (max: 25sec)
316
342
if err == nil {
317
343
if t .password != password {
318
- return 0
344
+ return 0 , errors . New ( "password mismatch" )
319
345
}
320
346
321
347
startedLoop:
@@ -336,14 +362,14 @@ func CreateTunnel(remoteHost, remotePort, username, password, sshPort string) in
336
362
}
337
363
338
364
t .LastConnection = time .Now ()
339
- return t .Port
365
+ return t .Port , nil
340
366
}
341
367
342
368
// This part from now creates a new tunnel
343
369
port , err := freeport .GetFreePort ()
344
370
if err != nil {
345
371
logger .Sugar ().Errorw (err .Error ())
346
- return 0
372
+ return 0 , errors . New ( "couldnt find a free port" )
347
373
}
348
374
349
375
dial := net .JoinHostPort ("127.0.0.1" , remotePort )
@@ -355,8 +381,8 @@ func CreateTunnel(remoteHost, remotePort, username, password, sshPort string) in
355
381
}
356
382
357
383
ctx , cancel := context .WithCancel (context .Background ())
384
+
358
385
sshTunnel := & Tunnel {
359
- auth : []ssh.AuthMethod {ssh .RetryableAuthMethod (ssh .Password (password ), 3 )},
360
386
hostKeys : ssh .InsecureIgnoreHostKey (),
361
387
user : username ,
362
388
mode : '>' ,
@@ -376,6 +402,23 @@ func CreateTunnel(remoteHost, remotePort, username, password, sshPort string) in
376
402
cancel : cancel ,
377
403
}
378
404
405
+ if connType == "ssh" {
406
+ sshTunnel .auth = []ssh.AuthMethod {
407
+ ssh .RetryableAuthMethod (ssh .Password (password ), 3 ),
408
+ }
409
+ }
410
+
411
+ if connType == "ssh_certificate" {
412
+ key , err := ssh .ParsePrivateKey ([]byte (password ))
413
+ if err != nil {
414
+ return 0 , errors .New ("an error occured while parsing ssh key" )
415
+ }
416
+
417
+ sshTunnel .auth = []ssh.AuthMethod {
418
+ ssh .RetryableAuthMethod (ssh .PublicKeys (key ), 3 ),
419
+ }
420
+ }
421
+
379
422
Tunnels .Set (remoteHost , remotePort , username , sshTunnel )
380
423
go sshTunnel .Start ()
381
424
@@ -398,8 +441,8 @@ loop:
398
441
399
442
if ! sshTunnel .Started {
400
443
cancel ()
401
- return 0
444
+ return 0 , errors . New ( "cannot start tunnel" )
402
445
}
403
446
404
- return sshTunnel .Port
447
+ return sshTunnel .Port , nil
405
448
}
0 commit comments