Skip to content

Commit

Permalink
Mask passwords in the log entries
Browse files Browse the repository at this point in the history
Currently Identity password is being logged in clear, with this change
password will be masked with ****

https://jira.hyperledger.org/browse/FAB-2717

Change-Id: Ideb469018fd0b9cd2356d48bf33f373c580a54d7
Signed-off-by: Anil Ambati <[email protected]>
  • Loading branch information
Anil Ambati committed Mar 10, 2017
1 parent 403080d commit 074ebab
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func (s *Server) RegisterBootstrapUser(user, pass, affiliation string) error {
}
registry := &s.Config.Registry
registry.Identities = append(registry.Identities, id)
log.Debugf("Registered bootstrap identity: %+v", id)
log.Debugf("Registered bootstrap identity: %+v", &id)
return nil
}

Expand Down
7 changes: 6 additions & 1 deletion lib/serverconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/cloudflare/cfssl/csr"
"github.com/hyperledger/fabric-ca/lib/ldap"
"github.com/hyperledger/fabric-ca/lib/tls"
"github.com/hyperledger/fabric-ca/util"
"github.com/hyperledger/fabric/bccsp/factory"
)

Expand Down Expand Up @@ -78,9 +79,13 @@ type ServerConfigRegistry struct {
// ServerConfigIdentity is identity information in the server's config
type ServerConfigIdentity struct {
Name string
Pass string
Pass string `secret:"password"`
Type string
Affiliation string
MaxEnrollments int
Attrs map[string]string
}

func (sc *ServerConfigIdentity) String() string {
return util.StructToString(sc)
}
33 changes: 33 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import (
"os"
"path"
"path/filepath"
"reflect"
"regexp"
"strings"
"time"
"unicode/utf8"
Expand Down Expand Up @@ -72,6 +74,12 @@ var RevocationReasonCodes = map[string]int{
"aacompromise": ocsp.AACompromise,
}

// SecretTag to tag a field as secret as in password, token
const SecretTag = "secret"

// PassExpr is the regular expression to check if a tag has 'password'
var PassExpr = regexp.MustCompile(`[,]?password[,]?`)

//ECDSASignature forms the structure for R and S value for ECDSA
type ECDSASignature struct {
R, S *big.Int
Expand Down Expand Up @@ -556,3 +564,28 @@ func GetSerialAsHex(serial *big.Int) string {

return hex
}

// StructToString converts a struct to a string. If a field
// has a 'secret' tag, it is masked in the returned string
func StructToString(si interface{}) string {
rval := reflect.ValueOf(si).Elem()
tipe := rval.Type()
var buffer bytes.Buffer
buffer.WriteString("{ ")
for i := 0; i < rval.NumField(); i++ {
tf := tipe.Field(i)
if !rval.FieldByName(tf.Name).CanSet() {
continue // skip unexported fields
}
var fStr string
tagv := tf.Tag.Get(SecretTag)
if PassExpr.MatchString(tagv) {
fStr = fmt.Sprintf("%s:**** ", tf.Name)
} else {
fStr = fmt.Sprintf("%s:%v ", tf.Name, rval.Field(i).Interface())
}
buffer.WriteString(fStr)
}
buffer.WriteString(" }")
return buffer.String()
}
26 changes: 26 additions & 0 deletions util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"

"github.com/hyperledger/fabric/bccsp/factory"
Expand Down Expand Up @@ -373,7 +374,32 @@ func TestGetUser(t *testing.T) {
if pass != "bar" {
t.Error("Failed to retrieve correct password")
}
}

func TestStructToString(t *testing.T) {
var obj struct {
Name string
Addr string `json:"address"`
Pass string `secret:"password"`
Pass1 string `secret:"password,token"`
Pass2 string `secret:"token,password"`
pass3 string `secret:"token,password,basic"`
}
obj.Name = "foo"
addr := "101, penn ave"
obj.Addr = addr
obj.Pass, obj.Pass1, obj.Pass2 = "bar", "bar", "bar"
obj.pass3 = "bar"
str := StructToString(&obj)
if strings.Index(str, "bar") > 0 {
t.Errorf("Password is not masked by the StructToString function: %s", str)
}
if strings.Index(str, "foo") < 0 {
t.Errorf("Name is masked by the StructToString function: %s", str)
}
if strings.Index(str, addr) < 0 {
t.Errorf("Addr is masked by the StructToString function: %s", str)
}
}

func makeFileAbs(t *testing.T, file, dir, expect string) {
Expand Down

0 comments on commit 074ebab

Please sign in to comment.