Secure Client for exposing TLS (aka SSL) secured services as plain-text connections locally, and for multiplexing a single port with multiple protocols using SNI
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.go 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "os"
  6. "strconv"
  7. "strings"
  8. sclient "git.rootprojects.org/root/sclient.go"
  9. )
  10. func usage() {
  11. fmt.Fprintf(os.Stderr, "\nusage: sclient <remote> <local>\n"+
  12. "\n"+
  13. " ex: sclient example.com 3000\n"+
  14. " (sclient example.com:443 localhost:3000)\n"+
  15. "\n"+
  16. " ex: sclient example.com:8443 0.0.0.0:4080\n"+
  17. "\n")
  18. flag.PrintDefaults()
  19. fmt.Println()
  20. }
  21. func main() {
  22. flag.Usage = usage
  23. insecure := flag.Bool("k", false, "ignore bad TLS/SSL/HTTPS certificates")
  24. servername := flag.String("servername", "", "specify a servername different from <remote> (to disable SNI use an IP as <remote> and do use this option)")
  25. flag.BoolVar(insecure, "insecure", false, "ignore bad TLS/SSL/HTTPS certificates")
  26. flag.Parse()
  27. remotestr := flag.Arg(0)
  28. localstr := flag.Arg(1)
  29. i := flag.NArg()
  30. if 2 != i {
  31. // We may omit the second argument if we're going straight to stdin
  32. if stat, _ := os.Stdin.Stat(); 1 == i && (stat.Mode()&os.ModeCharDevice) == 0 {
  33. localstr = "|"
  34. } else {
  35. usage()
  36. os.Exit(1)
  37. }
  38. }
  39. sclient := &sclient.Tunnel{
  40. RemotePort: 443,
  41. LocalAddress: "localhost",
  42. InsecureSkipVerify: *insecure,
  43. ServerName: *servername,
  44. }
  45. remote := strings.Split(remotestr, ":")
  46. //remoteAddr, remotePort, err := net.SplitHostPort(remotestr)
  47. if 2 == len(remote) {
  48. rport, err := strconv.Atoi(remote[1])
  49. if nil != err {
  50. usage()
  51. os.Exit(0)
  52. }
  53. sclient.RemotePort = rport
  54. } else if 1 != len(remote) {
  55. usage()
  56. os.Exit(0)
  57. }
  58. sclient.RemoteAddress = remote[0]
  59. if "-" == localstr || "|" == localstr {
  60. // User may specify stdin/stdout instead of net
  61. sclient.LocalAddress = localstr
  62. sclient.LocalPort = -1
  63. } else {
  64. // Test that argument is a local address
  65. local := strings.Split(localstr, ":")
  66. if 1 == len(local) {
  67. lport, err := strconv.Atoi(local[0])
  68. if nil != err {
  69. usage()
  70. os.Exit(0)
  71. }
  72. sclient.LocalPort = lport
  73. } else {
  74. lport, err := strconv.Atoi(local[1])
  75. if nil != err {
  76. usage()
  77. os.Exit(0)
  78. }
  79. sclient.LocalAddress = local[0]
  80. sclient.LocalPort = lport
  81. }
  82. }
  83. err := sclient.DialAndListen()
  84. if nil != err {
  85. fmt.Fprintf(os.Stderr, "%s\n", err)
  86. //usage()
  87. //os.Exit(6)
  88. }
  89. }