@@ -2,6 +2,7 @@ package bridge
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "io"
78 "net"
@@ -11,6 +12,9 @@ import (
1112 "time"
1213
1314 "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"
1418 "github.com/limanmys/render-engine/pkg/logger"
1519 "github.com/phayes/freeport"
1620 "golang.org/x/crypto/ssh"
@@ -301,8 +305,30 @@ func (t *Tunnel) String() string {
301305 return fmt .Sprintf ("%s@%s | %s %s %s" , t .user , t .hostAddr , left , mode , right )
302306}
303307
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+
304330// 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 ) {
306332 // Creating a tunnel cannot exceed 25 seconds
307333 ch := make (chan int )
308334 time .AfterFunc (25 * time .Second , func () {
@@ -315,7 +341,7 @@ func CreateTunnel(remoteHost, remotePort, username, password, sshPort string) in
315341 // Check if existing tunnel started, if not wait until starts (max: 25sec)
316342 if err == nil {
317343 if t .password != password {
318- return 0
344+ return 0 , errors . New ( "password mismatch" )
319345 }
320346
321347 startedLoop:
@@ -336,14 +362,14 @@ func CreateTunnel(remoteHost, remotePort, username, password, sshPort string) in
336362 }
337363
338364 t .LastConnection = time .Now ()
339- return t .Port
365+ return t .Port , nil
340366 }
341367
342368 // This part from now creates a new tunnel
343369 port , err := freeport .GetFreePort ()
344370 if err != nil {
345371 logger .Sugar ().Errorw (err .Error ())
346- return 0
372+ return 0 , errors . New ( "couldnt find a free port" )
347373 }
348374
349375 dial := net .JoinHostPort ("127.0.0.1" , remotePort )
@@ -355,8 +381,8 @@ func CreateTunnel(remoteHost, remotePort, username, password, sshPort string) in
355381 }
356382
357383 ctx , cancel := context .WithCancel (context .Background ())
384+
358385 sshTunnel := & Tunnel {
359- auth : []ssh.AuthMethod {ssh .RetryableAuthMethod (ssh .Password (password ), 3 )},
360386 hostKeys : ssh .InsecureIgnoreHostKey (),
361387 user : username ,
362388 mode : '>' ,
@@ -376,6 +402,23 @@ func CreateTunnel(remoteHost, remotePort, username, password, sshPort string) in
376402 cancel : cancel ,
377403 }
378404
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+
379422 Tunnels .Set (remoteHost , remotePort , username , sshTunnel )
380423 go sshTunnel .Start ()
381424
@@ -398,8 +441,8 @@ loop:
398441
399442 if ! sshTunnel .Started {
400443 cancel ()
401- return 0
444+ return 0 , errors . New ( "cannot start tunnel" )
402445 }
403446
404- return sshTunnel .Port
447+ return sshTunnel .Port , nil
405448}
0 commit comments