Skip to content

Instantly share code, notes, and snippets.

@jackyyf
Created August 16, 2015 15:49
Show Gist options
  • Save jackyyf/83f2910f149b662f3c1c to your computer and use it in GitHub Desktop.
Save jackyyf/83f2910f149b662f3c1c to your computer and use it in GitHub Desktop.
Gist by paste.py @ 2015-08-16 23:49:10.567352
package main
import (
"crypto/tls"
"crypto/x509"
"net/http"
"net"
"fmt"
"strings"
"io"
"bufio"
)
var client_cert = []byte(`-----BEGIN CERTIFICATE-----
MIIC3jCCAj+gAwIBAgIJAOwjFCZ87FYiMAoGCCqGSM49BAMCMIGlMQswCQYDVQQG
EwJDTjERMA8GA1UECAwIU2hhbmdIYWkxETAPBgNVBAcMCFNoYW5nSGFpMRswGQYD
VQQKDBJPaGlvIERvY2sgQ28uIEx0ZC4xFDASBgNVBAsMC09oaW9Qb3J0KFIpMRsw
GQYDVQQDDBJPaGlvUG9ydCBDbGllbnQgQ0ExIDAeBgkqhkiG9w0BCQEWEXBvcnRA
b2hpby5ldmUubW9lMB4XDTE1MDgxMzE1NTE1MVoXDTE2MDgxMjE1NTE1MVowgaEx
CzAJBgNVBAYTAkNOMREwDwYDVQQIDAhTaGFuZ0hhaTERMA8GA1UEBwwIU2hhbmdI
YWkxGzAZBgNVBAoMEk9oaW8gRG9jayBDby4gTHRkLjEUMBIGA1UECwwLT2hpb1Bv
cnQoUikxFzAVBgNVBAMMDk9oaW9Qb3J0IDAuMC4xMSAwHgYJKoZIhvcNAQkBFhFw
b3J0QG9oaW8uZXZlLm1vZTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAVD5tCUn
fG4NHLKnoWPZiXekz1Ar7y34mJdQudJMbg3PwJAIpOUtyBYBPaxehS+utFfjFkFh
pWR34hZ0odNccuJeAY0iK+YpvXjYZPCGnX8MdMq8uIQzxvtaYsCxvZpfbV9s8Vhu
JSp2ItKDUIDJsZxTlxBF8ftnQDqtLlrfwgvPRvUsoxcwFTATBgNVHSUEDDAKBggr
BgEFBQcDAjAKBggqhkjOPQQDAgOBjAAwgYgCQgCWjS0UYu1GLkzSTdiaInIcjLdq
X3LKXtpShmzqVeBm20UBlE+Nn+y8KKYoZqvlRmZIu8yoBnePsvnTxhiaJbQx3gJC
Abfri9jyIhqs/aRmFAvChIharW3O13HI+EuksYOO+rBkCTcCXm6YbkoPHIlKBed7
8W9svObseWlQr/u3lXQOOVwV
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDGTCCAnygAwIBAgIJAOkAdMFbUxLGMAoGCCqGSM49BAMEMIGlMQswCQYDVQQG
EwJDTjERMA8GA1UECAwIU2hhbmdIYWkxETAPBgNVBAcMCFNoYW5nSGFpMRswGQYD
VQQKDBJPaGlvIERvY2sgQ28uIEx0ZC4xFDASBgNVBAsMC09oaW9Qb3J0KFIpMRsw
GQYDVQQDDBJPaGlvUG9ydCBDbGllbnQgQ0ExIDAeBgkqhkiG9w0BCQEWEXBvcnRA
b2hpby5ldmUubW9lMB4XDTE1MDgxMzE0NTA1MFoXDTI1MDgxMDE0NTA1MFowgaUx
CzAJBgNVBAYTAkNOMREwDwYDVQQIDAhTaGFuZ0hhaTERMA8GA1UEBwwIU2hhbmdI
YWkxGzAZBgNVBAoMEk9oaW8gRG9jayBDby4gTHRkLjEUMBIGA1UECwwLT2hpb1Bv
cnQoUikxGzAZBgNVBAMMEk9oaW9Qb3J0IENsaWVudCBDQTEgMB4GCSqGSIb3DQEJ
ARYRcG9ydEBvaGlvLmV2ZS5tb2UwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGH
QBjdysLuFD2ru2+ZfnnW2iSsRni2kC1sEiXbOLja7iSLyd8oQ4njiH66vPuFF8zR
+q/ChWqqa6VfH2/mlTsrZAAOjBOP3ja4RLhhDEQZ7mXYNwD2Bln3Jv9Vzl+ZTzvV
8B2Wo6tOava7wpcDf147kc/jcNw6U5KFB+BJwdXZzDzcTKNQME4wHQYDVR0OBBYE
FInGbFE7L5hlS4myCrfgkEXS30R3MB8GA1UdIwQYMBaAFInGbFE7L5hlS4myCrfg
kEXS30R3MAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwQDgYoAMIGGAkFYGpXam2Bp
Z0tUs5cG6hIQt8COME9azqRU9I1GcCd+NVxfaaZgNA+0j2YZ6TVokX0Wd6Owd1F0
2dJkzr33Vn3o1QJBbDHwY+6M9fN6eyrmzjsKubfesgZXpE02Zvi5w9gxGxFTpItZ
e6JuISQseWPRqPJ8cNIdxZMDtQ/8dezA1RtEpHQ=
-----END CERTIFICATE-----
`)
var client_key = []byte(`-----BEGIN EC PARAMETERS-----
BgUrgQQAIw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIHbAgEBBEHM+iDnloiazpj+IEY6g2qE0S42uWTgCHxr0nGc0V4ogMKx69VFMs+A
v/ikkn2LaQopcgC5yV3U8z5a246E4q5yrqAHBgUrgQQAI6GBiQOBhgAEAVD5tCUn
fG4NHLKnoWPZiXekz1Ar7y34mJdQudJMbg3PwJAIpOUtyBYBPaxehS+utFfjFkFh
pWR34hZ0odNccuJeAY0iK+YpvXjYZPCGnX8MdMq8uIQzxvtaYsCxvZpfbV9s8Vhu
JSp2ItKDUIDJsZxTlxBF8ftnQDqtLlrfwgvPRvUs
-----END EC PRIVATE KEY-----
`)
var server_root_ca = []byte(`-----BEGIN CERTIFICATE-----
MIIDDDCCAm6gAwIBAgIJALtKQi5Re2ogMAoGCCqGSM49BAMEMIGeMQswCQYDVQQG
EwJDTjERMA8GA1UECAwIU2hhbmdIYWkxETAPBgNVBAcMCFNoYW5nSGFpMRswGQYD
VQQKDBJPaGlvIERvY2sgQ28uIEx0ZC4xFDASBgNVBAsMC09oaW9Qb3J0KFIpMRQw
EgYDVQQDDAtPaGlvUG9ydCBDQTEgMB4GCSqGSIb3DQEJARYRcG9ydEBvaGlvLmV2
ZS5tb2UwHhcNMTUwODEzMTQzMzAyWhcNMjUwODEwMTQzMzAyWjCBnjELMAkGA1UE
BhMCQ04xETAPBgNVBAgMCFNoYW5nSGFpMREwDwYDVQQHDAhTaGFuZ0hhaTEbMBkG
A1UECgwST2hpbyBEb2NrIENvLiBMdGQuMRQwEgYDVQQLDAtPaGlvUG9ydChSKTEU
MBIGA1UEAwwLT2hpb1BvcnQgQ0ExIDAeBgkqhkiG9w0BCQEWEXBvcnRAb2hpby5l
dmUubW9lMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBoKKU8g1pQoJO8ehQd4A2
TScz38jGO1G8QKkgQQdJtr5LUzIRpeU3EeI58mzWY/0H0TszBoxqbAwn8rpMz2Hr
eC8A8Hdvl5yIPibqwJEUkSKNDgCYR/OTMNALl6XjCnJ4PWLizcqHSkv5nCXZIfL9
LYQa3Qk0vmoVYTwIpBucDlRLvF2jUDBOMB0GA1UdDgQWBBSA2IE9EcyiJPieWY27
Hzd5w+vRTzAfBgNVHSMEGDAWgBSA2IE9EcyiJPieWY27Hzd5w+vRTzAMBgNVHRME
BTADAQH/MAoGCCqGSM49BAMEA4GLADCBhwJBHCRKhEHQdbA8rYEBRcf5sU4Op44v
3ihLlwOmsIs3BCeeiHBhbSIRcU9dAI+q7sXj3GmQWqJXnkaB1lImU/XO0FQCQgEN
JhzoMtmDnAvi3xKzcNfvc4GKCCfNbs+XmrKqgPaKPQdbiZVnXgRE/Jxebcqk8X5N
Ic4KuzaGf+W7UEgrSYsNqg==
-----END CERTIFICATE-----
`)
var server_addr = "ohioport.eve.moe:443"
type ProxyHandler struct {}
var ohioDockConfig *tls.Config
var valid_methods = []string {
"OPTIONS",
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"TRACE",
"CONNECT",
}
func ConnectToPort() (net.Conn, error) {
return tls.Dial("tcp", server_addr, ohioDockConfig)
}
var client = http.Client{}
func PipeWatcher(src io.Reader, sink io.WriteCloser) {
io.Copy(sink, src)
sink.Close()
}
func proxy_handle(conn net.Conn) {
my_addr := conn.RemoteAddr()
connbuf := bufio.NewReader(conn)
line, err := connbuf.ReadString('\n')
ok := false
wtf := 0
var rconn net.Conn
if err != nil {
fmt.Printf("[%s] Unable to read first line.\n", my_addr)
conn.Close()
}
var method, uri, protocol string
nums, err := fmt.Sscanf(line, "%s %s %s", &method, &uri, &protocol)
if err != nil || nums != 3 {
goto invalid_protocol
}
method = strings.ToUpper(method)
for _, m := range valid_methods {
if method == m {
ok = true
break
}
}
if !ok {
goto invalid_protocol
}
protocol = strings.ToUpper(protocol)
if !strings.HasPrefix(protocol, "HTTP/") {
goto invalid_protocol
}
if n, err := fmt.Sscanf(protocol[5:], "%1d.%1d", &wtf, &wtf); err != nil || n != 2 {
goto invalid_protocol
}
rconn, err = ConnectToPort()
if err != nil {
fmt.Printf("[%s] Unable to connect to remote server: %s\n", my_addr, err.Error())
conn.Write([]byte("HTTP/1.1 502 Bad Gateway\r\nServer: OhioPort/0.0.1\r\nConnection: close\r\n\r\n"))
conn.Close()
return
}
rconn.Write([]byte(line))
fmt.Printf("[%s] %s %s %s\n", my_addr, method, uri, protocol)
go PipeWatcher(connbuf, rconn)
go PipeWatcher(rconn, conn)
return
invalid_protocol:
fmt.Printf("[%s] Invalid HTTP Protocol. \n", my_addr)
conn.Close()
return
}
func main() {
client_keypair, err := tls.X509KeyPair(client_cert, client_key)
if err != nil {
panic(err)
}
RootCAs := x509.NewCertPool()
if !RootCAs.AppendCertsFromPEM(server_root_ca) {
panic("Invalid root ca.")
}
ohioDockConfig = &tls.Config {
Certificates: []tls.Certificate{client_keypair},
RootCAs: RootCAs,
ServerName: "ohioport.eve.moe",
CipherSuites: []uint16 { tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 },
MinVersion: tls.VersionTLS12,
}
server, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Printf("Unable to listen on port 8080.\n")
panic(err)
}
fmt.Println("HTTP proxy server is running on 8080")
for {
client, err := server.Accept()
if err != nil {
fmt.Printf("Error accepting new connection: %s\n", err.Error())
continue
}
go proxy_handle(client)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment