예제 #1
0
파일: rdpproxy.go 프로젝트: phuslu/cmdhere
func forward(lconn net.Conn, raddr string) {
	if err := exec.Command("wakeonlan", "18:66:DA:17:A2:95").Run(); err != nil {
		glog.Warningf("exec wakeonlan error: %+v", err)
	}

	glog.Infof("try connect to %+v for %+v forwarding", raddr, lconn.RemoteAddr())
	rconn, err := net.Dial("tcp", raddr)
	if err != nil {
		glog.Errorf("net.Dial(%#v) error: %v", raddr, err)
		return
	}

	glog.Infof("forward %+v to %+v", lconn.RemoteAddr(), rconn.RemoteAddr())
	go func() {
		buf := bufpool.Get().([]byte)
		defer bufpool.Put(buf)
		defer rconn.Close()
		defer lconn.Close()
		io.CopyBuffer(rconn, lconn, buf)
	}()
	go func() {
		buf := bufpool.Get().([]byte)
		defer bufpool.Put(buf)
		defer lconn.Close()
		defer rconn.Close()
		io.CopyBuffer(lconn, rconn, buf)
	}()
}
예제 #2
0
파일: httpproxy.go 프로젝트: phuslu/goagent
func ServeProfile(profile string, branding string) error {
	config, ok := Config[profile]
	if !ok {
		return fmt.Errorf("profile(%#v) not exists", profile)
	}

	listenOpts := &helpers.ListenOptions{TLSConfig: nil}

	ln, err := helpers.ListenTCP("tcp", config.Address, listenOpts)
	if err != nil {
		glog.Fatalf("ListenTCP(%s, %#v) error: %s", config.Address, listenOpts, err)
	}

	requestFilters, roundtripFilters, responseFilters := getFilters(profile)

	h := Handler{
		Listener:         ln,
		RequestFilters:   requestFilters,
		RoundTripFilters: roundtripFilters,
		ResponseFilters:  responseFilters,
		Branding:         branding,
	}

	s := &http.Server{
		Handler:        h,
		ReadTimeout:    time.Duration(config.ReadTimeout) * time.Second,
		WriteTimeout:   time.Duration(config.WriteTimeout) * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	glog.Infof("ListenAndServe(%#v) on %s\n", profile, h.Listener.Addr().String())
	return s.Serve(h.Listener)
}
예제 #3
0
파일: rdpproxy.go 프로젝트: phuslu/cmdhere
func main() {
	var laddr, raddr string
	flag.StringVar(&laddr, "laddr", "0.0.0.0:13389", "local address")
	flag.StringVar(&raddr, "raddr", "192.168.1.3:3389", "remote address")

	flag.Parse()

	ln, err := net.Listen("tcp", laddr)
	if err != nil {
		glog.Fatalf("net.Listen(%+v) error: %+v", laddr, err)
		return
	}
	defer ln.Close()

	glog.Infof("Serving on %+v", ln.Addr())
	for {
		conn, err := ln.Accept()
		if err != nil {
			glog.Fatalf("%+v Accept error: %+v", ln.Addr(), err)
		}
		go forward(conn, raddr)
	}
}
예제 #4
0
func (f *Filter) updater() {
	glog.V(2).Infof("start updater for %+v, expiry=%s, duration=%s", f.GFWList.URL.String(), f.GFWList.Expiry, f.GFWList.Duration)

	ticker := time.Tick(f.GFWList.Duration)

	for {
		select {
		case <-ticker:
			glog.V(2).Infof("Begin auto gfwlist(%#v) update...", f.GFWList.URL.String())
			h, err := f.Store.HeadObject(f.GFWList.Filename)
			if err != nil {
				glog.Warningf("stat gfwlist(%#v) err: %v", f.GFWList.Filename, err)
				continue
			}

			lm := h.Get("Last-Modified")
			if lm == "" {
				glog.Warningf("gfwlist(%#v) header(%#v) does not contains last-modified", f.GFWList.Filename, h)
				continue
			}

			modTime, err := time.Parse(f.Store.DateFormat(), lm)
			if err != nil {
				glog.Warningf("stat gfwlist(%#v) has parse %#v error: %v", f.GFWList.Filename, lm, err)
				continue
			}

			if time.Now().Sub(modTime) < f.GFWList.Expiry {
				continue
			}
		}

		glog.Infof("Downloading %#v", f.GFWList.URL.String())

		req, err := http.NewRequest(http.MethodGet, f.GFWList.URL.String(), nil)
		if err != nil {
			glog.Warningf("NewRequest(%#v) error: %v", f.GFWList.URL.String(), err)
			continue
		}

		resp, err := f.Transport.RoundTrip(req)
		if err != nil {
			glog.Warningf("%T.RoundTrip(%#v) error: %v", f.Transport, f.GFWList.URL.String(), err.Error())
			continue
		}

		var r io.Reader = resp.Body
		switch f.GFWList.Encoding {
		case "base64":
			r = base64.NewDecoder(base64.StdEncoding, r)
		default:
			break
		}

		data, err := ioutil.ReadAll(r)
		if err != nil {
			glog.Warningf("ioutil.ReadAll(%T) error: %v", r, err)
			resp.Body.Close()
			continue
		}

		err = f.Store.DeleteObject(f.GFWList.Filename)
		if err != nil {
			glog.Warningf("%T.DeleteObject(%#v) error: %v", f.Store, f.GFWList.Filename, err)
			continue
		}

		err = f.Store.PutObject(f.GFWList.Filename, http.Header{}, ioutil.NopCloser(bytes.NewReader(data)))
		if err != nil {
			glog.Warningf("%T.PutObject(%#v) error: %v", f.Store, f.GFWList.Filename, err)
			continue
		}

		glog.Infof("Update %#v from %#v OK", f.GFWList.Filename, f.GFWList.URL.String())
		resp.Body.Close()
	}
}
예제 #5
0
파일: rootca.go 프로젝트: phuslu/goagent
func NewRootCA(name string, vaildFor time.Duration, rsaBits int, certDir string, portable bool) (*RootCA, error) {
	keyFile := name + ".key"
	certFile := name + ".crt"

	var store storage.Store
	if portable {
		exe, err := os.Executable()
		if err != nil {
			glog.Fatalf("os.Executable() error: %+v", err)
		}
		store = &storage.FileStore{filepath.Dir(exe)}
	} else {
		store = &storage.FileStore{"."}
	}

	rootCA := &RootCA{
		store:    store,
		name:     name,
		keyFile:  keyFile,
		certFile: certFile,
		rsaBits:  rsaBits,
		certDir:  certDir,
		mu:       new(sync.Mutex),
	}

	if storage.NotExist(store, certFile) {
		glog.Infof("Generating RootCA for %s/%s", keyFile, certFile)
		template := x509.Certificate{
			IsCA:         true,
			SerialNumber: big.NewInt(1),
			Subject: pkix.Name{
				CommonName:   name,
				Country:      []string{"US"},
				Province:     []string{"California"},
				Locality:     []string{"Los Angeles"},
				Organization: []string{name},
				ExtraNames: []pkix.AttributeTypeAndValue{
					{
						Type:  []int{2, 5, 4, 42},
						Value: name,
					},
				},
			},
			DNSNames: []string{name},

			NotBefore: time.Now().Add(-time.Duration(30 * 24 * time.Hour)),
			NotAfter:  time.Now().Add(vaildFor),

			KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
			ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
			BasicConstraintsValid: true,
			// AuthorityKeyId:        sha1.New().Sum([]byte("phuslu")),
			// SubjectKeyId:          sha1.New().Sum([]byte("phuslu")),
		}

		priv, err := rsa.GenerateKey(rand.Reader, rsaBits)
		if err != nil {
			return nil, err
		}

		derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
		if err != nil {
			return nil, err
		}

		ca, err := x509.ParseCertificate(derBytes)
		if err != nil {
			return nil, err
		}

		rootCA.ca = ca
		rootCA.priv = priv
		rootCA.derBytes = derBytes

		keypem := &pem.Block{Type: "PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(rootCA.priv)}
		rc := ioutil.NopCloser(bytes.NewReader(pem.EncodeToMemory(keypem)))
		if _, err = store.Put(keyFile, http.Header{}, rc); err != nil {
			return nil, err
		}

		certpem := &pem.Block{Type: "CERTIFICATE", Bytes: rootCA.derBytes}
		rc = ioutil.NopCloser(bytes.NewReader(pem.EncodeToMemory(certpem)))
		if _, err = store.Put(certFile, http.Header{}, rc); err != nil {
			return nil, err
		}
	} else {
		for _, name := range []string{keyFile, certFile} {
			resp, err := store.Get(name)
			if err != nil {
				return nil, err
			}

			data, err := ioutil.ReadAll(resp.Body)
			resp.Body.Close()
			if err != nil {
				return nil, err
			}

			var b *pem.Block
			for {
				b, data = pem.Decode(data)
				if b == nil {
					break
				}
				switch b.Type {
				case "CERTIFICATE":
					rootCA.derBytes = b.Bytes
					ca, err := x509.ParseCertificate(rootCA.derBytes)
					if err != nil {
						return nil, err
					}
					rootCA.ca = ca
				case "PRIVATE KEY", "PRIVATE RSA KEY":
					priv, err := x509.ParsePKCS1PrivateKey(b.Bytes)
					if err != nil {
						return nil, err
					}
					rootCA.priv = priv
				}
			}
		}
	}

	switch runtime.GOOS {
	case "windows", "darwin":
		if _, err := rootCA.ca.Verify(x509.VerifyOptions{}); err != nil {
			glog.Warningf("Verify RootCA(%#v) error: %v, try import to system root", name, err)
			if err = helpers.RemoveCAFromSystemRoot(rootCA.name); err != nil {
				glog.Errorf("Remove Old RootCA(%#v) error: %v", name, err)
			}
			if err = helpers.ImportCAToSystemRoot(rootCA.ca); err != nil {
				glog.Errorf("Import RootCA(%#v) error: %v", name, err)
			} else {
				glog.Infof("Import RootCA(%s) OK", certFile)
			}

			if fs, err := store.List(certDir); err == nil {
				for _, f := range fs {
					if _, err = store.Delete(f); err != nil {
						glog.Errorf("%T.Delete(%#v) error: %v", store, f, err)
					}
				}
			}
		}
	}

	if fs, ok := store.(*storage.FileStore); ok {
		if storage.NotExist(store, certDir) {
			if err := os.Mkdir(filepath.Join(fs.Dirname, certDir), 0777); err != nil {
				return nil, err
			}
		}
	}

	return rootCA, nil
}
예제 #6
0
파일: handler.go 프로젝트: johnsonz/goproxy
func (h Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	var err error

	remoteAddr := req.RemoteAddr

	// Prepare filter.Context
	ctx := filters.NewContext(req.Context(), h, h.Listener, rw, h.Branding)
	req = req.WithContext(ctx)

	// Enable transport http proxy
	if req.Method != "CONNECT" && !req.URL.IsAbs() {
		if req.URL.Scheme == "" {
			if req.TLS != nil && req.ProtoMajor == 1 {
				req.URL.Scheme = "https"
			} else {
				req.URL.Scheme = "http"
			}
		}

		if req.TLS != nil {
			if req.Host == "" {
				if req.URL.Host != "" {
					req.Host = req.URL.Host
				} else {
					req.Host = req.TLS.ServerName
				}
			}
			if req.URL.Host == "" {
				if req.Host != "" {
					req.URL.Host = req.Host
				} else {
					req.URL.Host = req.TLS.ServerName
				}
			}
		}
	}

	// Filter Request
	for _, f := range h.RequestFilters {
		ctx, req, err = f.Request(ctx, req)
		if req == filters.DummyRequest {
			return
		}
		if err != nil {
			if err != io.EOF {
				glog.Errorf("%s Filter Request %T error: %+v", remoteAddr, f, err)
			}
			return
		}
		// Update context for request
		req = req.WithContext(ctx)
	}

	if req.Body != nil {
		defer req.Body.Close()
	}

	// Filter Request -> Response
	var resp *http.Response
	for _, f := range h.RoundTripFilters {
		ctx, resp, err = f.RoundTrip(ctx, req)
		if resp == filters.DummyResponse {
			return
		}
		// Unexcepted errors
		if err != nil {
			filters.SetRoundTripFilter(ctx, f)
			glog.Errorf("%s Filter RoundTrip %T error: %+v", remoteAddr, f, err)
			http.Error(rw, h.FormatError(ctx, err), http.StatusBadGateway)
			return
		}
		// Update context for request
		req = req.WithContext(ctx)
		// A roundtrip filter give a response
		if resp != nil {
			resp.Request = req
			filters.SetRoundTripFilter(ctx, f)
			break
		}
	}

	// Filter Response
	for _, f := range h.ResponseFilters {
		if resp == nil || resp == filters.DummyResponse {
			return
		}
		ctx, resp, err = f.Response(ctx, resp)
		if err != nil {
			glog.Errorln("%s Filter %T Response error: %+v", remoteAddr, f, err)
			http.Error(rw, h.FormatError(ctx, err), http.StatusBadGateway)
			return
		}
		// Update context for request
		req = req.WithContext(ctx)
	}

	if resp == nil {
		glog.Errorln("%s Handler %#v Response empty response", remoteAddr, h)
		http.Error(rw, h.FormatError(ctx, fmt.Errorf("empty response")), http.StatusBadGateway)
		return
	}

	if resp.Header.Get("Content-Length") == "" && resp.ContentLength >= 0 {
		resp.Header.Set("Content-Length", strconv.FormatInt(resp.ContentLength, 10))
	}
	for key, values := range resp.Header {
		for _, value := range values {
			rw.Header().Add(key, value)
		}
	}
	rw.WriteHeader(resp.StatusCode)
	if resp.Body != nil {
		defer resp.Body.Close()
		n, err := helpers.IOCopy(rw, resp.Body)
		if err != nil {
			if isClosedConnError(err) {
				glog.Infof("IOCopy %#v return %#v %T(%v)", resp.Body, n, err, err)
			} else {
				glog.Warningf("IOCopy %#v return %#v %T(%v)", resp.Body, n, err, err)
			}
		}
	}
}
예제 #7
0
func NewRootCA(name string, vaildFor time.Duration, rsaBits int, certDir string, portable bool) (*RootCA, error) {
	keyFile := name + ".key"
	certFile := name + ".crt"

	if portable {
		rootdir := filepath.Dir(os.Args[0])
		keyFile = filepath.Join(rootdir, keyFile)
		certFile = filepath.Join(rootdir, certFile)
		certDir = filepath.Join(rootdir, certDir)
	}

	rootCA := &RootCA{
		name:     name,
		keyFile:  keyFile,
		certFile: certFile,
		rsaBits:  rsaBits,
		certDir:  certDir,
		mu:       new(sync.Mutex),
	}

	if _, err := os.Stat(certFile); os.IsNotExist(err) {
		glog.Infof("Generating RootCA for %s", certFile)
		template := x509.Certificate{
			IsCA:         true,
			SerialNumber: big.NewInt(1),
			Subject: pkix.Name{
				CommonName:   name,
				Organization: []string{name},
			},
			NotBefore: time.Now().Add(-time.Duration(30 * 24 * time.Hour)),
			NotAfter:  time.Now().Add(vaildFor),

			KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
			ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
			BasicConstraintsValid: true,
		}

		priv, err := rsa.GenerateKey(rand.Reader, rsaBits)
		if err != nil {
			return nil, err
		}

		derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
		if err != nil {
			return nil, err
		}

		ca, err := x509.ParseCertificate(derBytes)
		if err != nil {
			return nil, err
		}

		rootCA.ca = ca
		rootCA.priv = priv
		rootCA.derBytes = derBytes

		keypem := &pem.Block{Type: "PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(rootCA.priv)}
		if err = ioutil.WriteFile(keyFile, pem.EncodeToMemory(keypem), 0755); err != nil {
			return nil, err
		}

		certpem := &pem.Block{Type: "CERTIFICATE", Bytes: rootCA.derBytes}
		if err = ioutil.WriteFile(certFile, pem.EncodeToMemory(certpem), 0755); err != nil {
			return nil, err
		}
	} else {
		data, err := ioutil.ReadFile(keyFile)
		if err != nil {
			return nil, err
		}

		var b *pem.Block
		for {
			b, data = pem.Decode(data)
			if b == nil {
				break
			}
			if b.Type == "CERTIFICATE" {
				rootCA.derBytes = b.Bytes
				ca, err := x509.ParseCertificate(rootCA.derBytes)
				if err != nil {
					return nil, err
				}
				rootCA.ca = ca
			} else if b.Type == "PRIVATE KEY" {
				priv, err := x509.ParsePKCS1PrivateKey(b.Bytes)
				if err != nil {
					return nil, err
				}
				rootCA.priv = priv
			}
		}

		data, err = ioutil.ReadFile(certFile)
		if err != nil {
			return nil, err
		}

		for {
			b, data = pem.Decode(data)
			if b == nil {
				break
			}
			if b.Type == "CERTIFICATE" {
				rootCA.derBytes = b.Bytes
				ca, err := x509.ParseCertificate(rootCA.derBytes)
				if err != nil {
					return nil, err
				}
				rootCA.ca = ca
			} else if b.Type == "PRIVATE KEY" {
				priv, err := x509.ParsePKCS1PrivateKey(b.Bytes)
				if err != nil {
					return nil, err
				}
				rootCA.priv = priv
			}
		}
	}

	switch runtime.GOOS {
	case "windows", "darwin":
		if _, err := rootCA.ca.Verify(x509.VerifyOptions{}); err != nil {
			glog.Warningf("Verify RootCA(%#v) error: %v, try import to system root", name, err)
			if err = helpers.RemoveCAFromSystemRoot(rootCA.name); err != nil {
				glog.Errorf("Remove Old RootCA(%#v) error: %v", name, err)
			}
			if err = helpers.ImportCAToSystemRoot(rootCA.ca); err != nil {
				glog.Errorf("Import RootCA(%#v) error: %v", name, err)
			} else {
				glog.Infof("Import RootCA(%s) OK", certFile)
			}

			if fis, err := ioutil.ReadDir(certDir); err == nil {
				for _, fi := range fis {
					if err = os.Remove(certDir + "/" + fi.Name()); err != nil {
						glog.Errorf("Remove(%#v) error: %v", fi.Name(), err)
					}
				}
			}
		}
	}

	if _, err := os.Stat(certDir); os.IsNotExist(err) {
		if err = os.Mkdir(certDir, 0755); err != nil {
			return nil, err
		}
	}

	return rootCA, nil
}