@@ -8,11 +8,14 @@ import (
88 "crypto/x509/pkix"
99 "encoding/pem"
1010 "github.com/armon/go-socks5"
11+ "github.com/elazarl/goproxy"
12+ "github.com/elazarl/goproxy/ext/auth"
1113 "github.com/grepplabs/kafka-proxy/config"
1214 "github.com/pkg/errors"
1315 "io/ioutil"
1416 "math/big"
1517 "net"
18+ "net/http"
1619 "os"
1720 "time"
1821)
@@ -101,7 +104,7 @@ func (s testCredentials) Valid(username, password string) bool {
101104 return s .username == username && s .password == password
102105}
103106
104- func makeTLSSocks5Pipe (conf * config.Config , authenticator socks5.Authenticator , username , password string ) (c1 , c2 net.Conn , stop func (), err error ) {
107+ func makeTLSSocks5ProxyPipe (conf * config.Config , authenticator socks5.Authenticator , username , password string ) (c1 , c2 net.Conn , stop func (), err error ) {
105108 socks5Conf := & socks5.Config {}
106109 if authenticator != nil {
107110 socks5Conf .AuthMethods = []socks5.Authenticator {authenticator }
@@ -209,6 +212,113 @@ func makeTLSSocks5Pipe(conf *config.Config, authenticator socks5.Authenticator,
209212 }
210213}
211214
215+ func makeTLSHttpProxyPipe (conf * config.Config , proxyusername , proxypassword string , username , password string ) (c1 , c2 net.Conn , stop func (), err error ) {
216+ server := goproxy .NewProxyHttpServer ()
217+
218+ if proxyusername != "" && proxypassword != "" {
219+ server .OnRequest ().HandleConnect (auth .BasicConnect ("" , func (user , passwd string ) bool {
220+ return user == proxyusername && passwd == proxypassword
221+ }))
222+ }
223+
224+ if err != nil {
225+ return nil , nil , nil , err
226+ }
227+ clientConfig , err := newTLSClientConfig (conf )
228+ if err != nil {
229+ return nil , nil , nil , err
230+ }
231+ serverConfig , err := newTLSListenerConfig (conf )
232+ if err != nil {
233+ return nil , nil , nil , err
234+ }
235+
236+ proxy , err := net .Listen ("tcp4" , "127.0.0.1:0" )
237+ if err != nil {
238+ return nil , nil , nil , err
239+ }
240+ httpProxy := & httpProxy {
241+ forwardDialer : directDialer {
242+ dialTimeout : 2 * time .Second ,
243+ keepAlive : 60 * time .Second ,
244+ },
245+ network : proxy .Addr ().Network (),
246+ hostPort : proxy .Addr ().String (),
247+ username : username ,
248+ password : password ,
249+ }
250+
251+ tlsDialer := tlsDialer {
252+ timeout : 3 * time .Second ,
253+ rawDialer : httpProxy ,
254+ config : clientConfig ,
255+ }
256+
257+ target , err := tls .Listen ("tcp" , "127.0.0.1:0" , serverConfig )
258+ if err != nil {
259+ proxy .Close ()
260+ return nil , nil , nil , err
261+ }
262+ // Start a connection between two endpoints.
263+ var err0 , err1 , err2 error
264+ go func () {
265+ err0 = http .Serve (proxy , server )
266+ }()
267+ done := make (chan bool )
268+ go func () {
269+ c2 , err2 = target .Accept ()
270+ close (done )
271+ if err2 != nil {
272+ return
273+ }
274+ // will force handshake completion
275+ buf := make ([]byte , 0 )
276+ c2 .Read (buf )
277+
278+ tlscon , ok := c2 .(* tls.Conn )
279+ if ok {
280+ state := tlscon .ConnectionState ()
281+ for _ , v := range state .PeerCertificates {
282+ _ = v
283+ //fmt.Println(x509.MarshalPKIXPublicKey(v.PublicKey))
284+ }
285+ }
286+ }()
287+ stop = func () {
288+ if err1 == nil {
289+ c1 .Close ()
290+ }
291+ if err2 == nil {
292+ c2 .Close ()
293+ }
294+ target .Close ()
295+ proxy .Close ()
296+ }
297+
298+ c1 , err1 = tlsDialer .Dial (target .Addr ().Network (), target .Addr ().String ())
299+ if err1 != nil {
300+ target .Close ()
301+ return nil , nil , nil , err1
302+ }
303+ select {
304+ case <- done :
305+ case <- time .After (4 * time .Second ):
306+ target .Close ()
307+ return nil , nil , nil , errors .New ("Accept timeout " )
308+ }
309+
310+ switch {
311+ case err1 != nil :
312+ stop ()
313+ return nil , nil , nil , err1
314+ case err2 != nil :
315+ stop ()
316+ return nil , nil , nil , err2
317+ default :
318+ return c1 , c2 , stop , nil
319+ }
320+ }
321+
212322func makePipe () (c1 , c2 net.Conn , stop func (), err error ) {
213323 dialer := directDialer {
214324 dialTimeout : 2 * time .Second ,
@@ -257,7 +367,7 @@ func makePipe() (c1, c2 net.Conn, stop func(), err error) {
257367 }
258368}
259369
260- func makeSocks5Pipe () (c1 , c2 net.Conn , stop func (), err error ) {
370+ func makeSocks5ProxyPipe () (c1 , c2 net.Conn , stop func (), err error ) {
261371 server , err := socks5 .New (& socks5.Config {})
262372 if err != nil {
263373 return nil , nil , nil , err
@@ -330,6 +440,77 @@ func makeSocks5Pipe() (c1, c2 net.Conn, stop func(), err error) {
330440 }
331441}
332442
443+ func makeHttpProxyPipe () (c1 , c2 net.Conn , stop func (), err error ) {
444+ server := goproxy .NewProxyHttpServer ()
445+ //server.Verbose = true
446+
447+ if err != nil {
448+ return nil , nil , nil , err
449+ }
450+ proxy , err := net .Listen ("tcp4" , "127.0.0.1:0" )
451+ if err != nil {
452+ return nil , nil , nil , err
453+ }
454+ target , err := net .Listen ("tcp4" , "127.0.0.1:0" )
455+ if err != nil {
456+ proxy .Close ()
457+ return nil , nil , nil , err
458+ }
459+ httpProxy := httpProxy {
460+ forwardDialer : directDialer {
461+ dialTimeout : 2 * time .Second ,
462+ keepAlive : 60 * time .Second ,
463+ },
464+ network : proxy .Addr ().Network (),
465+ hostPort : proxy .Addr ().String (),
466+ }
467+
468+ var err0 , err1 , err2 error
469+ go func () {
470+ err0 = http .Serve (proxy , server )
471+ }()
472+
473+ done := make (chan bool )
474+ go func () {
475+ c2 , err2 = target .Accept ()
476+ close (done )
477+ }()
478+
479+ c1 , err1 = httpProxy .Dial (target .Addr ().Network (), target .Addr ().String ())
480+
481+ stop = func () {
482+ if err1 == nil {
483+ c1 .Close ()
484+ }
485+ if err2 == nil {
486+ c2 .Close ()
487+ }
488+ target .Close ()
489+ proxy .Close ()
490+ }
491+
492+ select {
493+ case <- done :
494+ case <- time .After (3 * time .Second ):
495+ stop ()
496+ return nil , nil , nil , errors .New ("Accept timeout" )
497+ }
498+
499+ switch {
500+ case err0 != nil :
501+ stop ()
502+ return nil , nil , nil , err0
503+ case err1 != nil :
504+ stop ()
505+ return nil , nil , nil , err1
506+ case err2 != nil :
507+ stop ()
508+ return nil , nil , nil , err2
509+ default :
510+ return c1 , c2 , stop , nil
511+ }
512+ }
513+
333514func generateCert (catls * tls.Certificate , certFile * os.File , keyFile * os.File ) error {
334515 // Prepare certificate
335516 cert := & x509.Certificate {
0 commit comments