func init() { pool := x509.NewCertPool() ngrokRootCrt, err := assets.ReadAsset("assets/client/tls/ngrokroot.crt") if err != nil { panic(err) } snakeoilCaCrt, err := assets.ReadAsset("assets/client/tls/snakeoilca.crt") if err != nil { panic(err) } for _, b := range [][]byte{ngrokRootCrt, snakeoilCaCrt} { pemBlock, _ := pem.Decode(b) if pemBlock == nil { panic("Bad PEM data") } certs, err := x509.ParseCertificates(pemBlock.Bytes) if err != nil { panic(err) } pool.AddCert(certs[0]) } tlsConfig = &tls.Config{ RootCAs: pool, ServerName: "tls.ngrok.com", } }
func LoadTLSConfig(rootCertPaths []string) (*tls.Config, error) { pool := x509.NewCertPool() for _, certPath := range rootCertPaths { rootCrt, err := assets.ReadAsset(certPath) if err != nil { return nil, err } pemBlock, _ := pem.Decode(rootCrt) if pemBlock == nil { return nil, fmt.Errorf("Bad PEM data") } certs, err := x509.ParseCertificates(pemBlock.Bytes) if err != nil { return nil, err } pool.AddCert(certs[0]) } return &tls.Config{ RootCAs: pool, ServerName: "ngrokd.ngrok.com", }, nil }
func (whv *WebHttpView) register() { http.HandleFunc("/http/in/replay", func(w http.ResponseWriter, r *http.Request) { defer func() { if r := recover(); r != nil { err := util.MakePanicTrace(r) whv.Error("Replay failed: %v", err) http.Error(w, err, 500) } }() r.ParseForm() txnid := r.Form.Get("txnid") if txn, ok := whv.idToTxn[txnid]; ok { reqBytes, err := base64.StdEncoding.DecodeString(txn.Req.Raw) if err != nil { panic(err) } whv.ctl.PlayRequest(txn.ConnCtx.Tunnel, reqBytes) w.Write([]byte(http.StatusText(200))) } else { http.Error(w, http.StatusText(400), 400) } }) http.HandleFunc("/http/in", func(w http.ResponseWriter, r *http.Request) { defer func() { if r := recover(); r != nil { err := util.MakePanicTrace(r) whv.Error("HTTP web view failed: %v", err) http.Error(w, err, 500) } }() pageTmpl, err := assets.ReadAsset("assets/client/page.html") if err != nil { panic(err) } tmpl := template.Must(template.New("page.html").Delims("{%", "%}").Parse(string(pageTmpl))) payloadData := SerializedPayload{ Txns: whv.HttpRequests.Slice(), UiState: SerializedUiState{Tunnels: whv.ctl.State().GetTunnels()}, } payload, err := json.Marshal(payloadData) if err != nil { panic(err) } // write the response if err := tmpl.Execute(w, string(payload)); err != nil { panic(err) } }) }
func NewWebView(ctl mvc.Controller, addr string) *WebView { wv := &WebView{ Logger: log.NewPrefixLogger("view", "web"), wsMessages: util.NewBroadcast(), ctl: ctl, } // for now, always redirect to the http view http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/http/in", 302) }) // handle web socket connections http.HandleFunc("/_ws", func(w http.ResponseWriter, r *http.Request) { conn, err := websocket.Upgrade(w, r.Header, nil, 1024, 1024) if err != nil { http.Error(w, "Failed websocket upgrade", 400) wv.Warn("Failed websocket upgrade: %v", err) return } msgs := wv.wsMessages.Reg() defer wv.wsMessages.UnReg(msgs) for m := range msgs { err := conn.WriteMessage(websocket.OpText, m.([]byte)) if err != nil { // connection is closed break } } }) // serve static assets http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) { buf, err := assets.ReadAsset(path.Join("assets", "client", r.URL.Path[1:])) if err != nil { wv.Warn("Error serving static file: %s", err.Error()) http.NotFound(w, r) return } w.Write(buf) }) wv.Info("Serving web interface on %s", addr) wv.ctl.Go(func() { http.ListenAndServe(addr, nil) }) return wv }
func NewWebView(ctl *ui.Controller, state ui.State, port int) *WebView { v := &WebView{ wsMessages: util.NewBroadcast(), } switch p := state.GetProtocol().(type) { case *proto.Http: NewWebHttpView(v, ctl, p) } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/http/in", 302) }) http.HandleFunc("/_ws", func(w http.ResponseWriter, r *http.Request) { conn, err := websocket.Upgrade(w, r.Header, nil, 1024, 1024) if err != nil { http.Error(w, "Failed websocket upgrade", 400) log.Warn("Failed websocket upgrade: %v", err) return } msgs := v.wsMessages.Reg() defer v.wsMessages.UnReg(msgs) for m := range msgs { err := conn.WriteMessage(websocket.OpText, m.([]byte)) if err != nil { // connection is closed break } } }) http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) { buf, err := assets.ReadAsset(path.Join("assets", "client", r.URL.Path[1:])) if err != nil { log.Warn("Error serving static file: %s", err.Error()) http.NotFound(w, r) return } w.Write(buf) }) log.Info("Serving web interface on localhost:%d", port) go http.ListenAndServe(fmt.Sprintf(":%d", port), nil) return v }
func (h *WebHttpView) register() { http.HandleFunc("/http/in/replay", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() txnid := r.Form.Get("txnid") if txn, ok := h.idToTxn[txnid]; ok { bodyBytes, err := httputil.DumpRequestOut(txn.HttpTxn.Req.Request, true) if err != nil { panic(err) } h.ctl.Cmds <- ui.CmdRequest{Payload: bodyBytes} w.Write([]byte(http.StatusText(200))) } else { // XXX: 400 http.NotFound(w, r) } }) http.HandleFunc("/http/in", func(w http.ResponseWriter, r *http.Request) { pageTmpl, err := assets.ReadAsset("assets/client/page.html") if err != nil { panic(err) } tmpl := template.Must(template.New("page.html").Delims("{%", "%}").Parse(string(pageTmpl))) payloadData := SerializedPayload{ Txns: h.HttpRequests.Slice(), UiState: <-h.state, } payload, err := json.Marshal(payloadData) if err != nil { panic(err) } // write the response if err := tmpl.Execute(w, string(payload)); err != nil { panic(err) } }) }