1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 18:15:42 +01:00

Merge branch 'main' into experimental-integration-test-coverage

This commit is contained in:
Bernhard Reiter 2022-04-13 14:28:51 +02:00
commit 50ec5678cb
No known key found for this signature in database
GPG key ID: 2B7BA3BF9BC3A554
25 changed files with 712 additions and 82 deletions

19
.github/workflows/generate-markdown.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: generate-markdown
on:
push:
branches:
- "main"
- "build-scripts"
pull_request:
branches:
- "main"
jobs:
auto-update-readme:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Markdown autodocs
uses: dineshsonachalam/markdown-autodocs@v1.0.4
with:
output_file_paths: '[./README.md, ./docs/*.md]'

View file

@ -37,6 +37,22 @@ tag_checked_out:
git checkout -q tags/${BUILDTAG} git checkout -q tags/${BUILDTAG}
@echo Don\'t forget that we are in checked out tag $(BUILDTAG) now. @echo Don\'t forget that we are in checked out tag $(BUILDTAG) now.
# use bash shell arithmetic and sed to turn a `git describe` version
# into a semver version. For this we increase the PATCH number, so that
# any commit after a tag is considered newer than the semver from the tag
# without an optional 'v'
GITDESC := $(shell git describe)
GITDESCPATCH := $(shell echo '$(GITDESC)' | sed -E 's/v?[0-9]+\.[0-9]+\.([0-9]+)[-+]?.*/\1/')
SEMVERPATCH := $(shell echo $$(( $(GITDESCPATCH) + 1 )))
# Hint: The regexp in the next line only matches if there is a hyphen (`-`)
# and we can assume that git describe has added a string after the tag
SEMVER := $(shell echo '$(GITDESC)' | sed -E 's/v?([0-9]+\.[0-9]+\.)([0-9]+)(-.*)/\1$(SEMVERPATCH)\3/' )
testsemver:
@echo from \'$(GITDESC)\' transformed to \'$(SEMVER)\'
# Set -ldflags parameter to pass the semversion.
LDFLAGS = -ldflags "-X github.com/csaf-poc/csaf_distribution/util.SemVersion=$(SEMVER)"
# Build binaries and place them under bin-$(GOOS)-$(GOARCH) # Build binaries and place them under bin-$(GOOS)-$(GOARCH)
# Using 'Target-specific Variable Values' to specify the build target system # Using 'Target-specific Variable Values' to specify the build target system
@ -48,7 +64,7 @@ build_win: GOOS = windows
build_linux build_win: build_linux build_win:
$(eval BINDIR = bin-$(GOOS)-$(GOARCH)/ ) $(eval BINDIR = bin-$(GOOS)-$(GOARCH)/ )
$(MKDIR) $(BINDIR) $(MKDIR) $(BINDIR)
env GOARCH=$(GOARCH) GOOS=$(GOOS) $(BUILD) -o $(BINDIR) -v ./cmd/... env GOARCH=$(GOARCH) GOOS=$(GOOS) $(BUILD) -o $(BINDIR) $(LDFLAGS) -v ./cmd/...
# Remove bin-*-* directories # Remove bin-*-* directories

View file

