func main() { flag.Parse() p := martian.NewProxy() var x509c *x509.Certificate var priv interface{} if *generateCA { var err error x509c, priv, err = mitm.NewAuthority("martian.proxy", "Martian Authority", 30*24*time.Hour) if err != nil { log.Fatal(err) } } else if *cert != "" && *key != "" { tlsc, err := tls.LoadX509KeyPair(*cert, *key) if err != nil { log.Fatal(err) } priv = tlsc.PrivateKey x509c, err = x509.ParseCertificate(tlsc.Certificate[0]) if err != nil { log.Fatal(err) } } if x509c != nil && priv != nil { mc, err := mitm.NewConfig(x509c, priv) if err != nil { log.Fatal(err) } mc.SetValidity(*validity) mc.SetOrganization(*organization) p.SetMITM(mc) // Expose certificate authority. ah := martianhttp.NewAuthorityHandler(x509c) configure("/authority.cer", ah) } fg := fifo.NewGroup() hbhm := header.NewHopByHopModifier() fg.AddRequestModifier(hbhm) fg.AddRequestModifier(header.NewForwardedModifier()) fg.AddRequestModifier(header.NewBadFramingModifier()) vm := header.NewViaModifier("martian") fg.AddRequestModifier(vm) m := martianhttp.NewModifier() fg.AddRequestModifier(m) fg.AddResponseModifier(m) fg.AddResponseModifier(hbhm) fg.AddResponseModifier(vm) if *harLogging { hl := har.NewLogger("martian", "2.0.0") fg.AddRequestModifier(hl) fg.AddResponseModifier(hl) configure("/har/logs", har.NewExportHandler(hl)) configure("/har/logs/reset", har.NewResetHandler(hl)) } p.SetRequestModifier(fg) p.SetResponseModifier(fg) // Proxy specific handlers. // These handlers take precendence over proxy traffic and will not be // intercepted. // Configure modifiers. configure("/configure", m) // Verify assertions. vh := verify.NewHandler() vh.SetRequestVerifier(m) vh.SetResponseVerifier(m) configure("/verify", vh) // Reset verifications. rh := verify.NewResetHandler() rh.SetRequestVerifier(m) rh.SetResponseVerifier(m) configure("/verify/reset", rh) l, err := net.Listen("tcp", *addr) if err != nil { log.Fatal(err) } log.Println("martian: proxy started on:", l.Addr()) go p.Serve(l) sigc := make(chan os.Signal, 1) signal.Notify(sigc, os.Interrupt, os.Kill) <-sigc log.Println("martian: shutting down") }
func main() { flag.Parse() mlog.SetLevel(*level) p := martian.NewProxy() // Respond with 404 to any unknown proxy path. http.HandleFunc(*api+"/", http.NotFound) var x509c *x509.Certificate var priv interface{} if *generateCA { var err error x509c, priv, err = mitm.NewAuthority("martian.proxy", "Martian Authority", 30*24*time.Hour) if err != nil { log.Fatal(err) } } else if *cert != "" && *key != "" { tlsc, err := tls.LoadX509KeyPair(*cert, *key) if err != nil { log.Fatal(err) } priv = tlsc.PrivateKey x509c, err = x509.ParseCertificate(tlsc.Certificate[0]) if err != nil { log.Fatal(err) } } if x509c != nil && priv != nil { mc, err := mitm.NewConfig(x509c, priv) if err != nil { log.Fatal(err) } mc.SetValidity(*validity) mc.SetOrganization(*organization) mc.SkipTLSVerify(*skipTLSVerify) p.SetMITM(mc) // Expose certificate authority. ah := martianhttp.NewAuthorityHandler(x509c) configure("/authority.cer", ah) // Start TLS listener for transparent MITM. tl, err := net.Listen("tcp", *tlsAddr) if err != nil { log.Fatal(err) } go p.Serve(tls.NewListener(tl, mc.TLS())) } stack, fg := httpspec.NewStack("martian") p.SetRequestModifier(stack) p.SetResponseModifier(stack) m := martianhttp.NewModifier() fg.AddRequestModifier(m) fg.AddResponseModifier(m) if *harLogging { hl := har.NewLogger("martian", "2.0.0") stack.AddRequestModifier(hl) stack.AddResponseModifier(hl) configure("/logs", har.NewExportHandler(hl)) configure("/logs/reset", har.NewResetHandler(hl)) } // Proxy specific handlers. // These handlers take precendence over proxy traffic and will not be // intercepted. // Configure modifiers. configure("/configure", m) // Verify assertions. vh := verify.NewHandler() vh.SetRequestVerifier(m) vh.SetResponseVerifier(m) configure("/verify", vh) // Reset verifications. rh := verify.NewResetHandler() rh.SetRequestVerifier(m) rh.SetResponseVerifier(m) configure("/verify/reset", rh) l, err := net.Listen("tcp", *addr) if err != nil { log.Fatal(err) } if *trafficShaping { tsl := trafficshape.NewListener(l) tsh := trafficshape.NewHandler(tsl) configure("/shape-traffic", tsh) l = tsl } log.Println("martian: proxy started on:", l.Addr()) go p.Serve(l) sigc := make(chan os.Signal, 1) signal.Notify(sigc, os.Interrupt, os.Kill) <-sigc log.Println("martian: shutting down") }
// StartWithCertificate runs a proxy on addr and configures a cert for MITM func StartWithCertificate(proxyAddr string, cert string, key string) (*Martian, error) { flag.Set("logtostderr", "true") signal.Ignore(syscall.SIGPIPE) l, err := net.Listen("tcp", proxyAddr) if err != nil { return nil, err } mlog.Debugf("mobileproxy: started listener: %v", l.Addr()) p := martian.NewProxy() mux := http.NewServeMux() p.SetMux(mux) if cert != "" && key != "" { tlsc, err := tls.X509KeyPair([]byte(cert), []byte(key)) if err != nil { log.Fatal(err) } mlog.Debugf("mobileproxy: loaded cert and key") x509c, err := x509.ParseCertificate(tlsc.Certificate[0]) if err != nil { log.Fatal(err) } mlog.Debugf("mobileproxy: parsed cert") mc, err := mitm.NewConfig(x509c, tlsc.PrivateKey) if err != nil { log.Fatal(err) } mc.SetValidity(12 * time.Hour) mc.SetOrganization("Martian Proxy") p.SetMITM(mc) mux.Handle("martian.proxy/authority.cer", martianhttp.NewAuthorityHandler(x509c)) mlog.Debugf("mobileproxy: install cert from http://martian.proxy/authority.cer") } stack, fg := httpspec.NewStack("martian.mobileproxy") p.SetRequestModifier(stack) p.SetResponseModifier(stack) // add HAR logger hl := har.NewLogger() stack.AddRequestModifier(hl) stack.AddResponseModifier(hl) m := martianhttp.NewModifier() fg.AddRequestModifier(m) fg.AddResponseModifier(m) mlog.Debugf("mobileproxy: set martianhttp modifier") // Proxy specific handlers. // These handlers take precendence over proxy traffic and will not be intercepted. // Retrieve HAR logs mux.Handle("martian.proxy/logs", har.NewExportHandler(hl)) mux.Handle("martian.proxy/logs/reset", har.NewResetHandler(hl)) // Update modifiers. mux.Handle("martian.proxy/configure", m) mlog.Debugf("mobileproxy: configure with requests to http://martian.proxy/configure") // Verify assertions. vh := verify.NewHandler() vh.SetRequestVerifier(m) vh.SetResponseVerifier(m) mux.Handle("martian.proxy/verify", vh) mlog.Debugf("mobileproxy: check verifications with requests to http://martian.proxy/verify") // Reset verifications. rh := verify.NewResetHandler() rh.SetRequestVerifier(m) rh.SetResponseVerifier(m) mux.Handle("martian.proxy/verify/reset", rh) mlog.Debugf("mobileproxy: reset verifications with requests to http://martian.proxy/verify/reset") go p.Serve(l) mlog.Infof("mobileproxy: started proxy on listener") return &Martian{ proxy: p, listener: l, mux: mux, }, nil }