Commit 2f4b8a7b authored by David Venhoek's avatar David Venhoek Committed by Sietse Ringers
Browse files

chore: replace / in file paths with filepath.Join()

Closes #44
parent ce7b345a
......@@ -3,6 +3,7 @@ package irma
import (
"encoding/xml"
"fmt"
"path/filepath"
"github.com/go-errors/errors"
"github.com/privacybydesign/irmago/internal/fs"
......@@ -183,7 +184,7 @@ func (ct *CredentialType) SchemeManagerIdentifier() SchemeManagerIdentifier {
}
func (ct *CredentialType) Logo(conf *Configuration) string {
path := fmt.Sprintf("%s/%s/%s/Issues/%s/logo.png", conf.Path, ct.SchemeManagerID, ct.IssuerID, ct.ID)
path := filepath.Join(conf.Path, ct.SchemeManagerID, ct.IssuerID, "Issues", ct.ID, "logo.png")
exists, err := fs.PathExists(path)
if err != nil || !exists {
return ""
......
......@@ -83,8 +83,8 @@ func Copy(src, dest string) error {
// Save the filecontents at the specified path atomically:
// - first save the content in a temp file with a random filename in the same dir
// - then rename the temp file to the specified filepath, overwriting the old file
func SaveFile(filepath string, content []byte) (err error) {
dir := path.Dir(filepath)
func SaveFile(fpath string, content []byte) (err error) {
dir := path.Dir(fpath)
// Read random data for filename and convert to hex
randBytes := make([]byte, 16)
......@@ -95,13 +95,13 @@ func SaveFile(filepath string, content []byte) (err error) {
tempfilename := hex.EncodeToString(randBytes)
// Create temp file
err = ioutil.WriteFile(dir+"/"+tempfilename, content, 0600)
err = ioutil.WriteFile(filepath.Join(dir, tempfilename), content, 0600)
if err != nil {
return
}
// Rename, overwriting old file
return os.Rename(dir+"/"+tempfilename, filepath)
return os.Rename(filepath.Join(dir, tempfilename), fpath)
}
func CopyDirectory(src, dest string) error {
......
......@@ -4,6 +4,7 @@ import (
"encoding/json"
"reflect"
"testing"
"path/filepath"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/fs"
......@@ -376,14 +377,14 @@ func TestDownloadSchemeManager(t *testing.T) {
require.Contains(t, client.Configuration.Issuers, irma.NewIssuerIdentifier("irma-demo.RU"))
require.Contains(t, client.Configuration.CredentialTypes, irma.NewCredentialTypeIdentifier("irma-demo.RU.studentCard"))
basepath := test.FindTestdataFolder(t) + "/storage/test/irma_configuration/irma-demo"
exists, err := fs.PathExists(basepath + "/description.xml")
basepath := filepath.Join(test.FindTestdataFolder(t), "storage", "test", "irma_configuration", "irma-demo")
exists, err := fs.PathExists(filepath.Join(basepath, "description.xml"))
require.NoError(t, err)
require.True(t, exists)
exists, err = fs.PathExists(basepath + "/RU/description.xml")
exists, err = fs.PathExists(filepath.Join(basepath, "RU", "description.xml"))
require.NoError(t, err)
require.True(t, exists)
exists, err = fs.PathExists(basepath + "/RU/Issues/studentCard/description.xml")
exists, err = fs.PathExists(filepath.Join(basepath, "RU", "Issues", "studentCard", "description.xml"))
require.NoError(t, err)
require.True(t, exists)
}
......@@ -143,8 +143,8 @@ func defaultCounter(path string) (counter int) {
func init() {
issuerCmd.AddCommand(issuerKeygenCmd)
issuerKeygenCmd.Flags().StringP("privatekey", "s", "", `File to write private key to (default "PrivateKeys/$counter.xml")`)
issuerKeygenCmd.Flags().StringP("publickey", "p", "", `File to write public key to (default "PublicKeys/$counter.xml")`)
issuerKeygenCmd.Flags().StringP("privatekey", "s", "", `File to write private key to (default "PrivateKeys`+string(os.PathSeparator)+`$counter.xml")`)
issuerKeygenCmd.Flags().StringP("publickey", "p", "", `File to write public key to (default "PublicKeys`+string(os.PathSeparator)+`$counter.xml")`)
issuerKeygenCmd.Flags().StringP("expirydate", "e", "", "Expiry date for the key pair. Specify in RFC3339 (\"2006-01-02T15:04:05+07:00\") format. Alternatively, use the --valid-for option.")
issuerKeygenCmd.Flags().StringP("valid-for", "v", "1y", "The duration key pair should be valid starting from now. Specify as a number followed by either y, M, d, h, or m (for years, months, days, hours, and minutes, respectively). For example, use \"2y\" for a expiry date 2 years from now. This flag is ignored when expirydate flag is used.")
issuerKeygenCmd.Flags().IntP("keylength", "l", 2048, "Keylength")
......
......@@ -78,7 +78,7 @@ func init() {
func signManager(privatekey *ecdsa.PrivateKey, confpath string, skipverification bool) error {
// Write timestamp
bts := []byte(strconv.FormatInt(time.Now().Unix(), 10) + "\n")
if err := ioutil.WriteFile(confpath+"/timestamp", bts, 0644); err != nil {
if err := ioutil.WriteFile(filepath.Join(confpath, "timestamp"), bts, 0644); err != nil {
return errors.WrapPrefix(err, "Failed to write timestamp", 0)
}
......@@ -93,7 +93,7 @@ func signManager(privatekey *ecdsa.PrivateKey, confpath string, skipverification
// Write index
bts = []byte(index.String())
if err := ioutil.WriteFile(confpath+"/index", bts, 0644); err != nil {
if err := ioutil.WriteFile(filepath.Join(confpath, "index"), bts, 0644); err != nil {
return errors.WrapPrefix(err, "Failed to write index", 0)
}
......@@ -107,7 +107,7 @@ func signManager(privatekey *ecdsa.PrivateKey, confpath string, skipverification
if err != nil {
return errors.WrapPrefix(err, "Failed to serialize signature:", 0)
}
if err = ioutil.WriteFile(confpath+"/index.sig", sigbytes, 0644); err != nil {
if err = ioutil.WriteFile(filepath.Join(confpath, "index.sig"), sigbytes, 0644); err != nil {
return errors.WrapPrefix(err, "Failed to write index.sig", 0)
}
......@@ -117,7 +117,7 @@ func signManager(privatekey *ecdsa.PrivateKey, confpath string, skipverification
return errors.WrapPrefix(err, "Failed to serialize public key", 0)
}
pemEncodedPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: bts})
if err := ioutil.WriteFile(confpath+"/pk.pem", pemEncodedPub, 0644); err != nil {
if err := ioutil.WriteFile(filepath.Join(confpath, "pk.pem"), pemEncodedPub, 0644); err != nil {
return errors.WrapPrefix(err, "Failed to write public key", 0)
}
......@@ -148,8 +148,8 @@ func calculateFileHash(path string, info os.FileInfo, err error, confpath string
// Skip stuff we don't want
if info.IsDir() || // Can only sign files
strings.HasSuffix(path, "index") || // Skip the index file itself
strings.Contains(path, "/.git/") || // No need to traverse .git dirs, can take quite long
strings.Contains(path, "/PrivateKeys/") { // Don't sign private keys
strings.Contains(filepath.ToSlash(path), "/.git/") || // No need to traverse .git dirs, can take quite long
strings.Contains(filepath.ToSlash(path), "/PrivateKeys/") { // Don't sign private keys
return nil
}
// Skip everything except the stuff we do want
......@@ -171,6 +171,6 @@ func calculateFileHash(path string, info os.FileInfo, err error, confpath string
relativePath = filepath.Join(filepath.Base(confpath), relativePath)
hash := sha256.Sum256(bts)
index[relativePath] = hash[:]
index[filepath.ToSlash(relativePath)] = hash[:]
return nil
}
......@@ -3,6 +3,7 @@ package irmaclient
import (
"strconv"
"time"
"path/filepath"
"github.com/bwesterb/go-atum"
"github.com/getsentry/raven-go"
......@@ -140,7 +141,7 @@ func New(
handler: handler,
}
cm.Configuration, err = irma.NewConfigurationFromAssets(storagePath+"/irma_configuration", irmaConfigurationPath)
cm.Configuration, err = irma.NewConfigurationFromAssets(filepath.Join(storagePath,"irma_configuration"), irmaConfigurationPath)
if err != nil {
return nil, err
}
......
......@@ -5,6 +5,7 @@ import (
"errors"
"os"
"path/filepath"
"testing"
"github.com/privacybydesign/gabi"
......@@ -28,10 +29,11 @@ func TestMain(m *testing.M) {
func parseStorage(t *testing.T) *Client {
test.SetupTestStorage(t)
require.NoError(t, fs.CopyDirectory("../testdata/teststorage", "../testdata/storage/test"))
require.NoError(t, fs.CopyDirectory(filepath.Join("..", "testdata", "teststorage"),
filepath.Join("..", "testdata", "storage", "test")))
client, err := New(
"../testdata/storage/test",
"../testdata/irma_configuration",
filepath.Join("..", "testdata", "storage", "test"),
filepath.Join("..", "testdata", "irma_configuration"),
"",
&TestClientHandler{t: t},
)
......@@ -212,7 +214,7 @@ func TestWrongSchemeManager(t *testing.T) {
irmademo := irma.NewSchemeManagerIdentifier("irma-demo")
require.Contains(t, client.Configuration.SchemeManagers, irmademo)
require.NoError(t, os.Remove("../testdata/storage/test/irma_configuration/irma-demo/index"))
require.NoError(t, os.Remove(filepath.Join("..", "testdata", "storage", "test", "irma_configuration", "irma-demo", "index")))
err := client.Configuration.ParseFolder()
_, ok := err.(*irma.SchemeManagerError)
......
......@@ -4,6 +4,7 @@ import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"github.com/privacybydesign/gabi"
"github.com/privacybydesign/irmago"
......@@ -31,7 +32,7 @@ const (
)
func (s *storage) path(p string) string {
return s.storagePath + "/" + p
return filepath.Join(s.storagePath, p)
}
// EnsureStorageExists initializes the credential storage folder,
......@@ -72,7 +73,7 @@ func (s *storage) signatureFilename(attrs *irma.AttributeList) string {
// will be written to the same file, one overwriting the other - but that doesn't
// matter, because either one of the signatures is valid over both attribute lists,
// so keeping one of them suffices.
return signaturesDir + "/" + attrs.Hash()
return filepath.Join(signaturesDir, attrs.Hash())
}
func (s *storage) DeleteSignature(attrs *irma.AttributeList) error {
......
......@@ -309,28 +309,6 @@ func (conf *Configuration) ParseSchemeManagerFolder(dir string, manager *SchemeM
return
}
// relativePath returns, given a outer path that contains the inner path,
// the relative path between outer an inner, which is such that
// outer/returnvalue refers to inner.
func relativePath(outer string, inner string) (string, error) {
// Take Abs() of both paths to ensure that we don't fail on e.g.
// outer = "./foo" and inner = "foo/bar"
outerAbs, err := filepath.Abs(outer)
if err != nil {
return "", err
}
innerAbs, err := filepath.Abs(inner)
if err != nil {
return "", err
}
if !strings.HasPrefix(innerAbs, outerAbs) {
return "", errors.New("inner path is not contained in outer path")
}
// These are used as key in the scheme index, so always use forward slashes
return strings.Replace(innerAbs[len(outerAbs)+1:], string(filepath.Separator), "/", -1), nil
}
// PrivateKey returns the specified private key, or nil if not present in the Configuration.
func (conf *Configuration) PrivateKey(id IssuerIdentifier) (*gabi.PrivateKey, error) {
if sk := conf.privateKeys[id]; sk != nil {
......@@ -524,7 +502,7 @@ func (conf *Configuration) parseKeysFolder(issuerid IssuerIdentifier) error {
if err != nil {
return err
}
relativepath, err := relativePath(conf.Path, file)
relativepath, err := filepath.Rel(conf.Path, file)
if err != nil {
return err
}
......@@ -637,7 +615,7 @@ func (conf *Configuration) pathToDescription(manager *SchemeManager, path string
return false, nil
}
relativepath, err := relativePath(conf.Path, path)
relativepath, err := filepath.Rel(conf.Path, path)
if err != nil {
return false, err
}
......@@ -1035,12 +1013,12 @@ func (conf *Configuration) parseIndex(name string, manager *SchemeManager) (Sche
func (conf *Configuration) checkUnsignedFiles(name string, index SchemeManagerIndex) error {
return filepath.Walk(filepath.Join(conf.Path, name), func(path string, info os.FileInfo, err error) error {
relpath, err := relativePath(conf.Path, path)
relpath, err := filepath.Rel(conf.Path, path)
if err != nil {
return err
}
for _, ex := range sigExceptions {
if ex.MatchString(relpath) {
if ex.MatchString(filepath.ToSlash(relpath)) {
return nil
}
}
......@@ -1143,19 +1121,19 @@ func (conf *Configuration) VerifySignature(id SchemeManagerIdentifier) (err erro
}()
dir := filepath.Join(conf.Path, id.String())
if err := fs.AssertPathExists(dir+"/index", dir+"/index.sig", dir+"/pk.pem"); err != nil {
if err := fs.AssertPathExists(filepath.Join(dir, "index"), filepath.Join(dir, "index.sig"), filepath.Join(dir, "pk.pem")); err != nil {
return errors.New("Missing scheme manager index file, signature, or public key")
}
// Read and hash index file
indexbts, err := ioutil.ReadFile(dir + "/index")
indexbts, err := ioutil.ReadFile(filepath.Join(dir, "index"))
if err != nil {
return err
}
indexhash := sha256.Sum256(indexbts)
// Read and parse scheme manager public key
pkbts, err := ioutil.ReadFile(dir + "/pk.pem")
pkbts, err := ioutil.ReadFile(filepath.Join(dir, "pk.pem"))
if err != nil {
return err
}
......@@ -1165,7 +1143,7 @@ func (conf *Configuration) VerifySignature(id SchemeManagerIdentifier) (err erro
}
// Read and parse signature
sig, err := ioutil.ReadFile(dir + "/index.sig")
sig, err := ioutil.ReadFile(filepath.Join(dir, "index.sig"))
if err != nil {
return err
}
......@@ -1270,12 +1248,12 @@ func (conf *Configuration) UpdateSchemeManager(id SchemeManagerIdentifier, downl
continue
}
var matches []string
matches = issPattern.FindStringSubmatch(filename)
matches = issPattern.FindStringSubmatch(filepath.ToSlash(filename))
if len(matches) == 3 {
issid := NewIssuerIdentifier(fmt.Sprintf("%s.%s", matches[1], matches[2]))
downloaded.Issuers[issid] = struct{}{}
}
matches = credPattern.FindStringSubmatch(filename)
matches = credPattern.FindStringSubmatch(filepath.ToSlash(filename))
if len(matches) == 4 {
credid := NewCredentialTypeIdentifier(fmt.Sprintf("%s.%s.%s", matches[1], matches[2], matches[3]))
downloaded.CredentialTypes[credid] = struct{}{}
......@@ -1355,7 +1333,7 @@ func (conf *Configuration) validateIssuer(manager *SchemeManager, issuer *Issuer
if manager.ID != issuer.SchemeManagerID {
return errors.Errorf("Issuer %s has wrong SchemeManager %s", issuerid.String(), issuer.SchemeManagerID)
}
if err = fs.AssertPathExists(dir + "/logo.png"); err != nil {
if err = fs.AssertPathExists(filepath.Join(dir, "logo.png")); err != nil {
conf.Warnings = append(conf.Warnings, fmt.Sprintf("Issuer %s has no logo.png", issuerid.String()))
}
return nil
......@@ -1376,7 +1354,7 @@ func (conf *Configuration) validateCredentialType(manager *SchemeManager, issuer
if cred.SchemeManagerID != manager.ID {
return errors.Errorf("Credential type %s has wrong SchemeManager %s", credid.String(), cred.SchemeManagerID)
}
if err := fs.AssertPathExists(dir + "/logo.png"); err != nil {
if err := fs.AssertPathExists(filepath.Join(dir, "logo.png")); err != nil {
conf.Warnings = append(conf.Warnings, fmt.Sprintf("Credential type %s has no logo.png", credid.String()))
}
return conf.validateAttributes(cred)
......
......@@ -46,7 +46,7 @@ func TestConfigurationAutocopy(t *testing.T) {
func TestParseInvalidIrmaConfiguration(t *testing.T) {
// The description.xml of the scheme manager under this folder has been edited
// to invalidate the scheme manager signature
conf, err := NewConfigurationReadOnly("testdata/irma_configuration_invalid")
conf, err := NewConfigurationReadOnly(filepath.Join("testdata","irma_configuration_invalid"))
require.NoError(t, err)
// Parsing it should return a SchemeManagerError
......@@ -81,7 +81,8 @@ func TestInvalidIrmaConfigurationRestoreFromRemote(t *testing.T) {
test.CreateTestStorage(t)
defer test.ClearTestStorage(t)
conf, err := NewConfigurationFromAssets("testdata/storage/test/irma_configuration", "testdata/irma_configuration_invalid")
conf, err := NewConfigurationFromAssets(filepath.Join("testdata", "storage", "test", "irma_configuration"),
filepath.Join("testdata","irma_configuration_invalid"))
require.NoError(t, err)
err = conf.ParseOrRestoreFolder()
......@@ -95,7 +96,8 @@ func TestInvalidIrmaConfigurationRestoreFromAssets(t *testing.T) {
test.CreateTestStorage(t)
defer test.ClearTestStorage(t)
conf, err := NewConfigurationFromAssets("testdata/storage/test/irma_configuration", "testdata/irma_configuration_invalid")
conf, err := NewConfigurationFromAssets(filepath.Join("testdata", "storage", "test", "irma_configuration"),
filepath.Join("testdata", "irma_configuration_invalid"))
require.NoError(t, err)
// Fails: no remote and the version in the assets is broken
......@@ -104,7 +106,7 @@ func TestInvalidIrmaConfigurationRestoreFromAssets(t *testing.T) {
require.NotEmpty(t, conf.DisabledSchemeManagers)
// Try again from correct assets
conf.assets = "testdata/irma_configuration"
conf.assets = filepath.Join("testdata", "irma_configuration")
err = conf.ParseOrRestoreFolder()
require.NoError(t, err)
require.Empty(t, conf.DisabledSchemeManagers)
......@@ -165,7 +167,7 @@ func TestMetadataAttribute(t *testing.T) {
}
func TestMetadataCompatibility(t *testing.T) {
conf, err := NewConfigurationReadOnly("testdata/irma_configuration")
conf, err := NewConfigurationReadOnly(filepath.Join("testdata", "irma_configuration"))
require.NoError(t, err)
require.NoError(t, conf.ParseFolder())
......
......@@ -68,7 +68,7 @@ func (conf *Configuration) downloadPrivateKeys(scheme *SchemeManager) error {
}
for _, index := range indices {
remote := fmt.Sprintf("%s/PrivateKeys/%d.xml", issid.Name(), index)
local := fmt.Sprintf("%s/%s/%s", conf.Path, scheme.ID, remote)
local := filepath.Join(conf.Path, scheme.ID, remote)
if err = transport.GetFile(remote, filepath.FromSlash(local)); err != nil {
Logger.Warnf("Downloading private key %d of issuer %s failed", index, issid.String())
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment