Beispiel #1
0
func lazySetupPrefixes() {
	if prefix == nil {
		if !loggingEnabled {
			panic("attempting setup before logging enabled")
		}
		prefix = map[string]string{
			"debug": ansi.Magenta("debug "),
			// info has no prefix
			"ok":      ansi.Bold(ansi.Green("ok ")),
			"warning": ansi.Bold(ansi.Yellow("warning ")),
			"fatal":   ansi.Bold(ansi.Red("fatal ")),
		}
	}
}
Beispiel #2
0
func shell(fwdChan chan<- conf.ForwardLine, cfg *conf.Config, dialer Dialer) {
	help := func() {
		infoln("Available commands:")
		infoln("  help, ?                          - show help")
		infoln("  quit, ^D                         - stop forwarding and exit")
		infoln("  test                             - test each forward for connection")
		infoln("  stat                             - show forwarding statistics")
		infoln("  debug                            - enable debugging")
		infoln("  fwd srcip:srcport dstip:dstport  - add forward")
	}

	term := liner.NewLiner()
	atExit(func() {
		term.Close()
	})

	// Receive commands

	commands := make(chan string)
	next := make(chan bool)
	go func() {
		for {
			prompt := "mole> "
			if debugEnabled {
				prompt = "(debug) mole> "
			}
			cmd, err := term.Prompt(prompt)
			if err == io.EOF {
				fmt.Println("quit")
				commands <- "quit"
				return
			}

			if cmd != "" {
				commands <- cmd
				term.AppendHistory(cmd)
				_, ok := <-next
				if !ok {
					return
				}
			}
		}
	}()

	// Catch ^C and treat as "quit" command

	sigchan := make(chan os.Signal, 1)
	signal.Notify(sigchan, os.Interrupt)
	go func() {
		<-sigchan
		fmt.Println("quit")
		commands <- "quit"
	}()

	// Handle commands

	for {
		cmd := <-commands

		parts := strings.SplitN(cmd, " ", -1)

		switch parts[0] {
		case "quit":
			close(next)
			return
		case "help", "?":
			help()
		case "stat":
			printStats()
		case "test":
			results := testForwards(dialer, cfg)
			for res := range results {
				infof(ansi.Bold(ansi.Cyan(res.name)))
				for _, line := range res.results {
					if line.err == nil {
						infof("%22s %s in %.02f ms", line.dst, ansi.Bold(ansi.Green("-ok-")), line.ms)
					} else {
						infof("%22s %s in %.02f ms (%s)", line.dst, ansi.Bold(ansi.Red("fail")), line.ms, line.err)
					}
				}
			}
		case "debug":
			infoln(msgDebugEnabled)
			debugEnabled = true
		case "fwd":
			if len(parts) != 3 {
				warnf(msgErrIncorrectFwd, cmd)
				break
			}

			src := strings.SplitN(parts[1], ":", 2)
			if len(src) != 2 {
				warnf(msgErrIncorrectFwdSrc, parts[1])
				break
			}

			var ipExists bool
			for _, ip := range currentAddresses() {
				if ip == src[0] {
					ipExists = true
					break
				}
			}
			if !ipExists {
				warnf(msgErrIncorrectFwdIP, src[0])
				break
			}

			dst := strings.SplitN(parts[2], ":", 2)
			if len(dst) != 2 {
				warnf(msgErrIncorrectFwdDst, parts[2])
				break
			}

			srcp, err := strconv.Atoi(src[1])
			if err != nil {
				warnln(err)
				break
			}
			if srcp < 1024 {
				warnf(msgErrIncorrectFwdPriv, srcp)
				break
			}

			dstp, err := strconv.Atoi(dst[1])
			if err != nil {
				warnln(err)
				break
			}
			fwd := conf.ForwardLine{
				SrcIP:   src[0],
				SrcPort: srcp,
				DstIP:   dst[0],
				DstPort: dstp,
			}
			okln("add", fwd)
			fwdChan <- fwd
		default:
			warnf(msgErrNoSuchCommand, parts[0])
		}

		next <- true
	}
}