@ -3,8 +3,8 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// //
// SPDX-FileCopyrightText: 2021 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de> // SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
// Software-Engineering: 2021 Intevation GmbH <https://intevation.de> // Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
package main package main
@ -12,11 +12,13 @@ import (
"bufio" "bufio"
_ "embed" // Used for embedding. _ "embed" // Used for embedding.
"encoding/json" "encoding/json"
"fmt"
"html/template" "html/template"
"io" "io"
"log" "log"
"os" "os"
"github.com/csaf-poc/csaf_distribution/util"
"github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
) )
@ -29,6 +31,7 @@ type options struct {
Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"` Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"`
ClientCert *string `long:"client-cert" description:"TLS client certificate file (PEM encoded data)" value-name:"CERT-FILE"` ClientCert *string `long:"client-cert" description:"TLS client certificate file (PEM encoded data)" value-name:"CERT-FILE"`
ClientKey *string `long:"client-key" description:"TLS client private key file (PEM encoded data)" value-name:"KEY-FILE"` ClientKey *string `long:"client-key" description:"TLS client private key file (PEM encoded data)" value-name:"KEY-FILE"`
Version bool `long:"version" description:"Display version of the binary"`
} }
func errCheck(err error) { func errCheck(err error) {
@ -132,6 +135,11 @@ func realMain(args []string) {
domains, err := flags.ParseArgs(opts, args) domains, err := flags.ParseArgs(opts, args)
errCheck(err) errCheck(err)
if opts.Version {
fmt.Println(util.SemVersion)
return
}
if len(domains) == 0 { if len(domains) == 0 {
log.Println("No domains given.") log.Println("No domains given.")
return return

View file

@ -82,7 +82,13 @@ func (c *controller) auth(
verify := os.Getenv("SSL_CLIENT_VERIFY") verify := os.Getenv("SSL_CLIENT_VERIFY")
log.Printf("SSL_CLIENT_VERIFY: %s\n", verify) log.Printf("SSL_CLIENT_VERIFY: %s\n", verify)
log.Printf("ca: %s\n", os.Getenv("SSL_CLIENT_I_DN")) if verify == "SUCCESS" || strings.HasPrefix(verify, "FAILED") {
// potentially we want to see the Issuer when there is a problem
// but it is not clear if we get this far in case of "FAILED".
// docs (accessed 2022-03-31 when 1.20.2 was current stable):
// https://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_verify
log.Printf("SSL_CLIENT_I_DN: %s\n", os.Getenv("SSL_CLIENT_I_DN"))
}
switch { switch {
case verify == "SUCCESS" && (c.cfg.Issuer == nil || *c.cfg.Issuer == os.Getenv("SSL_CLIENT_I_DN")): case verify == "SUCCESS" && (c.cfg.Issuer == nil || *c.cfg.Issuer == os.Getenv("SSL_CLIENT_I_DN")):

View file

@ -9,16 +9,32 @@
package main package main
import ( import (
"fmt"
"log" "log"
"net/http/cgi" "net/http/cgi"
"github.com/csaf-poc/csaf_distribution/util"
"github.com/jessevdk/go-flags"
) )
type options struct {
Version bool `long:"version" description:"Display version of the binary"`
}
func main() { func main() {
cfg, err := loadConfig() cfg, err := loadConfig()
if err != nil { if err != nil {
log.Fatalf("error: %v\n", err) log.Fatalf("error: %v\n", err)
} }
var opts options
parser := flags.NewParser(&opts, flags.Default)
parser.Parse()
if opts.Version {
fmt.Println(util.SemVersion)
return
}
c, err := newController(cfg) c, err := newController(cfg)
if err != nil { if err != nil {
log.Fatalf("error: %v\n", err) log.Fatalf("error: %v\n", err)

View file

@ -23,6 +23,7 @@ import (
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/csaf-poc/csaf_distribution/csaf" "github.com/csaf-poc/csaf_distribution/csaf"
"github.com/csaf-poc/csaf_distribution/util"
"github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
"github.com/mitchellh/go-homedir" "github.com/mitchellh/go-homedir"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
@ -48,7 +49,8 @@ type options struct {
Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"` Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"`
Config *string `short:"c" long:"config" description:"Path to config ini file" value-name:"INI-FILE" no-ini:"true"` Config *string `short:"c" long:"config" description:"Path to config ini file" value-name:"INI-FILE" no-ini:"true"`
Version bool `long:"version" description:"Display version of the binary"`
} }
type processor struct { type processor struct {
@ -359,6 +361,11 @@ func main() {
args, err := parser.Parse() args, err := parser.Parse()
check(err) check(err)
if opts.Version {
fmt.Println(util.SemVersion)
return
}
if opts.Config != nil { if opts.Config != nil {
iniParser := flags.NewIniParser(parser) iniParser := flags.NewIniParser(parser)
iniParser.ParseAsDefaults = true iniParser.ParseAsDefaults = true

View file

@ -5,29 +5,29 @@ a web browser.
### Configure nginx ### Configure nginx
Assuming the relevant server block is in `/etc/nginx/sites-enabled/default` and the CA used to verify the client certificates is under `/etc/ssl/`, Assuming the relevant server block is in `/etc/nginx/sites-enabled/default` and the CA used to verify the client certificates is under `/etc/ssl/`,
adjust it like shown in the following example: adjust the content of the `server{}` block like shown in the following example:
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../docs/scripts/TLSClientConfigsForITest.sh&lines=25-40) -->
<!-- The below code snippet is automatically added from ../docs/scripts/TLSClientConfigsForITest.sh -->
```sh
ssl_client_certificate '${SSL_CLIENT_CERTIFICATE}'; # e.g. ssl_client_certificate /etc/ssl/rootca-cert.pem;
ssl_verify_client optional;
ssl_verify_depth 2;
# This example allows access to all three TLP locations for all certs.
location ~ /.well-known/csaf/(red|green|amber)/{
# For atomic directory switches
disable_symlinks off;
autoindex on;
# in this location access is only allowed with client certs
if ($ssl_client_verify != SUCCESS){
# we use status code 404 == "Not Found", because we do not
# want to reveal if this location exists or not.
return 404;
}
}
``` ```
server { <!-- MARKDOWN-AUTO-DOCS:END -->
# Other Config
# ...
ssl_client_certificate /etc/ssl/rootca-cert.pem;
ssl_verify_client optional;
ssl_verify_depth 2;
# This example allows access to all three TLP locations for all certs.
location ~ /.well-known/csaf/(red|green|amber)/{
autoindex on;
# in this location access is only allowed with client certs
if ($ssl_client_verify != SUCCESS){
# we use status code 404 == "Not Found", because we do not
# want to reveal if this location exists or not.
return 404;
}
}
}
```
This will restrict the access to the defined paths in the ```location``` This will restrict the access to the defined paths in the ```location```
directive to only authenticated client certificates issued by the CAs directive to only authenticated client certificates issued by the CAs
which are configured with `ssl_client_certificate`. which are configured with `ssl_client_certificate`.
@ -37,8 +37,15 @@ differently, you could use several location blocks
each which a single `if` that matches the `$ssl_client_i_dn` variable each which a single `if` that matches the `$ssl_client_i_dn` variable
to CAs that you would want to allow for that location. to CAs that you would want to allow for that location.
If you want to restrict the writing permission and the accessing to the web-interface of the `csaf_provider` to only some TLS client certificates, the CA issuer of these certificates should be assigned to the `issuer` config option in the `/user/lib/csaf/config.toml` file e.g. `issuer = "C=DE,O=CSAF Tools Development (internal),CN=Tester" `. If you want to restrict the writing permission and access to the web-interface
To inspect the accepted format for this field you can check the value of the `ca:` in the nginx log file `/var/log/nginx/error.log`. of the `csaf_provider` to only some TLS client certificates,
the CA issuer of these certificates should be assigned to the `issuer`
config option in the `/user/lib/csaf/config.toml` file
e.g. `issuer = "C=DE,O=CSAF Tools Development (internal),CN=Tester" `.
The value will be checked against the `$ssl_client_i_dn` variable
within the `csaf_provider`.
To inspect the precise string of certain certificate, try it and
check the logged value in the nginx log file, e.g. `/var/log/nginx/error.log`.
Reload or restart nginx to apply the changes (e.g. `systemctl reload nginx` Reload or restart nginx to apply the changes (e.g. `systemctl reload nginx`
on Debian or Ubuntu.) on Debian or Ubuntu.)
@ -47,6 +54,6 @@ To test this see [development-client-certs.md](development-client-certs.md) and
* From the browser after importing the `testclient1.p12`: * From the browser after importing the `testclient1.p12`:
nagivate to the protected directories. nagivate to the protected directories.
* With curl: `curl https://{serverURL}/.well-known/csaf/red/ --cert-type p12 --cert testclient1.p12`. * With curl: `curl https://{serverURL}/.well-known/csaf/red/ --cert-type p12 --cert testclient1.p12`.
(If the server uses self-signed certifcate one of the following options should be added to the `curl` command: (If the server uses a root certifcate that is not in the default certificate store one of the following options should be added to the `curl` command:
`--insecure` to disable the verification, * `--insecure` to disable the verification,
`--cacert {CA-Certificate-File}` to pass the CA-Certificate that verifies the server). * `--cacert {CA-Certificate-File}` to pass the CA-Certificate that verifies the server).

View file

@ -11,14 +11,16 @@ which is suitable for testing in development setups.
## create root CA ## create root CA
```bash <!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../docs/scripts/createRootCAForITest.sh&lines=13-50) -->
mkdir devca1 <!-- The below code snippet is automatically added from ../docs/scripts/createRootCAForITest.sh -->
cd devca1 ```sh
mkdir -p ~/${FOLDERNAME}
cd ~/${FOLDERNAME}
certtool --generate-privkey --outfile rootca-key.pem certtool --generate-privkey --outfile rootca-key.pem
echo ' echo '
organization = "CSAF Tools Development (internal)" organization = "'${ORGANAME}'"
country = DE country = DE
cn = "Tester" cn = "Tester"
@ -30,19 +32,21 @@ serial = 001
expiration_days = 100 expiration_days = 100
' >gnutls-certtool.rootca.template ' >gnutls-certtool.rootca.template
certtool --generate-self-signed --load-privkey rootca-key.pem --outfile rootca-cert.pem --template gnutls-certtool.rootca.template certtool --generate-self-signed --load-privkey rootca-key.pem --outfile rootca-cert.pem --template gnutls-certtool.rootca.template --stdout | head -1
``` ```
<!-- MARKDOWN-AUTO-DOCS:END -->
## create webserver cert ## create webserver cert
```bash <!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../docs/scripts/createWebserverCertForITest.sh&lines=11-55) -->
#being in devca1/ <!-- The below code snippet is automatically added from ../docs/scripts/createWebserverCertForITest.sh -->
```sh
cd ~/${FOLDERNAME}
certtool --generate-privkey --outfile testserver-key.pem certtool --generate-privkey --outfile testserver-key.pem
echo ' echo '
organization = "CSAF Tools Development (internal)" organization = "'${ORGANAME}'"
country = DE country = DE
cn = "Service Testing" cn = "Service Testing"
@ -58,14 +62,20 @@ serial = 010
expiration_days = 50 expiration_days = 50
' > gnutls-certtool.testserver.template ' > gnutls-certtool.testserver.template
certtool --generate-certificate --load-privkey testserver-key.pem --outfile testserver.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testserver.template certtool --generate-certificate --load-privkey testserver-key.pem --outfile testserver.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testserver.template --stdout | head -1
cat testserver.crt rootca-cert.pem >bundle.crt cat testserver.crt rootca-cert.pem >bundle.crt
echo Full path config options for nginx:
echo " ssl_certificate \"$PWD/bundle.crt\";"
echo " ssl_certificate_key \"$PWD/testserver-key.pem\";"
```
SSL_CERTIFICATE=$(
echo "$PWD/bundle.crt"
)
SSL_CERTIFICATE_KEY=$(
echo "$PWD/testserver-key.pem"
)
```
<!-- MARKDOWN-AUTO-DOCS:END -->
Replace `{FOLDERNAME}` with the folder name you want to save the keys into it and `{ORGANAME}` with the organisation name that should be used by creating the Certificate.
## Considerations and References ## Considerations and References

View file

@ -10,13 +10,15 @@ would used for server and for client certificates.)
The following lines directly create the client certificate. The following lines directly create the client certificate.
(As opposed to first creating a certificate signing request and (As opposed to first creating a certificate signing request and
then signing it.) then signing it.)
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../docs/scripts/createCCForITest.sh&lines=15-35) -->
<!-- The below code snippet is automatically added from ../docs/scripts/createCCForITest.sh -->
```sh
cd ~/${FOLDERNAME}
```bash
# being in devca1/
certtool --generate-privkey --outfile testclient1-key.pem certtool --generate-privkey --outfile testclient1-key.pem
echo ' echo '
organization = "CSAF Tools Development (internal)" organization = "'${ORGANAME}'"
country = DE country = DE
cn = "TLS Test Client 1" cn = "TLS Test Client 1"
@ -28,18 +30,23 @@ serial = 020
expiration_days = 50 expiration_days = 50
' > gnutls-certtool.testclient1.template ' > gnutls-certtool.testclient1.template
certtool --generate-certificate --load-privkey testclient1-key.pem --outfile testclient1.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient1.template certtool --generate-certificate --load-privkey testclient1-key.pem --outfile testclient1.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient1.template --stdout | head -1
certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient1.crt --load-privkey testclient1-key.pem --to-p12 --p12-name "Test Client 1" --null-password --outder --outfile testclient1.p12 certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient1.crt --load-privkey testclient1-key.pem --to-p12 --p12-name "Test Client 1" --null-password --outder --outfile testclient1.p12
``` ```
<!-- MARKDOWN-AUTO-DOCS:END -->
and we do a second one with shorter expiration day: and we do a second one with shorter expiration day:
```bash <!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../docs/scripts/createCCForITest.sh&lines=34-53) -->
<!-- The below code snippet is automatically added from ../docs/scripts/createCCForITest.sh -->
```sh
certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient1.crt --load-privkey testclient1-key.pem --to-p12 --p12-name "Test Client 1" --null-password --outder --outfile testclient1.p12
certtool --generate-privkey --outfile testclient2-key.pem certtool --generate-privkey --outfile testclient2-key.pem
echo ' echo '
organization = "CSAF Tools Development (internal)" organization = "'${ORGANAME}'"
country = DE country = DE
cn = "TLS Test Client 2" cn = "TLS Test Client 2"
@ -51,13 +58,12 @@ serial = 021
expiration_days = 1 expiration_days = 1
' > gnutls-certtool.testclient2.template ' > gnutls-certtool.testclient2.template
certtool --generate-certificate --load-privkey testclient2-key.pem --outfile testclient2.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient2.template certtool --generate-certificate --load-privkey testclient2-key.pem --outfile testclient2.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient2.template --stdout | head -1
certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient2.crt --load-privkey testclient2-key.pem --to-p12 --p12-name "Test Client 2" --null-password --outder --outfile testclient2.p12 certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient2.crt --load-privkey testclient2-key.pem --to-p12 --p12-name "Test Client 2" --null-password --outder --outfile testclient2.p12
``` ```
<!-- MARKDOWN-AUTO-DOCS:END -->
In case of many CAs are used to verify the client certificates these should be included in the list of the allowed CA certificates in the `ssl_client_certificate` bundle of nginx. In case of many CAs are used to verify the client certificates these should be included in the list of the allowed CA certificates in the `ssl_client_certificate` bundle of nginx.
E.g. `cat rootca-cert-1.pem rootca-cert-2.pem >> allowedCAs.pem`. Nginx config: `ssl_client_certificate allowedCAs.pem;` E.g. `cat rootca-cert-1.pem rootca-cert-2.pem >> allowedCAs.pem`. Nginx config: `ssl_client_certificate allowedCAs.pem;`

View file

@ -44,25 +44,21 @@ We recommend to
### Example configuration ### Example configuration
Assuming the relevant server block is in `/etc/nginx/sites-enabled/default`, Assuming the relevant server block is in `/etc/nginx/sites-enabled/default`,
change the `listen` configuration and add options so nginx change the `listen` configuration in the `server {}` block and add options so nginx
finds your your private key and the certificate chain. finds your your private key and the certificate chain.
```nginx <!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../docs/scripts/TLSConfigsForITest.sh&lines=31-37) -->
server { <!-- The below code snippet is automatically added from ../docs/scripts/TLSConfigsForITest.sh -->
listen 443 ssl http2 default_server; # ipv4 ```sh
listen [::]:443 ssl http2 default_server; # ipv6 listen 443 ssl default_server; # ipv4
server_name www.example.com listen [::]:443 ssl http2 default_server; # ipv6
ssl_certificate /etc/ssl/{domainName}.pem; # or bundle.crt ssl_certificate '${SSL_CERTIFICATE}'; # e.g. ssl_certificate /etc/ssl/csaf/bundle.crt
ssl_certificate_key /etc/ssl/{domainName}.key"; ssl_certificate_key '${SSL_CERTIFICATE_KEY}'; # e.g. ssl_certificate_key /etc/ssl/csaf/testserver-key.pem;
ssl_protocols TLSv1.2 TLSv1.3; ssl_protocols TLSv1.2 TLSv1.3;
# Other Config
# ...
}
``` ```
<!-- MARKDOWN-AUTO-DOCS:END -->
Replace `{domainName}` with the name for your certificate in the example.
Reload or restart nginx to apply the changes (e.g. `systemctl reload nginx` Reload or restart nginx to apply the changes (e.g. `systemctl reload nginx`
on Debian or Ubuntu.) on Debian or Ubuntu.)

View file

@ -24,7 +24,9 @@ chmod -R g+w .
Modify the content of `/etc/nginx/fcgiwrap.conf` like following: Modify the content of `/etc/nginx/fcgiwrap.conf` like following:
``` <!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../docs/scripts/setupProviderForITest.sh&lines=24-52) -->
<!-- The below code snippet is automatically added from ../docs/scripts/setupProviderForITest.sh -->
```sh
# Include this file on your nginx.conf to support debian cgi-bin scripts using # Include this file on your nginx.conf to support debian cgi-bin scripts using
# fcgiwrap # fcgiwrap
location /cgi-bin/ { location /cgi-bin/ {
@ -55,7 +57,7 @@ location /cgi-bin/ {
fastcgi_param SSL_CLIENT_I_DN $ssl_client_i_dn; fastcgi_param SSL_CLIENT_I_DN $ssl_client_i_dn;
} }
``` ```
<!-- MARKDOWN-AUTO-DOCS:END -->
Add to `/etc/nginx/sites-enabled/default`: Add to `/etc/nginx/sites-enabled/default`:
``` ```
@ -89,28 +91,32 @@ Rename and place the `csaf_provider` binary file under `/usr/lib/cgi-bin/csaf_pr
Create configuration file under `/usr/lib/csaf/config.toml`: Create configuration file under `/usr/lib/csaf/config.toml`:
``` <!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../docs/scripts/setupProviderForITest.sh&lines=82-87) -->
<!-- The below code snippet is automatically added from ../docs/scripts/setupProviderForITest.sh -->
```sh
# upload_signature = true # upload_signature = true
# key = "/usr/lib/csaf/public.asc" # key = "/usr/lib/csaf/public.asc"
key = "/usr/lib/csaf/private.asc" key = "/usr/lib/csaf/private.asc"
#tlps = ["green", "red"] #tlps = ["green", "red"]
canonical_url_prefix = "http://192.168.56.102" canonical_url_prefix = "https://localhost:8443"
#no_passphrase = true #no_passphrase = true
``` ```
with suitable replacements <!-- MARKDOWN-AUTO-DOCS:END -->
(This configurations-example assumes that the private/public keys are available under `/usr/lib/csaf/`). with suitable [replacements](#provider-options)
(This configuration examples assumes that the private/public keys are available under `/usr/lib/csaf/`).
with suitable [replacements](#provider-options).
Create the folders: Create the folders:
```(shell) ```(shell)
curl http://192.168.56.102/cgi-bin/csaf_provider.go/create curl https://192.168.56.102/cgi-bin/csaf_provider.go/create --cert-type p12 --cert {clientCertificatfile}
``` ```
Replace {clientCertificate} with the client certificate file.
Or using the uploader: Or using the uploader:
```(shell) ```(shell)
./csaf_uploader -a create -u http://192.168.56.102/cgi-bin/csaf_provider.go ./csaf_uploader -a create -u http://192.168.56.102/cgi-bin/csaf_provider.go -p {password}
``` ```
Replace {password} with the password used for the authentication with csaf_provider.
This needs to set the `password` option in `config.toml`.
## Provider options ## Provider options
Provider has many config options described as following: Provider has many config options described as following:
@ -119,9 +125,9 @@ Provider has many config options described as following:
- key: The private OpenPGP key. - key: The private OpenPGP key.
- folder: Specify the root folder. Default: `/var/www/`. - folder: Specify the root folder. Default: `/var/www/`.
- web: Specify the web folder. Default: `/var/www/html`. - web: Specify the web folder. Default: `/var/www/html`.
- tlps: Set the allowed TLP comming with the upload request (one or more of "csaf", "white", "amber", "green", "red"). - tlps: Set the allowed TLP comming with the upload request (one or more of "csaf", "white", "amber", "green", "red").
The "csaf" selection lets the provider takes the value from the CSAF document. The "csaf" selection lets the provider takes the value from the CSAF document.
These affects the list items in the web interface. These affects the list items in the web interface.
Default: `["csaf", "white", "amber", "green", "red"]`. Default: `["csaf", "white", "amber", "green", "red"]`.
- upload_signature: Send signature with the request, an additional input-field in the web interface will be shown to let user enter an ascii armored signature. Default: `false`. - upload_signature: Send signature with the request, an additional input-field in the web interface will be shown to let user enter an ascii armored signature. Default: `false`.
- openpgp_url: URL to OpenPGP key-server. Default: `https://openpgp.circl.lu`. - openpgp_url: URL to OpenPGP key-server. Default: `https://openpgp.circl.lu`.

25
docs/scripts/Readme.md Normal file
View file

@ -0,0 +1,25 @@
Scripts for assisting the Integration tests. They are written on Ubuntu 20.04 TLS amd64.
- `prepareUbunutForITest.sh` installs the required packages for the csaf_distribution integration tests on a naked ubuntu 20.04 LTS amd64.
- `TLSConfigsForITest.sh` generates a root CA and webserver cert by running `createRootCAForITest.sh` and `createWebserverCertForITest.sh`
and configures nginx for serving TLS connections.
- `TLSClientConfigsForITest.sh` generates client certificates by calling `createCCForITest.sh` which uses the root certificate initialized before with `createRootCAForITest.sh`. It configures nginx to enable the authentication with client certificate. (This assumes that the same folder name is used to create the root certificate)
- `setupProviderForITest.sh` builds the csaf_provider, writes the required nginx configurations and create the initial folders. IT calls `uploadToProvider.sh` to upload some csaf example files to the provider.
As creating the folders needs to authenticate with the csaf_provider, the configurations of TLS server and Client certificate authentication should be set. So it is recommended to call the scripts in this order: `TLSConfigsForITest.sh`, `TLSClientConfigsForITest.sh`, `setupProviderForITest.sh`
Calling example (as root):
``` bash
curl --fail -O https://raw.githubusercontent.com/csaf-poc/csaf_distribution/main/docs/scripts/prepareUbuntuInstanceForITests.sh
bash prepareUbuntuInstanceForITests.sh
git clone https://github.com/csaf-poc/csaf_distribution.git
pushd csaf_distribution/docs/scripts/
env FOLDERNAME=devca1 ORGANAME="CSAF Tools Development (internal)" ./TLSConfigsForITest.sh
env FOLDERNAME=devca1 ORGANAME="CSAF Tools Development (internal)" ./TLSClientConfigsForITest.sh
./setupProviderForITest.sh
```

View file

@ -0,0 +1,45 @@
#!/usr/bin/env bash
# This file is Free Software under the MIT License
# without warranty, see README.md and LICENSES/MIT.txt for details.
#
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
# Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
# It sets the right nginx configurations for enabling client certificate authentication.
# FOLDERNAME and ORGANAME variables must be set.
# FOLDERNAME: Where to store the CAs and keys.
# ORGANAME: The organization name used in the CA template.
# Usage Example: env FOLDERNAME=devca1 ORGANAME="CSAF Tools Development (internal)" ./TLSClientConfigsForITest.sh
set -e
NGINX_CONFIG_PATH=/etc/nginx/sites-available/default
cd ~/csaf_distribution/docs/scripts/
source ./createCCForITest.sh
echo '
ssl_client_certificate '${SSL_CLIENT_CERTIFICATE}'; # e.g. ssl_client_certificate /etc/ssl/rootca-cert.pem;
ssl_verify_client optional;
ssl_verify_depth 2;
# This example allows access to all three TLP locations for all certs.
location ~ /.well-known/csaf/(red|green|amber)/{
# For atomic directory switches
disable_symlinks off;
autoindex on;
# in this location access is only allowed with client certs
if ($ssl_client_verify != SUCCESS){
# we use status code 404 == "Not Found", because we do not
# want to reveal if this location exists or not.
return 404;
}
}
'> clientCertificateConfigs.txt
sed -i "/^server {/r ${HOME}/${FOLDERNAME}/clientCertificateConfigs.txt" $NGINX_CONFIG_PATH
systemctl reload nginx

View file

@ -0,0 +1,52 @@
#!/usr/bin/env bash
# This file is Free Software under the MIT License
# without warranty, see README.md and LICENSES/MIT.txt for details.
#
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
# Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
# This script generates webserver cert that is signed with the generated root CA.
# It sets the right nginx configurations for serving TLS connections.
# FOLDERNAME and ORGANAME variables must be set.
# FOLDERNAME: Where to store the CAs and keys.
# ORGANAME: The organization name used in the CA template.
# Usage Example: env FOLDERNAME=devca1 ORGANAME="CSAF Tools Development (internal)" ./TLSConfigsForITest.sh
set -e
NGINX_CONFIG_PATH=/etc/nginx/sites-available/default
cd ~/csaf_distribution/docs/scripts/
## Create Root CA
./createRootCAForITest.sh
## Create webserver cert
source ./createWebserverCertForITest.sh
# Configure nginx
echo '
listen 443 ssl default_server; # ipv4
listen [::]:443 ssl http2 default_server; # ipv6
ssl_certificate '${SSL_CERTIFICATE}'; # e.g. ssl_certificate /etc/ssl/csaf/bundle.crt
ssl_certificate_key '${SSL_CERTIFICATE_KEY}'; # e.g. ssl_certificate_key /etc/ssl/csaf/testserver-key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
' > TLSConfigs.txt
# a second listener port for testing setup where someone wants to tunnel access
# to an unpriviledged port and still have the same access url
echo '
listen 8443 ssl default_server; # ipv4
listen [::]:8443 ssl http2 default_server; # ipv6
' > TLS8443Configs.txt
cp $NGINX_CONFIG_PATH $NGINX_CONFIG_PATH.org
sed -i "/^server {/r ${HOME}/${FOLDERNAME}/TLSConfigs.txt" $NGINX_CONFIG_PATH
sed -i "/^server {/r ${HOME}/${FOLDERNAME}/TLS8443Configs.txt" $NGINX_CONFIG_PATH
sed -i "/^\s*listen.*80/d" $NGINX_CONFIG_PATH # Remove configs for listinig on port 80
systemctl reload nginx

View file

@ -0,0 +1,57 @@
# This file is Free Software under the MIT License
# without warranty, see README.md and LICENSES/MIT.txt for details.
#
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
# Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
# This scripts creates two client certificates. It uses for signing the root certifcate
# created with `createRootCAForITest.sh` that must be run earlier.
set -e
mkdir -p ~/${FOLDERNAME}
cd ~/${FOLDERNAME}
certtool --generate-privkey --outfile testclient1-key.pem
echo '
organization = "'${ORGANAME}'"
country = DE
cn = "TLS Test Client 1"
tls_www_client
signing_key
encryption_key
serial = 020
expiration_days = 50
' > gnutls-certtool.testclient1.template
certtool --generate-certificate --load-privkey testclient1-key.pem --outfile testclient1.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient1.template --stdout | head -1
certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient1.crt --load-privkey testclient1-key.pem --to-p12 --p12-name "Test Client 1" --null-password --outder --outfile testclient1.p12
certtool --generate-privkey --outfile testclient2-key.pem
echo '
organization = "'${ORGANAME}'"
country = DE
cn = "TLS Test Client 2"
tls_www_client
signing_key
encryption_key
serial = 021
expiration_days = 1
' > gnutls-certtool.testclient2.template
certtool --generate-certificate --load-privkey testclient2-key.pem --outfile testclient2.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient2.template --stdout | head -1
certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient2.crt --load-privkey testclient2-key.pem --to-p12 --p12-name "Test Client 2" --null-password --outder --outfile testclient2.p12
SSL_CLIENT_CERTIFICATE=$(
echo "$PWD/rootca-cert.pem"
)

View file

@ -0,0 +1,31 @@
#!/usr/bin/env bash
# This file is Free Software under the MIT License
# without warranty, see README.md and LICENSES/MIT.txt for details.
#
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
# Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
set -e
mkdir -p ~/${FOLDERNAME}
cd ~/${FOLDERNAME}
certtool --generate-privkey --outfile rootca-key.pem
echo '
organization = "'${ORGANAME}'"
country = DE
cn = "Tester"
ca
cert_signing_key
crl_signing_key
serial = 001
expiration_days = 100
' >gnutls-certtool.rootca.template
certtool --generate-self-signed --load-privkey rootca-key.pem --outfile rootca-cert.pem --template gnutls-certtool.rootca.template --stdout | head -1

View file

@ -0,0 +1,41 @@
# This file is Free Software under the MIT License
# without warranty, see README.md and LICENSES/MIT.txt for details.
#
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
# Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
set -e
cd ~/${FOLDERNAME}
certtool --generate-privkey --outfile testserver-key.pem
echo '
organization = "'${ORGANAME}'"
country = DE
cn = "Service Testing"
tls_www_server
signing_key
encryption_key
non_repudiation
dns_name = "*.local"
dns_name = "localhost"
serial = 010
expiration_days = 50
' > gnutls-certtool.testserver.template
certtool --generate-certificate --load-privkey testserver-key.pem --outfile testserver.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testserver.template --stdout | head -1
cat testserver.crt rootca-cert.pem >bundle.crt
SSL_CERTIFICATE=$(
echo "$PWD/bundle.crt"
)
SSL_CERTIFICATE_KEY=$(
echo "$PWD/testserver-key.pem"
)

View file

@ -0,0 +1,32 @@
#!/usr/bin/env bash
#
# Desc: Tries getting csaf 2.0 examples from api.github. Do not run too often!
#
# This file is Free Software under the MIT License
# without warranty, see README.md and LICENSES/MIT.txt for details.
#
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
# Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
set -e
# using an extended regular expression to whitelist only CSAF 2.0 filenames
# with a sane path
CSAFPATHregexp='^ *"path": "(csaf_2.0/examples/csaf/[a-z0-9+-_]+.json)",'
curl --silent --show-error -H 'Accept: application/vnd.github.v3.raw' \
https://api.github.com/repos/oasis-tcs/csaf/contents/csaf_2.0/examples/csaf \
| grep -E "$CSAFPATHregexp" \
| sed -E -e "s;${CSAFPATHregexp};\1;" \
> csaf_examples_pathnames.txt
mkdir csaf_examples
cd csaf_examples
cat ../csaf_examples_pathnames.txt | \
xargs -I {} \
curl --silent --show-error -H 'Accept: application/vnd.github.v3.raw' \
https://api.github.com/repos/oasis-tcs/csaf/contents/{} -O

View file

@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -e
# This script prepares a naked Ubuntu 20.04 LTS amd64
# for the csaf_distribution integration tests
# by installing the required packages.
apt install -y make git nginx fcgiwrap gnutls-bin
# Install Go from binary distribution
curl -O https://storage.googleapis.com/golang/go1.18.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz

View file

@ -0,0 +1,96 @@
#!/usr/bin/env bash
# This file is Free Software under the MIT License
# without warranty, see README.md and LICENSES/MIT.txt for details.
#
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
# Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
# This script sets up the csaf_provider and writes the required nginx configurations.
# It creates the initial folders and uploads some example files to the csaf_provider with the help of `uploadToProvider.sh`
set -e
chgrp -R www-data /var/www
chmod -R g+w /var/www
NGINX_CONFIG_PATH=/etc/nginx/sites-available/default
cp /usr/share/doc/fcgiwrap/examples/nginx.conf /etc/nginx/fcgiwrap.conf
echo '
# Include this file on your nginx.conf to support debian cgi-bin scripts using
# fcgiwrap
location /cgi-bin/ {
# Disable gzip (it makes scripts feel slower since they have to complete
# before getting gzipped)
gzip off;
# Set the root to /usr/lib (inside this location this means that we are
# giving access to the files under /usr/lib/cgi-bin)
root /usr/lib;
# Fastcgi socket
fastcgi_pass unix:/var/run/fcgiwrap.socket;
# Fastcgi parameters, include the standard ones
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.go)(.*)$;
# Adjust non standard parameters (SCRIPT_FILENAME)
fastcgi_param SCRIPT_FILENAME /usr/lib$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param CSAF_CONFIG /usr/lib/csaf/config.toml;
fastcgi_param SSL_CLIENT_VERIFY $ssl_client_verify;
fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn;
fastcgi_param SSL_CLIENT_I_DN $ssl_client_i_dn;
}
' > /etc/nginx/fcgiwrap.conf
sed -i "/^server {/a include fcgiwrap.conf;" $NGINX_CONFIG_PATH
echo "
# For atomic directory switches
disable_symlinks off;
# directory listings
autoindex on;
" > locationConfig.txt
sed -i "/^\s*location \/ {/r locationConfig.txt" $NGINX_CONFIG_PATH # Insert config inside location{}
systemctl reload nginx
# assuming that we are in a checked out version in the docs/scripts directory
# and we want to build the version that is currently checked out
pushd ../..
export PATH=$PATH:/usr/local/go/bin
make build_linux
# Place the binary under the corresponding path.
mkdir -p /usr/lib/cgi-bin/
cp bin-linux-amd64/csaf_provider /usr/lib/cgi-bin/csaf_provider.go
mkdir -p /usr/lib/csaf/
cp docs/test-keys/*.asc /usr/lib/csaf/
# Configuration file
echo '
# upload_signature = true
# key = "/usr/lib/csaf/public.asc"
key = "/usr/lib/csaf/private.asc"
#tlps = ["green", "red"]
canonical_url_prefix = "https://localhost:8443"
#no_passphrase = true
' > /usr/lib/csaf/config.toml
# Create the Folders
curl https://localhost:8443/cgi-bin/csaf_provider.go/create --cert-type p12 --cert ~/devca1/testclient1.p12 --insecure
popd
# Upload files
./uploadToProvider.sh

View file

@ -0,0 +1,30 @@
#!/usr/bin/env bash
#
# Desc: Call ./downloadExamples.sh and then try csaf_uploader.
#
# This file is Free Software under the MIT License
# without warranty, see README.md and LICENSES/MIT.txt for details.
#
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
# Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
set -e
# assumes that the following script only downloads file with filenames
# following https://docs.oasis-open.org/csaf/csaf/v2.0/cs01/csaf-v2.0-cs01.html#51-filename
# which are save to process further
./downloadExamples.sh
TLPs=("white" "green" "amber" "red")
COUNTER=0
for f in $(ls csaf_examples);
do
../../bin-linux-amd64/csaf_uploader -a upload -t ${TLPs[$COUNTER]} \
-u https://localhost:8443/cgi-bin/csaf_provider.go --insecure -P security123 \
--client-cert ~/devca1/testclient1.crt --client-key ~/devca1/testclient1-key.pem \
./csaf_examples/"$f";
let COUNTER++
done;

23
docs/test-keys/Readme.md Normal file
View file

@ -0,0 +1,23 @@
OpenPGP key-pair for testing.
This has been created with:
* gpg (GnuPG) 2.2.19
* (linked with) libgcrypt 1.8.5
### `test1@example.com`
```bash
gpg --full-gen-key
RSA (sign only)
Requested keysize is 4096 bits
key does not expire at all
Real name: test1
Email address: test1@example.com
comment:
```
```bash
gpg --export-secret-key --armor test1 > private.asc
gpg --export --armor test1 > public.asc
```
The passphrase for this test OpenPGP key-pair is: `security123`

View file

@ -0,0 +1,56 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
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
=ssfC
-----END PGP PRIVATE KEY BLOCK-----

28
docs/test-keys/public.asc Normal file
View file

@ -0,0 +1,28 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGI8XxwBEACaVzxyaHp6+D+cO6bNkIQlnX3gmQn5fXeaLF7nwmtYr1c2bAsn
x2SNwrqKIWb80VqPbqO3L+i742IIYF5yS5W/UDaKOFSDqjZsSIleb/gH83Wcnahm
UWxi7ENiHQTSGMG7MWb+uU11TUBhxHsW01oGID06dCz/0PmkkuuggSli3sulM9B7
UKAqZO2uvGEb3/n2rrEfc8Nh5XgrfbV4f1Gqfxsn1kFr8hIdbfoRuJ98jJ771a4M
eOYurY5EyT/IhFPN+f4sGeztcPtENJIww5wJCzmw5KEPtyTBH97QSUjSsmqGhojk
YpL5yAHId4xGGU717pgxLONS1yjW4r5ydjcUN4xRJLJVb6LB3/3YXcaVhVPXaDM7
uC97O7CWzlrppACAXMLvsR/flvCskRWAnZ2PKP899Yq3FYZggKC5uvOQbdL3Ya3R
JjI0hRcVRG3by6flRzyfHkz68bsDX5vCCA1NA56JSquCgWDhaORVCE9gVy1KE8ap
h2rgsHwjtde+1wuRDY0FhqFAraWpyxJRT+xCSFozRZxCtBdhAgLnK07ovIUU3aOv
xRpKyUSjw+zVx437S3U8al/hjttgK1KtCt9F5i4nhyXTM+K6FnIHzQsl1OdRNbqA
cmxW1hDmedVOrJwq5VWqquxlf430HrRU9UQGGn1YcGg3rtyLqut63hZvQQARAQAB
tBl0ZXN0MSA8dGVzdDFAZXhhbXBsZS5jb20+iQJOBBMBCgA4FiEEOVOfoEE9nJwJ
7hauNkDK3qAbSi8FAmI8XxwCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ
NkDK3qAbSi8GCQ//SdBBEq7uGHFb5YrNKB9cfGTWgM5cUJRz2I9OaXnDAJDleDED
c/bB3rubSJTAaCj8O0obC9kvKWGzQ89TG064pAC+sQWfnwTvNR3uQyR6050xA1cW
SsWloBICNpwN/oRk4QtUyvy0HIDV/UCe5AgJsR/Y/FnpFv/VJDVfQeckDYdAljqW
b5IQsu1PGTXNzJi1/boMX4NqK/vkSMujIOqXONz7fRhl+Kht8aum1MYZZD2snHG1
qXoqlUZkDEsbrDPvOds7Pu0DTNpTvBcEFh5apvZW8EtgTBom3/0n4dGxetvXzqVM
sZcToFWEeieYCkXlFOICQT7HSXo06z9pbVncg5IH3ytVaINGxve9ACpwOeIXClur
8U5eRBd3m8KEi/jHYGBQHOO4yUgUDX9YhoabLOvPTD4AsV7FlisqS8GW2YAa+nGK
qyDDIIZtMiG2r1Gd/zdKrjAJZZu1Z1Zt5tphwbxWFRkxFDB8pszo/JXeuyLevBUK
JrsfXjPJLtpTvIrxnUogJvVdF0fmlLJu2FI/71oPrEiyVytH4JpQv44r5jJ6NDH+
/KSqoF/dzuZIHI7CTTYUNZTDWJryjfc3dZ4pzgloWvotVfZUBwyrLwko+uOblb84
kSxNqYxdYAjkVFBpr2xEdjhtQg/44MQpImvoWLyXVUt3hFtSOdWZEURcMOk=
=4s3V
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -3,8 +3,8 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// //
// SPDX-FileCopyrightText: 2021 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de> // SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
// Software-Engineering: 2021 Intevation GmbH <https://intevation.de> // Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
package util package util
@ -17,6 +17,10 @@ import (
"time" "time"
) )
// SemVersion the version in semver.org format, MUST be overwritten during
// the linking stage of the build process
var SemVersion = "0.0.0"
// NWriter is an io.Writer counting the bytes copied through it. // NWriter is an io.Writer counting the bytes copied through it.
type NWriter struct { type NWriter struct {
io.Writer io.Writer