func ticketCommand(args []string) { cl := NewClient(serverAddress(), moleIni.Get("server", "fingerprint")) cl.Ticket = moleIni.Get("server", "ticket") tic, err := cl.ParseTicket() fatalErr(err) infof(msgTicketExplanation, ansi.Cyan(tic.User), ansi.Cyan(time.Time(tic.Validity).String())) for _, ip := range tic.IPs { infoln(" * ", ansi.Cyan(ip)) } }
func tableFormatter(cell string, row, col, flags int) string { if row == 0 { return ansi.Underline(cell) } else if col == 0 { return ansi.Bold(ansi.Cyan(cell)) } else if col == 1 && (strings.HasSuffix(cell, "U") || strings.HasSuffix(cell, "E")) { return ansi.Red(cell) } else if flags&table.Truncated != 0 { return cell[:len(cell)-1] + ansi.Red(">") } return cell }
func mainUsage(w io.Writer) { tw := tabwriter.NewWriter(w, 2, 4, 2, ' ', 0) fmt.Fprintln(w, ansi.Bold("Commands:")) var cmds []string for _, cmd := range commandList { cmds = append(cmds, cmd.name) } sort.Strings(cmds) for _, name := range cmds { cmd := commandMap[name] if sn := cmd.descr; sn != "" { alias := "" // Ignore undocumented commands if len(cmd.aliases) > 0 { alias = " (" + strings.Join(cmd.aliases, ", ") + ")" } tw.Write([]byte(fmt.Sprintf(" %s%s\t%s\n", ansi.Bold(ansi.Cyan(name)), ansi.Cyan(alias), sn))) } } tw.Flush() fmt.Fprintln(w, "\n Commands can be abbreviated to their unique prefix.\n") fmt.Fprintln(w, ansi.Bold("Examples:")) examples := [][]string{ {" mole ls", "# show all available tunnels"}, {" mole l foo", "# show all available tunnels matching the regexp \"foo\""}, {" mole show foo", "# show the hosts and forwards in the tunnel \"foo\""}, {" sudo mole dig foo", "# dig the tunnel \"foo\""}, {" sudo mole -d d foo", "# dig the tunnel \"foo\", while showing debug output"}, {" mole push foo.ini", "# create or update the \"foo\" tunnel from a local file"}, {" mole install", "# list packages available for installation"}, {" mole ins vpnc", "# install a package named vpnc"}, {" mole up -force", "# perform a forced up/downgrade to the server version"}, } optionTable(w, examples) w.Write([]byte("\n")) }
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 } }