// NewStack returns a martian modifier stack that handles ensuring proper proxy // behavior, in addition to a fifo.Group that can be used to add additional // modifiers within the stack. func NewStack(via string) (outer *fifo.Group, inner *fifo.Group) { outer = fifo.NewGroup() hbhm := header.NewHopByHopModifier() outer.AddRequestModifier(hbhm) outer.AddRequestModifier(header.NewForwardedModifier()) outer.AddRequestModifier(header.NewBadFramingModifier()) vm := header.NewViaModifier(via) outer.AddRequestModifier(vm) inner = fifo.NewGroup() outer.AddRequestModifier(inner) outer.AddResponseModifier(inner) outer.AddResponseModifier(vm) outer.AddResponseModifier(hbhm) return outer, inner }
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) 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() var mitm *martian.MITM if *cert != "" && *key != "" { tlsc, err := tls.LoadX509KeyPair(*cert, *key) if err != nil { log.Fatal(err) } x509c, err := x509.ParseCertificate(tlsc.Certificate[0]) if err != nil { log.Fatal(err) } var pub crypto.PublicKey switch priv := tlsc.PrivateKey.(type) { case *rsa.PrivateKey: pub = &priv.PublicKey case *ecdsa.PrivateKey: pub = &priv.PublicKey default: log.Fatal("Public key is not of supported type: rsa, ecdsa.") } mitm = &martian.MITM{ Authority: x509c, PublicKey: pub, PrivateKey: tlsc.PrivateKey, Validity: *validity, Organization: *organization, } } p := martian.NewProxy(mitm) fg := fifo.NewGroup() hbhmod := header.NewHopByHopModifier() fg.AddRequestModifier(hbhmod) fg.AddRequestModifier(header.NewForwardedModifier()) fg.AddRequestModifier(header.NewBadFramingModifier()) fg.AddRequestModifier(header.NewViaModifier("martian 1.1")) m := martianhttp.NewModifier() fg.AddRequestModifier(m) fg.AddResponseModifier(m) fg.AddResponseModifier(hbhmod) p.SetRequestModifier(fg) p.SetResponseModifier(fg) // Proxy specific handlers. // These handlers take precendence over proxy traffic and will not be // intercepted. // Update modifiers. configure("martian/modifiers", m) // Verify assertions. vh := verify.NewHandler() vh.SetRequestVerifier(m) vh.SetResponseVerifier(m) configure("martian/verify", vh) // Reset verifications. rh := verify.NewResetHandler() rh.SetRequestVerifier(m) rh.SetResponseVerifier(m) configure("martian/verify/reset", rh) // Forward all other requests to the proxy. http.Handle("/", p) log.Printf("Martian started at %s", *addr) log.Fatal(http.ListenAndServe(*addr, nil)) }