Example #1
0
// Serve starts up an HTTP server using http.DefaultServerMux to handle
// requests.  This server will server over TLS, using the certs
// stored in c.CertPath to verify itself to clients and verify clients.
func (e *Env) Serve() error {
	caCert, caKey, clientCert, clientKey, serverCert, serverKey :=
		filepath.Join(e.conf.CertPath, caCertFilename),
		filepath.Join(e.conf.CertPath, caKeyFilename),
		filepath.Join(e.conf.CertPath, clientCertFilename),
		filepath.Join(e.conf.CertPath, clientKeyFilename),
		filepath.Join(e.conf.CertPath, serverCertFilename),
		filepath.Join(e.conf.CertPath, serverKeyFilename)
	if err := certs.WriteNewCerts(caCert, caKey, "", CA); err != nil {
		return fmt.Errorf("cannot write ca certs: %v", err)
	}
	if err := certs.WriteNewCerts(clientCert, clientKey, caKey, Client); err != nil {
		return fmt.Errorf("cannot write client certs: %v", err)
	}
	if err := certs.WriteNewCerts(serverCert, serverKey, caKey, Server); err != nil {
		return fmt.Errorf("cannot write server certs: %v", err)
	}
	tlsConfig, err := certs.ClientVerifyingTLSConfig(caCert)
	if err != nil {
		return fmt.Errorf("cannot verify client cert: %v", err)
	}
	server := &http.Server{
		Addr:      fmt.Sprintf("%s:%d", e.conf.Host, e.conf.Port),
		TLSConfig: tlsConfig,
	}
	http.HandleFunc("/query", func(w http.ResponseWriter, r *http.Request) {
		w = httputil.Log(w, r, true)
		defer log.Print(w)
		queryBytes, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "could not read request body", http.StatusBadRequest)
			return
		}
		q, err := query.NewQuery(string(queryBytes))
		if err != nil {
			http.Error(w, "could not parse query", http.StatusBadRequest)
			return
		}
		ctx, cancel := httputil.Context(w, r, time.Minute*15)
		defer cancel()
		packets := e.Lookup(ctx, q)
		w.Header().Set("Content-Type", "appliation/octet-stream")
		base.PacketsToFile(packets, w)
	})
	http.Handle("/debug/stats", stats.S)
	return server.ListenAndServeTLS(serverCert, serverKey)
}
Example #2
0
// ExportDebugHandlers exports a set of HTTP handlers on /debug/t<thread id> for
// querying internal state from this thread.
func (t *Thread) ExportDebugHandlers(mux *http.ServeMux) {
	prefix := fmt.Sprintf("/debug/t%d", t.id)
	mux.HandleFunc(prefix+"/files", func(w http.ResponseWriter, r *http.Request) {
		w = httputil.Log(w, r, false)
		defer log.Print(w)
		w.Header().Set("Content-Type", "text/plain")
		fmt.Fprintf(w, "Thread %d (IDX: %q, PKT: %q)\n", t.id, t.indexPath, t.packetPath)
		t.mu.RLock()
		for name := range t.files {
			fmt.Fprintf(w, "\t%v\n", name)
		}
		t.mu.RUnlock()
	})
	mux.HandleFunc(prefix+"/index", func(w http.ResponseWriter, r *http.Request) {
		w = httputil.Log(w, r, false)
		defer log.Print(w)
		t.mu.RLock()
		defer t.mu.RUnlock()
		vals := r.URL.Query()
		file := t.files[vals.Get("name")]
		if file == nil {
			http.Error(w, "file not found", http.StatusNotFound)
			return
		}
		var start, finish []byte
		var err error
		if s := vals.Get("start"); s != "" {
			start, err = hex.DecodeString(s)
			if err != nil {
				http.Error(w, "bad start", http.StatusBadRequest)
				return
			}
		}
		if f := vals.Get("finish"); f != "" {
			finish, err = hex.DecodeString(f)
			if err != nil {
				http.Error(w, "bad finish", http.StatusBadRequest)
				return
			}
		}
		w.Header().Set("Content-Type", "text/plain")
		file.DumpIndex(w, start, finish)
	})
	mux.HandleFunc(prefix+"/packets", func(w http.ResponseWriter, r *http.Request) {
		w = httputil.Log(w, r, false)
		defer log.Print(w)
		t.mu.RLock()
		defer t.mu.RUnlock()
		vals := r.URL.Query()
		file := t.files[vals.Get("name")]
		if file == nil {
			http.Error(w, "file not found", http.StatusNotFound)
			return
		}
		w.Header().Set("Content-Type", "application/octet-stream")
		base.PacketsToFile(file.AllPackets(), w)
	})
	mux.HandleFunc(prefix+"/positions", func(w http.ResponseWriter, r *http.Request) {
		w = httputil.Log(w, r, true)
		defer log.Print(w)
		t.mu.RLock()
		defer t.mu.RUnlock()
		vals := r.URL.Query()
		file := t.files[vals.Get("name")]
		if file == nil {
			http.Error(w, "file not found", http.StatusNotFound)
			return
		}
		queryBytes, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "could not read request body", http.StatusBadRequest)
			return
		}
		queryStr := string(queryBytes)
		q, err := query.NewQuery(queryStr)
		if err != nil {
			http.Error(w, "could not parse query", http.StatusBadRequest)
			return
		}
		w.Header().Set("Content-Type", "text/plain")
		positions, err := file.Positions(context.Background(), q)
		if err != nil {
			fmt.Fprintf(w, "ERROR: %v", err)
			return
		}
		fmt.Fprintf(w, "POSITIONS:\n")
		if positions.IsAllPositions() {
			fmt.Fprintf(w, "\tALL")
		} else {
			var buf [4]byte
			for _, pos := range positions {
				binary.BigEndian.PutUint32(buf[:], uint32(pos))
				fmt.Fprintf(w, "\t%v\n", hex.EncodeToString(buf[:]))
			}
		}
	})
}