Compare commits
60 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
accce088e6 | ||
![]() |
42beefd223 | ||
![]() |
12b71780a1 | ||
![]() |
b444857549 | ||
![]() |
2004e84df8 | ||
![]() |
7441572846 | ||
![]() |
93dd1b4e8d | ||
![]() |
398a6182af | ||
![]() |
d467b652ec | ||
![]() |
19c29cfdc6 | ||
![]() |
1548d1e36b | ||
![]() |
3e8ace902d | ||
![]() |
8afd6c6f28 | ||
![]() |
b94bd86d03 | ||
![]() |
7829962acd | ||
![]() |
299421e0fe | ||
a7c097d232 | |||
7282cb5fa0 | |||
2f8508ee92 | |||
b036b9e8f8 | |||
f36a500210 | |||
dbcf640320 | |||
08f2f9031d | |||
d40d687f6e | |||
b12bf1bf22 | |||
7bcc9344ec | |||
f84eb3ce70 | |||
f576588ec0 | |||
0ae229792c | |||
4e69e3d50b | |||
059a24d638 | |||
45071f0faa | |||
0791f1145b | |||
51c58d6407 | |||
0bf519a351 | |||
1eb8e6fb5c | |||
c4b8236446 | |||
162c6fb01a | |||
11c6b51be6 | |||
17712bf3ae | |||
7a438a29ed | |||
b0cd962ce9 | |||
92462d8986 | |||
8d1a4408ce | |||
179688d8c0 | |||
cb674587f6 | |||
dc0ec87635 | |||
4c86b4fd8a | |||
d48d8e217d | |||
0ac1d8ad65 | |||
c46fcb14f7 | |||
3ec7aace8a | |||
07b65bee1f | |||
1589518259 | |||
9fe7931202 | |||
8daf43276b | |||
2173a6a36e | |||
f9c992dcb2 | |||
fd9eae23eb | |||
![]() |
53eeba13a8 |
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@@ -0,0 +1,8 @@
|
||||
.idea
|
||||
.git
|
||||
.gitlab-ci.yml
|
||||
.vscode
|
||||
|
||||
# CI cache folder storing docker images
|
||||
ci-exports
|
||||
|
106
.gitlab-ci.yml
Normal file
106
.gitlab-ci.yml
Normal file
@@ -0,0 +1,106 @@
|
||||
image: docker:19.03.12
|
||||
|
||||
stages:
|
||||
- docker_test
|
||||
- docker_push
|
||||
|
||||
variables:
|
||||
# When using dind service, we need to instruct docker to talk with
|
||||
# the daemon started inside of the service. The daemon is available
|
||||
# with a network connection instead of the default
|
||||
# /var/run/docker.sock socket. Docker 19.03 does this automatically
|
||||
# by setting the DOCKER_HOST in
|
||||
# https://github.com/docker-library/docker/blob/d45051476babc297257df490d22cbd806f1b11e4/19.03/docker-entrypoint.sh#L23-L29
|
||||
#
|
||||
# The 'docker' hostname is the alias of the service container as described at
|
||||
# https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services.
|
||||
#
|
||||
# Specify to Docker where to create the certificates, Docker will
|
||||
# create them automatically on boot, and will create
|
||||
# `/certs/client` that will be shared between the service and job
|
||||
# container, thanks to volume mount from config.toml
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
|
||||
DOCKER_HOST: tcp://docker:2376
|
||||
|
||||
services:
|
||||
- docker:19.03.12-dind
|
||||
|
||||
.docker_cache:
|
||||
cache:
|
||||
# The same key should be used across branches
|
||||
key: "$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- ci-exports/*.tar
|
||||
|
||||
# Make sure we can build a docker image
|
||||
# It's cached for later jobs
|
||||
build_docker:
|
||||
extends:
|
||||
- .docker_cache
|
||||
stage: docker_test
|
||||
script:
|
||||
# Try to load latest branch image from local tar or from registry
|
||||
- docker load ci-exports/$CI_COMMIT_REF_SLUG.tar || docker pull $CI_REGISTRY_IMAGE:latest || true
|
||||
- docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:latest .
|
||||
- mkdir -p ci-exports/
|
||||
- docker save $CI_REGISTRY_IMAGE:latest > ci-exports/$CI_COMMIT_REF_SLUG.tar
|
||||
|
||||
# Publishes the configured CI registry (by default that's gitlab's registry)
|
||||
push_ci_registry:
|
||||
extends:
|
||||
- .docker_cache
|
||||
stage: docker_push
|
||||
cache:
|
||||
policy: pull
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- cat ci-exports/$CI_COMMIT_REF_SLUG.tar | docker load
|
||||
- docker tag $CI_REGISTRY_IMAGE:latest $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||
- docker push $CI_REGISTRY_IMAGE:latest
|
||||
only:
|
||||
refs:
|
||||
# Make sure to protect these tags!
|
||||
- /^v(\d+\.){2,3}\d+$/
|
||||
- /.+-release$/
|
||||
variables:
|
||||
- $CI_REGISTRY
|
||||
- $CI_REGISTRY_USER
|
||||
- $CI_REGISTRY_PASSWORD
|
||||
- $CI_REGISTRY_IMAGE
|
||||
|
||||
# Publishes the cached image to docker
|
||||
push_dockerhub_registry:
|
||||
extends:
|
||||
- .docker_cache
|
||||
stage: docker_push
|
||||
cache:
|
||||
policy: pull
|
||||
before_script:
|
||||
- docker login -u $DOCKERHUB_REGISTRY_USER -p $DOCKERHUB_REGISTRY_PASSWORD $DOCKERHUB_REGISTRY
|
||||
script:
|
||||
- cat ci-exports/$CI_COMMIT_REF_SLUG.tar | docker load
|
||||
- docker tag $CI_REGISTRY_IMAGE:latest $DOCKERHUB_REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||
- docker tag $CI_REGISTRY_IMAGE:latest $DOCKERHUB_REGISTRY_IMAGE:latest
|
||||
- docker push $DOCKERHUB_REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||
- docker push $DOCKERHUB_REGISTRY_IMAGE:latest
|
||||
# Push the readme to dockerhub
|
||||
- >-
|
||||
docker run -v $PWD:/workspace
|
||||
-e DOCKERHUB_USERNAME="$DOCKERHUB_REGISTRY_USER"
|
||||
-e DOCKERHUB_PASSWORD="$DOCKERHUB_REGISTRY_PASSWORD"
|
||||
-e DOCKERHUB_REPOSITORY="$DOCKERHUB_REGISTRY_IMAGE"
|
||||
-e README_FILEPATH='/workspace/README.md'
|
||||
peterevans/dockerhub-description:2
|
||||
only:
|
||||
refs:
|
||||
# Make sure to protect these tags!
|
||||
- /^v(\d+\.){2,3}\d+$/
|
||||
- /.+-release$/
|
||||
variables:
|
||||
- $DOCKERHUB_REGISTRY
|
||||
- $DOCKERHUB_REGISTRY_USER
|
||||
- $DOCKERHUB_REGISTRY_PASSWORD
|
||||
- $DOCKERHUB_REGISTRY_IMAGE
|
@@ -31,4 +31,4 @@
|
||||
* numRi per su3 file: 75 --> 77
|
||||
|
||||
2016-01
|
||||
* fork from https://github.com/idk/reseed-tools
|
||||
* fork from https://i2pgit.org/idk/reseed-tools
|
||||
|
@@ -1,8 +1,8 @@
|
||||
FROM debian:stable-backports
|
||||
ARG I2P_GID=1000
|
||||
ARG I2P_UID=1000
|
||||
COPY . /var/lib/i2p/go/src/github.com/idk/reseed-tools
|
||||
WORKDIR /var/lib/i2p/go/src/github.com/idk/reseed-tools
|
||||
COPY . /var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools
|
||||
WORKDIR /var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools
|
||||
RUN apt-get update && \
|
||||
apt-get dist-upgrade -y && \
|
||||
apt-get install -y git golang-1.13-go make && \
|
||||
@@ -11,4 +11,4 @@ RUN apt-get update && \
|
||||
RUN /usr/lib/go-1.13/bin/go build -v -tags netgo -ldflags '-w -extldflags "-static"'
|
||||
USER $I2P_UID
|
||||
WORKDIR /var/lib/i2p/i2p-config/reseed
|
||||
ENTRYPOINT [ "/var/lib/i2p/go/src/github.com/idk/reseed-tools/entrypoint.sh" ]
|
||||
ENTRYPOINT [ "/var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools/entrypoint.sh" ]
|
12
Makefile
12
Makefile
@@ -135,3 +135,15 @@ docker-homerun:
|
||||
--volume reseed-keys:/var/lib/i2p/i2p-config/reseed:z \
|
||||
eyedeekay/reseed \
|
||||
--signer=hankhill19580@gmail.com
|
||||
|
||||
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre/
|
||||
export CGO_CFLAGS=-I/usr/lib/jvm/java-8-openjdk-amd64/include/ -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux/
|
||||
|
||||
gojava:
|
||||
go get -u -v github.com/sridharv/gojava
|
||||
cp -v ~/go/bin/gojava ./gojava
|
||||
|
||||
jar: gojava
|
||||
echo $(JAVA_HOME)
|
||||
./gojava -v -o reseed.jar -s . build ./reseed
|
||||
|
||||
|
28
README.md
28
README.md
@@ -9,8 +9,8 @@ create, sign, and validate SU3 files. Please note that this requires at least Go
|
||||
If you have go installed you can download, build, and install this tool with `go get`
|
||||
|
||||
```
|
||||
go get github.com/idk/reseed-tools
|
||||
i2p-tools -h
|
||||
go get i2pgit.org/idk/reseed-tools
|
||||
reseed-tools -h
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -76,13 +76,13 @@ work for you. In that case, just copy-and-paste:
|
||||
### Locally behind a webserver (reverse proxy setup), preferred:
|
||||
|
||||
```
|
||||
i2p-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --port=8443 --ip=127.0.0.1 --trustProxy
|
||||
reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --port=8443 --ip=127.0.0.1 --trustProxy
|
||||
```
|
||||
|
||||
### Without a webserver, standalone with TLS support
|
||||
|
||||
```
|
||||
i2p-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --tlsHost=your-domain.tld
|
||||
reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --tlsHost=your-domain.tld
|
||||
```
|
||||
|
||||
If this is your first time running a reseed server (ie. you don't have any existing keys),
|
||||
@@ -102,26 +102,26 @@ also a short guide and complete tech info.
|
||||
Requires ```go mod``` and at least go 1.13. To build the idk/reseed-tools
|
||||
fork, from anywhere:
|
||||
|
||||
git clone https://github.com/idk/reseed-tools
|
||||
cd i2p-tools-1
|
||||
git clone https://i2pgit.org/idk/reseed-tools
|
||||
cd reseed-tools
|
||||
make build
|
||||
|
||||
### Without a webserver, standalone, self-supervising(Automatic restarts)
|
||||
|
||||
```
|
||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --littleboss=start
|
||||
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --littleboss=start
|
||||
```
|
||||
|
||||
### Without a webserver, standalone, automatic OnionV3 with TLS support
|
||||
|
||||
```
|
||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --i2p --p2p
|
||||
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --i2p --p2p
|
||||
```
|
||||
|
||||
### Without a webserver, standalone, serve P2P with LibP2P
|
||||
|
||||
```
|
||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --p2p
|
||||
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --p2p
|
||||
```
|
||||
|
||||
### Without a webserver, standalone, upload a single signed .su3 to github
|
||||
@@ -129,29 +129,29 @@ fork, from anywhere:
|
||||
* This one isn't working yet, I'll get to it eventually, I've got a cooler idea now.
|
||||
|
||||
```
|
||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --github --ghrepo=i2p-tools-1 --ghuser=eyedeekay
|
||||
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --github --ghrepo=reseed-tools --ghuser=eyedeekay
|
||||
```
|
||||
|
||||
### Without a webserver, standalone, in-network reseed
|
||||
|
||||
```
|
||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --i2p
|
||||
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --i2p
|
||||
```
|
||||
|
||||
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS
|
||||
|
||||
```
|
||||
./i2p-tools-1 reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion
|
||||
./reseed-tools reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion
|
||||
```
|
||||
|
||||
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS, and LibP2P
|
||||
|
||||
```
|
||||
./i2p-tools-1 reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --p2p
|
||||
./reseed-tools reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --p2p
|
||||
```
|
||||
|
||||
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS, I2P In-Network reseed, and LibP2P, self-supervising
|
||||
|
||||
```
|
||||
./i2p-tools-1 reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --p2p --littleboss=start
|
||||
./reseed-tools reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --p2p --littleboss=start
|
||||
```
|
||||
|
@@ -18,10 +18,10 @@ import (
|
||||
"github.com/cretz/bine/torutil/ed25519"
|
||||
"github.com/eyedeekay/sam3"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
"github.com/idk/reseed-tools/reseed"
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/urfave/cli"
|
||||
"i2pgit.org/idk/reseed-tools/reseed"
|
||||
)
|
||||
|
||||
func NewReseedCommand() cli.Command {
|
||||
@@ -133,6 +133,15 @@ func NewReseedCommand() cli.Command {
|
||||
Value: "start",
|
||||
Usage: "Self-Supervise this application",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "acme",
|
||||
Usage: "Automatically generate a TLS certificate with the ACME protocol, defaults to Let's Encrypt",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "acmeserver",
|
||||
Value: "https://acme-staging-v02.api.letsencrypt.org/directory",
|
||||
Usage: "Use this server to issue a certificate with the ACME protocol",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -208,13 +217,53 @@ func reseedAction(c *cli.Context) {
|
||||
var i2pTlsCert, i2pTlsKey string
|
||||
var i2pkey i2pkeys.I2PKeys
|
||||
|
||||
if tlsHost != "" {
|
||||
onionTlsHost = tlsHost
|
||||
i2pTlsHost = tlsHost
|
||||
tlsKey = c.String("tlsKey")
|
||||
// if no key is specified, default to the host.pem in the current dir
|
||||
if tlsKey == "" {
|
||||
tlsKey = tlsHost + ".pem"
|
||||
onionTlsKey = tlsHost + ".pem"
|
||||
i2pTlsKey = tlsHost + ".pem"
|
||||
}
|
||||
|
||||
tlsCert = c.String("tlsCert")
|
||||
// if no certificate is specified, default to the host.crt in the current dir
|
||||
if tlsCert == "" {
|
||||
tlsCert = tlsHost + ".crt"
|
||||
onionTlsCert = tlsHost + ".crt"
|
||||
i2pTlsCert = tlsHost + ".crt"
|
||||
}
|
||||
|
||||
// prompt to create tls keys if they don't exist?
|
||||
auto := c.Bool("yes")
|
||||
// use ACME?
|
||||
acme := c.Bool("acme")
|
||||
if acme {
|
||||
acmeserver := c.String("acmeserver")
|
||||
err := checkUseAcmeCert(tlsHost, signerID, acmeserver, &tlsCert, &tlsKey, auto)
|
||||
if nil != err {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
} else {
|
||||
err := checkOrNewTLSCert(tlsHost, &tlsCert, &tlsKey, auto)
|
||||
if nil != err {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if c.Bool("i2p") {
|
||||
var err error
|
||||
i2pkey, err = LoadKeys("reseed.i2pkeys", c)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
if i2pTlsHost == "" {
|
||||
i2pTlsHost = i2pkey.Addr().Base32()
|
||||
}
|
||||
if i2pTlsHost != "" {
|
||||
// if no key is specified, default to the host.pem in the current dir
|
||||
if i2pTlsKey == "" {
|
||||
@@ -250,7 +299,9 @@ func reseedAction(c *cli.Context) {
|
||||
}
|
||||
ok = []byte(key.PrivateKey())
|
||||
}
|
||||
if onionTlsHost == "" {
|
||||
onionTlsHost = torutil.OnionServiceIDFromPrivateKey(ed25519.PrivateKey(ok)) + ".onion"
|
||||
}
|
||||
err = ioutil.WriteFile(c.String("onionKey"), ok, 0644)
|
||||
if err != nil {
|
||||
log.Fatalln(err.Error())
|
||||
@@ -275,27 +326,6 @@ func reseedAction(c *cli.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
if tlsHost != "" {
|
||||
tlsKey = c.String("tlsKey")
|
||||
// if no key is specified, default to the host.pem in the current dir
|
||||
if tlsKey == "" {
|
||||
tlsKey = tlsHost + ".pem"
|
||||
}
|
||||
|
||||
tlsCert = c.String("tlsCert")
|
||||
// if no certificate is specified, default to the host.crt in the current dir
|
||||
if tlsCert == "" {
|
||||
tlsCert = tlsHost + ".crt"
|
||||
}
|
||||
|
||||
// prompt to create tls keys if they don't exist?
|
||||
auto := c.Bool("yes")
|
||||
err := checkOrNewTLSCert(tlsHost, &tlsCert, &tlsKey, auto)
|
||||
if nil != err {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
reloadIntvl, err := time.ParseDuration(c.String("interval"))
|
||||
if nil != err {
|
||||
fmt.Printf("'%s' is not a valid time interval.\n", reloadIntvl)
|
||||
@@ -362,7 +392,7 @@ func reseedAction(c *cli.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func reseedHTTPS(c *cli.Context, tlsCert, tlsKey string, reseeder reseed.Reseeder) {
|
||||
func reseedHTTPS(c *cli.Context, tlsCert, tlsKey string, reseeder *reseed.ReseederImpl) {
|
||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||
server.Reseeder = reseeder
|
||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||
@@ -391,7 +421,7 @@ func reseedHTTPS(c *cli.Context, tlsCert, tlsKey string, reseeder reseed.Reseede
|
||||
}
|
||||
}
|
||||
|
||||
func reseedHTTP(c *cli.Context, reseeder reseed.Reseeder) {
|
||||
func reseedHTTP(c *cli.Context, reseeder *reseed.ReseederImpl) {
|
||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||
server.Reseeder = reseeder
|
||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||
@@ -428,7 +458,7 @@ func makeRandomHost(port int) (host.Host, error) {
|
||||
return host, nil
|
||||
}
|
||||
|
||||
func reseedP2P(c *cli.Context, reseeder reseed.Reseeder) {
|
||||
func reseedP2P(c *cli.Context, reseeder *reseed.ReseederImpl) {
|
||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||
server.Reseeder = reseeder
|
||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||
@@ -466,7 +496,7 @@ func reseedP2P(c *cli.Context, reseeder reseed.Reseeder) {
|
||||
}
|
||||
}
|
||||
|
||||
func reseedOnion(c *cli.Context, onionTlsCert, onionTlsKey string, reseeder reseed.Reseeder) {
|
||||
func reseedOnion(c *cli.Context, onionTlsCert, onionTlsKey string, reseeder *reseed.ReseederImpl) {
|
||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||
server.Reseeder = reseeder
|
||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||
@@ -541,7 +571,7 @@ func reseedOnion(c *cli.Context, onionTlsCert, onionTlsKey string, reseeder rese
|
||||
log.Printf("Onion server started on %s\n", server.Addr)
|
||||
}
|
||||
|
||||
func reseedI2P(c *cli.Context, i2pTlsCert, i2pTlsKey string, i2pIdentKey i2pkeys.I2PKeys, reseeder reseed.Reseeder) {
|
||||
func reseedI2P(c *cli.Context, i2pTlsCert, i2pTlsKey string, i2pIdentKey i2pkeys.I2PKeys, reseeder *reseed.ReseederImpl) {
|
||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||
server.Reseeder = reseeder
|
||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||
|
192
cmd/utils.go
192
cmd/utils.go
@@ -2,10 +2,12 @@ package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
@@ -16,8 +18,15 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/idk/reseed-tools/reseed"
|
||||
"github.com/idk/reseed-tools/su3"
|
||||
"i2pgit.org/idk/reseed-tools/reseed"
|
||||
"i2pgit.org/idk/reseed-tools/su3"
|
||||
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/go-acme/lego/v4/challenge/http01"
|
||||
"github.com/go-acme/lego/v4/challenge/tlsalpn01"
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
)
|
||||
|
||||
func loadPrivateKey(path string) (*rsa.PrivateKey, error) {
|
||||
@@ -35,6 +44,24 @@ func loadPrivateKey(path string) (*rsa.PrivateKey, error) {
|
||||
return privKey, nil
|
||||
}
|
||||
|
||||
// Taken directly from the lego example, since we need very minimal support
|
||||
// https://go-acme.github.io/lego/usage/library/
|
||||
type MyUser struct {
|
||||
Email string
|
||||
Registration *registration.Resource
|
||||
key crypto.PrivateKey
|
||||
}
|
||||
|
||||
func (u *MyUser) GetEmail() string {
|
||||
return u.Email
|
||||
}
|
||||
func (u MyUser) GetRegistration() *registration.Resource {
|
||||
return u.Registration
|
||||
}
|
||||
func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
|
||||
return u.key
|
||||
}
|
||||
|
||||
func signerFile(signerID string) string {
|
||||
return strings.Replace(signerID, "@", "_at_", 1)
|
||||
}
|
||||
@@ -60,6 +87,165 @@ func getOrNewSigningCert(signerKey *string, signerID string, auto bool) (*rsa.Pr
|
||||
return loadPrivateKey(*signerKey)
|
||||
}
|
||||
|
||||
func checkUseAcmeCert(tlsHost, signer, cadirurl string, tlsCert, tlsKey *string, auto bool) error {
|
||||
_, certErr := os.Stat(*tlsCert)
|
||||
_, keyErr := os.Stat(*tlsKey)
|
||||
if certErr != nil || keyErr != nil {
|
||||
if certErr != nil {
|
||||
fmt.Printf("Unable to read TLS certificate '%s'\n", *tlsCert)
|
||||
}
|
||||
if keyErr != nil {
|
||||
fmt.Printf("Unable to read TLS key '%s'\n", *tlsKey)
|
||||
}
|
||||
|
||||
if !auto {
|
||||
fmt.Printf("Would you like to generate a new certificate with Let's Encrypt or a custom ACME server? '%s'? (y or n): ", tlsHost)
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, _ := reader.ReadString('\n')
|
||||
if []byte(input)[0] != 'y' {
|
||||
fmt.Println("Continuing without TLS")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TLSConfig := &tls.Config{}
|
||||
TLSConfig.NextProtos = []string{"http/1.1"}
|
||||
TLSConfig.Certificates = make([]tls.Certificate, 1)
|
||||
var err error
|
||||
TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(*tlsCert, *tlsKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if time.Now().Sub(TLSConfig.Certificates[0].Leaf.NotAfter) < (time.Hour * 48) {
|
||||
ecder, err := ioutil.ReadFile(tlsHost + signer + ".acme.key")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
privateKey, err := x509.ParseECPrivateKey(ecder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user := MyUser{
|
||||
Email: signer,
|
||||
key: privateKey,
|
||||
}
|
||||
config := lego.NewConfig(&user)
|
||||
config.CADirURL = cadirurl
|
||||
config.Certificate.KeyType = certcrypto.RSA2048
|
||||
client, err := lego.NewClient(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
renewAcmeIssuedCert(client, user, tlsHost, tlsCert, tlsKey)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ecder, err := x509.MarshalECPrivateKey(privateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
filename := tlsHost + signer + ".acme.key"
|
||||
keypem, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer keypem.Close()
|
||||
err = pem.Encode(keypem, &pem.Block{Type: "EC PRIVATE KEY", Bytes: ecder})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user := MyUser{
|
||||
Email: signer,
|
||||
key: privateKey,
|
||||
}
|
||||
config := lego.NewConfig(&user)
|
||||
config.CADirURL = cadirurl
|
||||
config.Certificate.KeyType = certcrypto.RSA2048
|
||||
client, err := lego.NewClient(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return newAcmeIssuedCert(client, user, tlsHost, tlsCert, tlsKey)
|
||||
}
|
||||
|
||||
func renewAcmeIssuedCert(client *lego.Client, user MyUser, tlsHost string, tlsCert, tlsKey *string) error {
|
||||
var err error
|
||||
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "8000"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "8443"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// New users will need to register
|
||||
if user.Registration, err = client.Registration.QueryRegistration(); err != nil {
|
||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user.Registration = reg
|
||||
}
|
||||
resource, err := client.Certificate.Get(tlsHost, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
certificates, err := client.Certificate.Renew(*resource, true, false, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ioutil.WriteFile(tlsHost+".pem", certificates.PrivateKey, 0600)
|
||||
ioutil.WriteFile(tlsHost+".crt", certificates.Certificate, 0600)
|
||||
// ioutil.WriteFile(tlsHost+".crl", certificates.PrivateKey, 0600)
|
||||
*tlsCert = tlsHost + ".crt"
|
||||
*tlsKey = tlsHost + ".pem"
|
||||
return nil
|
||||
}
|
||||
|
||||
func newAcmeIssuedCert(client *lego.Client, user MyUser, tlsHost string, tlsCert, tlsKey *string) error {
|
||||
var err error
|
||||
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "8000"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "8443"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// New users will need to register
|
||||
if user.Registration, err = client.Registration.QueryRegistration(); err != nil {
|
||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user.Registration = reg
|
||||
}
|
||||
|
||||
request := certificate.ObtainRequest{
|
||||
Domains: []string{tlsHost},
|
||||
Bundle: true,
|
||||
}
|
||||
certificates, err := client.Certificate.Obtain(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ioutil.WriteFile(tlsHost+".pem", certificates.PrivateKey, 0600)
|
||||
ioutil.WriteFile(tlsHost+".crt", certificates.Certificate, 0600)
|
||||
// ioutil.WriteFile(tlsHost+".crl", certificates.PrivateKey, 0600)
|
||||
*tlsCert = tlsHost + ".crt"
|
||||
*tlsKey = tlsHost + ".pem"
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkOrNewTLSCert(tlsHost string, tlsCert, tlsKey *string, auto bool) error {
|
||||
_, certErr := os.Stat(*tlsCert)
|
||||
_, keyErr := os.Stat(*tlsKey)
|
||||
@@ -71,7 +257,7 @@ func checkOrNewTLSCert(tlsHost string, tlsCert, tlsKey *string, auto bool) error
|
||||
fmt.Printf("Unable to read TLS key '%s'\n", *tlsKey)
|
||||
}
|
||||
|
||||
if auto {
|
||||
if !auto {
|
||||
fmt.Printf("Would you like to generate a new self-signed certificate for '%s'? (y or n): ", tlsHost)
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, _ := reader.ReadString('\n')
|
||||
|
@@ -4,9 +4,9 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/idk/reseed-tools/reseed"
|
||||
"github.com/idk/reseed-tools/su3"
|
||||
"github.com/urfave/cli"
|
||||
"i2pgit.org/idk/reseed-tools/reseed"
|
||||
"i2pgit.org/idk/reseed-tools/su3"
|
||||
)
|
||||
|
||||
func NewSu3VerifyCommand() cli.Command {
|
||||
|
@@ -6,4 +6,13 @@ your attention, we're going to take this opportunity to tell you a little about
|
||||
network which uses "Garlic Routing" to maintain privacy. Reseed nodes help you get connected to I2P for the first time,
|
||||
and even though you should only have to use them once in a great while, they are very important services.
|
||||
|
||||

|
||||
[To learn more about I2P, visit the project website](https://geti2p.net)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
[](https://geti2p.net)
|
||||
|
||||
- [Learn more about reseeds here:](https://geti2p.net/en/docs/reseed)
|
||||
- [Learn how to run a reseed here:](https://geti2p.net/en/get-involved/guides/reseed)
|
||||
- [Read the reseed server code and learn about more reseed options here:](https://i2pgit.org/idk/reseed-tools)
|
||||
|
||||
### Here on purpose? Here's a one-time link to a reseed bundle for you.
|
||||
|
@@ -13,3 +13,25 @@ img {
|
||||
margin-right: auto;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.link-button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
font-size: 1em;
|
||||
font-family: serif;
|
||||
}
|
||||
|
||||
.link-button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.link-button:active {
|
||||
color:red;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env sh
|
||||
|
||||
cp -r /var/lib/i2p/go/src/github.com/idk/reseed-tools/content ./content
|
||||
cp -r /var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools/content ./content
|
||||
|
||||
/var/lib/i2p/go/src/github.com/idk/reseed-tools/i2p-tools-1 reseed --yes=true --netdb=/var/lib/i2p/i2p-config/netDb $@
|
||||
/var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools/reseed-tools reseed --yes=true --netdb=/var/lib/i2p/i2p-config/netDb $@
|
||||
|
27
go.mod
27
go.mod
@@ -3,36 +3,17 @@ module i2pgit.org/idk/reseed-tools
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcd v0.21.0-beta // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/cretz/bine v0.1.0
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab // indirect
|
||||
github.com/eyedeekay/sam3 v0.32.32
|
||||
github.com/gomodule/redigo v1.8.3 // indirect
|
||||
github.com/google/gopacket v1.1.19 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/go-acme/lego/v4 v4.3.1
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/jackpal/gateway v1.0.6 // indirect
|
||||
github.com/justinas/alice v1.2.0
|
||||
github.com/koron/go-ssdp v0.0.2 // indirect
|
||||
github.com/libp2p/go-libp2p v0.13.0
|
||||
github.com/libp2p/go-libp2p-core v0.8.0
|
||||
github.com/libp2p/go-libp2p-gostream v0.3.0
|
||||
github.com/libp2p/go-libp2p-gostream v0.3.1
|
||||
github.com/libp2p/go-libp2p-http v0.2.0
|
||||
github.com/libp2p/go-libp2p-noise v0.1.2 // indirect
|
||||
github.com/libp2p/go-netroute v0.1.4 // indirect
|
||||
github.com/libp2p/go-sockaddr v0.1.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/throttled/throttled v2.2.4+incompatible
|
||||
github.com/throttled/throttled/v2 v2.7.1
|
||||
github.com/urfave/cli v1.22.5
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20200225224916-64bca66f6ad3 // indirect
|
||||
gitlab.com/golang-commonmark/markdown v0.0.0-20191127184510-91b5b3c99c19
|
||||
go.opencensus.io v0.22.5 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.16.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect
|
||||
golang.org/x/sys v0.0.0-20201223074533-0d417f636930 // indirect
|
||||
golang.org/x/text v0.3.4
|
||||
golang.org/x/text v0.3.5
|
||||
)
|
||||
|
@@ -41,4 +41,4 @@
|
||||
* numRi per su3 file: 75 --> 77
|
||||
|
||||
2016-01
|
||||
* fork from https://github.com/idk/reseed-tools
|
||||
* fork from https://i2pgit.org/idk/reseed-tools
|
||||
|
2
main.go
2
main.go
@@ -4,8 +4,8 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/idk/reseed-tools/cmd"
|
||||
"github.com/urfave/cli"
|
||||
"i2pgit.org/idk/reseed-tools/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@@ -47,7 +47,7 @@ func ContentPath() (string, error) {
|
||||
return filepath.Join(exPath, "content"), nil
|
||||
}
|
||||
|
||||
func HandleARealBrowser(w http.ResponseWriter, r *http.Request) {
|
||||
func (srv *Server) HandleARealBrowser(w http.ResponseWriter, r *http.Request) {
|
||||
if ContentPathError != nil {
|
||||
http.Error(w, "403 Forbidden", http.StatusForbidden)
|
||||
return
|
||||
@@ -73,6 +73,12 @@ func HandleARealBrowser(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
w.Write([]byte(header))
|
||||
HandleALocalizedFile(w, base.String())
|
||||
w.Write([]byte(`<ul><li><form method="post" action="/i2pseeds" class="inline">
|
||||
<input type="hidden" name="onetime" value="` + srv.Acceptable() + `">
|
||||
<button type="submit" name="submit_param" value="submit_value" class="link-button">
|
||||
Bundle
|
||||
</button>
|
||||
</form></li></ul>`))
|
||||
w.Write([]byte(footer))
|
||||
}
|
||||
}
|
||||
@@ -84,7 +90,7 @@ func HandleAFile(w http.ResponseWriter, dirPath, file string) {
|
||||
path := filepath.Join(BaseContentPath, file)
|
||||
f, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://github.com/idk/reseed-tools\n\t" + err.Error()))
|
||||
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://i2pgit.org/idk/reseed-tools\n\t" + err.Error()))
|
||||
return
|
||||
}
|
||||
CachedDataPages[file] = f
|
||||
@@ -99,7 +105,7 @@ func HandleALocalizedFile(w http.ResponseWriter, dirPath string) {
|
||||
dir := filepath.Join(BaseContentPath, "lang", dirPath)
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://github.com/idk/reseed-tools\n\t" + err.Error()))
|
||||
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://i2pgit.org/idk/reseed-tools\n\t" + err.Error()))
|
||||
}
|
||||
var f []byte
|
||||
for _, file := range files {
|
||||
@@ -110,12 +116,13 @@ func HandleALocalizedFile(w http.ResponseWriter, dirPath string) {
|
||||
path := filepath.Join(dir, file.Name())
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://github.com/idk/reseed-tools\n\t" + err.Error()))
|
||||
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://i2pgit.org/idk/reseed-tools\n\t" + err.Error()))
|
||||
return
|
||||
}
|
||||
f = append(f, []byte(`<div id="`+trimmedName+`">`)...)
|
||||
f = append(f, []byte(md.RenderToString(b))...)
|
||||
f = append(f, []byte(`</div>`)...)
|
||||
|
||||
}
|
||||
CachedLanguagePages[dirPath] = string(f)
|
||||
w.Write([]byte(CachedLanguagePages[dirPath]))
|
||||
|
@@ -3,6 +3,7 @@ package reseed
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"log"
|
||||
@@ -20,8 +21,8 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
gostream "github.com/libp2p/go-libp2p-gostream"
|
||||
p2phttp "github.com/libp2p/go-libp2p-http"
|
||||
"github.com/throttled/throttled"
|
||||
"github.com/throttled/throttled/store"
|
||||
throttled "github.com/throttled/throttled/v2"
|
||||
"github.com/throttled/throttled/v2/store"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -34,9 +35,10 @@ type Server struct {
|
||||
I2PSession *sam3.StreamSession
|
||||
I2PListener *sam3.StreamListener
|
||||
I2PKeys i2pkeys.I2PKeys
|
||||
Reseeder Reseeder
|
||||
Reseeder *ReseederImpl
|
||||
Blacklist *Blacklist
|
||||
OnionListener *tor.OnionService
|
||||
acceptables map[string]time.Time
|
||||
}
|
||||
|
||||
func NewServer(prefix string, trustProxy bool) *Server {
|
||||
@@ -65,6 +67,7 @@ func NewServer(prefix string, trustProxy bool) *Server {
|
||||
server := Server{Server: h, Reseeder: nil}
|
||||
|
||||
th := throttled.RateLimit(throttled.PerHour(4), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(200000))
|
||||
thw := throttled.RateLimit(throttled.PerHour(30), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(200000))
|
||||
|
||||
middlewareChain := alice.New()
|
||||
if trustProxy {
|
||||
@@ -79,13 +82,85 @@ func NewServer(prefix string, trustProxy bool) *Server {
|
||||
})
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware, browsingMiddleware).Then(errorHandler))
|
||||
mux.Handle("/", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware, thw.Throttle, server.browsingMiddleware).Then(errorHandler))
|
||||
mux.Handle(prefix+"/i2pseeds.su3", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware, verifyMiddleware, th.Throttle).Then(http.HandlerFunc(server.reseedHandler)))
|
||||
server.Handler = mux
|
||||
|
||||
return &server
|
||||
}
|
||||
|
||||
// See use of crypto/rand on:
|
||||
// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go
|
||||
const (
|
||||
letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" // 52 possibilities
|
||||
letterIdxBits = 6 // 6 bits to represent 64 possibilities / indexes
|
||||
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
|
||||
)
|
||||
|
||||
func SecureRandomAlphaString() string {
|
||||
length := 16
|
||||
result := make([]byte, length)
|
||||
bufferSize := int(float64(length) * 1.3)
|
||||
for i, j, randomBytes := 0, 0, []byte{}; i < length; j++ {
|
||||
if j%bufferSize == 0 {
|
||||
randomBytes = SecureRandomBytes(bufferSize)
|
||||
}
|
||||
if idx := int(randomBytes[j%length] & letterIdxMask); idx < len(letterBytes) {
|
||||
result[i] = letterBytes[idx]
|
||||
i++
|
||||
}
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// SecureRandomBytes returns the requested number of bytes using crypto/rand
|
||||
func SecureRandomBytes(length int) []byte {
|
||||
var randomBytes = make([]byte, length)
|
||||
_, err := rand.Read(randomBytes)
|
||||
if err != nil {
|
||||
log.Fatal("Unable to generate random bytes")
|
||||
}
|
||||
return randomBytes
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
func (srv *Server) Acceptable() string {
|
||||
if srv.acceptables == nil {
|
||||
srv.acceptables = make(map[string]time.Time)
|
||||
}
|
||||
if len(srv.acceptables) > 50 {
|
||||
for val := range srv.acceptables {
|
||||
srv.CheckAcceptable(val)
|
||||
}
|
||||
for val := range srv.acceptables {
|
||||
if len(srv.acceptables) < 50 {
|
||||
break
|
||||
}
|
||||
delete(srv.acceptables, val)
|
||||
}
|
||||
}
|
||||
acceptme := SecureRandomAlphaString()
|
||||
srv.acceptables[acceptme] = time.Now()
|
||||
return acceptme
|
||||
}
|
||||
|
||||
func (srv *Server) CheckAcceptable(val string) bool {
|
||||
if srv.acceptables == nil {
|
||||
srv.acceptables = make(map[string]time.Time)
|
||||
}
|
||||
if timeout, ok := srv.acceptables[val]; ok {
|
||||
checktime := time.Now().Sub(timeout)
|
||||
if checktime > (4 * time.Minute) {
|
||||
delete(srv.acceptables, val)
|
||||
return false
|
||||
}
|
||||
delete(srv.acceptables, val)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (srv *Server) ListenAndServe() error {
|
||||
addr := srv.Addr
|
||||
if addr == "" {
|
||||
@@ -245,7 +320,7 @@ func (srv *Server) ListenAndServeI2P(samaddr string, I2PKeys i2pkeys.I2PKeys) er
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("I2P server started on http://%v.onion\n", srv.OnionListener.ID)
|
||||
log.Printf("I2P server started on http://%v.b32.i2p\n", srv.I2PListener.Addr().(i2pkeys.I2PAddr).Base32())
|
||||
return srv.Serve(srv.I2PListener)
|
||||
}
|
||||
|
||||
@@ -291,10 +366,13 @@ func loggingMiddleware(next http.Handler) http.Handler {
|
||||
return handlers.CombinedLoggingHandler(os.Stdout, next)
|
||||
}
|
||||
|
||||
func browsingMiddleware(next http.Handler) http.Handler {
|
||||
func (srv *Server) browsingMiddleware(next http.Handler) http.Handler {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
if srv.CheckAcceptable(r.FormValue("onetime")) {
|
||||
srv.reseedHandler(w, r)
|
||||
}
|
||||
if i2pUserAgent != r.UserAgent() {
|
||||
HandleARealBrowser(w, r)
|
||||
srv.HandleARealBrowser(w, r)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
|
@@ -15,7 +15,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/idk/reseed-tools/su3"
|
||||
"i2pgit.org/idk/reseed-tools/su3"
|
||||
)
|
||||
|
||||
type routerInfo struct {
|
||||
@@ -33,13 +33,13 @@ func (p Peer) Hash() int {
|
||||
return int(crc32.ChecksumIEEE(c))
|
||||
}
|
||||
|
||||
type Reseeder interface {
|
||||
/*type Reseeder interface {
|
||||
// get an su3 file (bytes) for a peer
|
||||
PeerSu3Bytes(peer Peer) ([]byte, error)
|
||||
}
|
||||
}*/
|
||||
|
||||
type ReseederImpl struct {
|
||||
netdb NetDbProvider
|
||||
netdb *LocalNetDbImpl
|
||||
su3s chan [][]byte
|
||||
|
||||
SigningKey *rsa.PrivateKey
|
||||
@@ -49,7 +49,7 @@ type ReseederImpl struct {
|
||||
NumSu3 int
|
||||
}
|
||||
|
||||
func NewReseeder(netdb NetDbProvider) *ReseederImpl {
|
||||
func NewReseeder(netdb *LocalNetDbImpl) *ReseederImpl {
|
||||
return &ReseederImpl{
|
||||
netdb: netdb,
|
||||
su3s: make(chan [][]byte),
|
||||
@@ -224,10 +224,10 @@ func (rs *ReseederImpl) createSu3(seeds []routerInfo) (*su3.File, error) {
|
||||
return su3File, nil
|
||||
}
|
||||
|
||||
type NetDbProvider interface {
|
||||
/*type NetDbProvider interface {
|
||||
// Get all router infos
|
||||
RouterInfos() ([]routerInfo, error)
|
||||
}
|
||||
}*/
|
||||
|
||||
type LocalNetDbImpl struct {
|
||||
Path string
|
||||
|
Reference in New Issue
Block a user