Skip to content

Commit

Permalink
Configured publishing to the central maven repository
Browse files Browse the repository at this point in the history
  • Loading branch information
erikvanzijst committed Aug 17, 2021
1 parent 8004431 commit 7455c84
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 57 deletions.
89 changes: 87 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ beyond `scala-logging`

Can be used as a library, or as a standalone program.


## Standalone

```
Expand Down Expand Up @@ -40,12 +41,13 @@ etag: "5e9efe7d-264"
accept-ranges: bytes
```


## Library

To use it as a library in-process:

```scala
import tlsproxy.TlsProxy
import io.github.erikvanzijst.scalatlsproxy.TlsProxy

new TlsProxy(3128).run()
```
Expand All @@ -56,13 +58,14 @@ calling thread. It does not return.
To move it to the background, pass it to a `Thread` or `Executor`:

```scala
import tlsproxy.TlsProxy
import io.github.erikvanzijst.scalatlsproxy.TlsProxy
import java.util.concurrent.Executors

val executor = Executors.newSingleThreadExecutor()
executor.submit(new TlsProxy(3128))
```


## Caveat emptor

This is only implements the `CONNECT` method and can therefor only proxy HTTPS
Expand All @@ -75,10 +78,92 @@ connection getting closed:
18:08:53.604 [main] ERROR tlsproxy.TlsProxyHandler - /0:0:0:0:0:0:0:1:51043 -> unconnected: error: connection closed: java.io.IOException: Malformed request
```


## Robustness (or lack thereof)

* This implementation is totally susceptible to all kinds of [slowloris attacks](https://en.wikipedia.org/wiki/Slowloris_(computer_security).
* It does not support client authentication
* Uses only 1 thread and cannot currently scale to multiple cores
* Does not restrict non-standard upstream ports
* Undoubtedly riddled with bugs


## Publishing

Publishing is done to the Sonatype Central Repository and requires gpg-signed
artifacts. For this, install gpg and (on Mac) `pin-entry-mac`:

```
$ brew install gnupg pinentry-mac
```

Add the pinentry program to `~/.gnupg/gpg-agent.conf`:

```
pinentry-program /usr/local/bin/pinentry-mac
```

Restart `gpg-agent`:

```
$ gpgconf --kill gpg-agent
```

Run `publishLocalSigned` to ensure signing from `sbt` works (this should pop
up a dialog to enter the private key's passphrase):

```
$ sbt publishLocalSigned
[info] Loading global plugins from /Users/erik/.sbt/1.0/plugins
[info] Loading settings for project tlsproxy-build from plugins.sbt ...
[info] Loading project definition from /Users/erik/work/tlsproxy/project
[info] Loading settings for project tlsproxy from build.sbt ...
[info] Set current project to tlsproxy (in build file:/Users/erik/work/tlsproxy/)
[info] Wrote /Users/erik/work/tlsproxy/target/scala-2.12/tlsproxy_2.12-0.1.pom
[info] :: delivering :: erikvanzijst#tlsproxy_2.12;0.1 :: 0.1 :: release :: Tue Aug 17 22:44:46 CEST 2021
[info] delivering ivy file to /Users/erik/work/tlsproxy/target/scala-2.12/ivy-0.1.xml
[info] gpg: using "E96DDAAB16804D86EFA2A08A4539ACC7B26D1005" as default secret key for signing
[info] gpg: using "E96DDAAB16804D86EFA2A08A4539ACC7B26D1005" as default secret key for signing
[info] gpg: using "E96DDAAB16804D86EFA2A08A4539ACC7B26D1005" as default secret key for signing
[info] gpg: using "E96DDAAB16804D86EFA2A08A4539ACC7B26D1005" as default secret key for signing
[info] published tlsproxy_2.12 to /Users/erik/.ivy2/local/erikvanzijst/tlsproxy_2.12/0.1/jars/tlsproxy_2.12.jar
[info] published tlsproxy_2.12 to /Users/erik/.ivy2/local/erikvanzijst/tlsproxy_2.12/0.1/docs/tlsproxy_2.12-javadoc.jar
[info] published tlsproxy_2.12 to /Users/erik/.ivy2/local/erikvanzijst/tlsproxy_2.12/0.1/srcs/tlsproxy_2.12-sources.jar
[info] published tlsproxy_2.12 to /Users/erik/.ivy2/local/erikvanzijst/tlsproxy_2.12/0.1/poms/tlsproxy_2.12.pom.asc
[info] published tlsproxy_2.12 to /Users/erik/.ivy2/local/erikvanzijst/tlsproxy_2.12/0.1/poms/tlsproxy_2.12.pom
[info] published tlsproxy_2.12 to /Users/erik/.ivy2/local/erikvanzijst/tlsproxy_2.12/0.1/jars/tlsproxy_2.12.jar.asc
[info] published tlsproxy_2.12 to /Users/erik/.ivy2/local/erikvanzijst/tlsproxy_2.12/0.1/srcs/tlsproxy_2.12-sources.jar.asc
[info] published tlsproxy_2.12 to /Users/erik/.ivy2/local/erikvanzijst/tlsproxy_2.12/0.1/docs/tlsproxy_2.12-javadoc.jar.asc
[success] Total time: 1 s, completed Aug 17, 2021 10:44:47 PM
```

Now publish to Sonatype:

```
$ sbt publishSigned
[info] Loading global plugins from /Users/erik/.sbt/1.0/plugins
[info] Loading settings for project tlsproxy-build from plugins.sbt ...
[info] Loading project definition from /Users/erik/work/tlsproxy/project
[info] Loading settings for project tlsproxy from build.sbt ...
[info] Set current project to scala-tlsproxy (in build file:/Users/erik/work/tlsproxy/)
[info] Wrote /Users/erik/work/tlsproxy/target/scala-2.12/scala-tlsproxy_2.12-0.1-SNAPSHOT.pom
[info] gpg: using "E96DDAAB16804D86EFA2A08A4539ACC7B26D1005" as default secret key for signing
[info] gpg: using "E96DDAAB16804D86EFA2A08A4539ACC7B26D1005" as default secret key for signing
[info] gpg: using "E96DDAAB16804D86EFA2A08A4539ACC7B26D1005" as default secret key for signing
[info] gpg: using "E96DDAAB16804D86EFA2A08A4539ACC7B26D1005" as default secret key for signing
[info] published scala-tlsproxy_2.12 to https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/erikvanzijst/scala-tlsproxy_2.12/0.1-SNAPSHOT/scala-tlsproxy_2.12-0.1-SNAPSHOT.jar
[info] published scala-tlsproxy_2.12 to https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/erikvanzijst/scala-tlsproxy_2.12/0.1-SNAPSHOT/scala-tlsproxy_2.12-0.1-SNAPSHOT-sources.jar
[info] published scala-tlsproxy_2.12 to https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/erikvanzijst/scala-tlsproxy_2.12/0.1-SNAPSHOT/scala-tlsproxy_2.12-0.1-SNAPSHOT-javadoc.jar
[info] published scala-tlsproxy_2.12 to https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/erikvanzijst/scala-tlsproxy_2.12/0.1-SNAPSHOT/scala-tlsproxy_2.12-0.1-SNAPSHOT.jar.asc
[info] published scala-tlsproxy_2.12 to https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/erikvanzijst/scala-tlsproxy_2.12/0.1-SNAPSHOT/scala-tlsproxy_2.12-0.1-SNAPSHOT.pom.asc
[info] published scala-tlsproxy_2.12 to https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/erikvanzijst/scala-tlsproxy_2.12/0.1-SNAPSHOT/scala-tlsproxy_2.12-0.1-SNAPSHOT-sources.jar.asc
[info] published scala-tlsproxy_2.12 to https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/erikvanzijst/scala-tlsproxy_2.12/0.1-SNAPSHOT/scala-tlsproxy_2.12-0.1-SNAPSHOT-javadoc.jar.asc
[info] published scala-tlsproxy_2.12 to https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/erikvanzijst/scala-tlsproxy_2.12/0.1-SNAPSHOT/scala-tlsproxy_2.12-0.1-SNAPSHOT.pom
[success] Total time: 9 s, completed Aug 17, 2021 11:29:22 PM
```

Troubleshooting:

* https://github.com/sbt/sbt-pgp#sbt-pgp
* https://gist.github.com/danieleggert/b029d44d4a54b328c0bac65d46ba4c65
* https://www.scala-sbt.org/release/docs/Using-Sonatype.html
39 changes: 36 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,9 +1,42 @@
name := "tlsproxy"
name := "scala-tlsproxy"
organization := "io.github.erikvanzijst"

version := "0.1"
version := "0.1-SNAPSHOT"

scalaVersion := "2.12.14"

libraryDependencies += "com.github.scopt" %% "scopt" % "4.0.1"
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3"
libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.9.4"

credentials += Credentials(Path.userHome / ".sbt" / "sonatype_credentials")

ThisBuild / organization := "io.github.erikvanzijst"
ThisBuild / organizationName := "erikvanzijst"
ThisBuild / organizationHomepage := Some(url("https://github.com/erikvanzijst"))

ThisBuild / scmInfo := Some(
ScmInfo(
url("https://github.com/erikvanzijst/scala_tlsproxy"),
"scm:[email protected]:erikvanzijst/scala_tlsproxy.git"
)
)
ThisBuild / developers := List(
Developer(
id = "erikvanzijst",
name = "Erik van Zijst",
email = "[email protected]",
url = url("https://github.com/erikvanzijst")
)
)

ThisBuild / description := "Very simple HTTPS proxy server lib written in Scala 2.12 with no external dependencies."
ThisBuild / licenses := List("Apache 2" -> new URL("http://www.apache.org/licenses/LICENSE-2.0.txt"))
ThisBuild / homepage := Some(url("https://github.com/erikvanzijst/scala_tlsproxy"))

ThisBuild / pomIncludeRepository := { _ => false }
ThisBuild / publishTo := {
val nexus = "https://s01.oss.sonatype.org/"
if (isSnapshot.value) Some("snapshots" at nexus + "content/repositories/snapshots")
else Some("releases" at nexus + "service/local/staging/deploy/maven2")
}
ThisBuild / publishMavenStyle := true
1 change: 1 addition & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2")
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tlsproxy
package io.github.erikvanzijst.scalatlsproxy

import java.io.IOException
import java.nio.ByteBuffer
Expand Down
18 changes: 18 additions & 0 deletions src/main/scala/io/github/erikvanzijst/scalatlsproxy/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.github.erikvanzijst.scalatlsproxy

import ch.qos.logback.classic.Level
import com.typesafe.scalalogging.StrictLogging
import org.slf4j.LoggerFactory

object Main extends StrictLogging {

// Suppress debug when running from the shell
Seq("io.github.erikvanzijst.scalatlsproxy.TlsProxyHandler",
"io.github.erikvanzijst.scalatlsproxy.ServerHandler",
"io.github.erikvanzijst.scalatlsproxy.Pipe")
.map(LoggerFactory.getLogger)
.map(_.asInstanceOf[ch.qos.logback.classic.Logger])
.foreach(_.setLevel(Level.INFO))

def main(args: Array[String]): Unit = new TlsProxy(3128).run()
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tlsproxy
package io.github.erikvanzijst.scalatlsproxy

import java.nio.ByteBuffer
import java.nio.channels.{SelectionKey, SocketChannel}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tlsproxy
package io.github.erikvanzijst.scalatlsproxy

import java.net.InetSocketAddress
import java.nio.channels.{SelectionKey, Selector, ServerSocketChannel}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package tlsproxy
package io.github.erikvanzijst.scalatlsproxy

import java.nio.channels.Selector

import ch.qos.logback.classic.Level
import com.typesafe.scalalogging.StrictLogging
import org.slf4j.LoggerFactory

trait KeyHandler {
def process(): Unit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tlsproxy
package io.github.erikvanzijst.scalatlsproxy

import java.io.IOException
import java.net.InetSocketAddress
Expand All @@ -7,23 +7,24 @@ import java.nio.channels.{SelectionKey, Selector, SocketChannel, UnresolvedAddre
import java.nio.charset.StandardCharsets

import com.typesafe.scalalogging.StrictLogging
import tlsproxy.TlsProxyHandler.userAgent

import scala.collection.JavaConverters._
import scala.util.Try
import scala.util.matching.Regex

object ProxyPhase extends Enumeration {
type ProxyPhase = Value
val Destination, Headers, Response, Connecting, Established, Error = Value
}

object TlsProxyHandler {
private val destPattern = "CONNECT ([^:]+):([0-9]+) HTTP/1.1".r
private val userAgent = "TlsProxy/1.0 (github.com/erikvanzijst/scala_tlsproxy)"
val destPattern: Regex = "CONNECT ([^:]+):([0-9]+) HTTP/1.1".r
val userAgent: String = "TlsProxy/1.0 (github.com/erikvanzijst/scala_tlsproxy)"
}

class TlsProxyHandler(selector: Selector, clientChannel: SocketChannel) extends KeyHandler with StrictLogging {
import ProxyPhase._
import TlsProxyHandler._

clientChannel.configureBlocking(false)
private val peer = clientChannel.getRemoteAddress
Expand All @@ -50,7 +51,6 @@ class TlsProxyHandler(selector: Selector, clientChannel: SocketChannel) extends
throw new IOException(s"$peer handshake overflow")
}


private def readLine(): Option[String] = {
readClient()
clientBuffer.flip()
Expand Down Expand Up @@ -169,9 +169,8 @@ class TlsProxyHandler(selector: Selector, clientChannel: SocketChannel) extends
clientChannel.write(serverBuffer)
serverBuffer.compact()

if (serverBuffer.position() == 0) {
if (serverBuffer.position() == 0)
close()
}
}

} catch {
Expand Down
39 changes: 0 additions & 39 deletions src/main/scala/tlsproxy/Main.scala

This file was deleted.

0 comments on commit 7455c84

Please sign in to comment.