From 81a8e5a184acf81ff6d18c3e8c0fef59d92fbd05 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 18 Jun 2016 02:04:57 -0400 Subject: Write a mutable String class to avoid memory usage issues. Safer logging. As for logging, filter the password from more types of requests. --- proto/io.go | 34 ++++++---- proto/nslcd_h.go | 120 +++++++++++++++++----------------- proto/server/func_handlerequest.go.sh | 32 +++++++-- 3 files changed, 107 insertions(+), 79 deletions(-) diff --git a/proto/io.go b/proto/io.go index 1f46503..ba8c8d0 100644 --- a/proto/io.go +++ b/proto/io.go @@ -40,6 +40,25 @@ type nslcdObjectPtr interface { nslcdRead(fd io.Reader) } +type String []byte +func (s String) String() string { + return string(s) +} +func (s String) GoString() string { + return fmt.Sprintf("nslcd_proto.String(%#v)", string(s)) +} +func (data String) nslcdWrite(fd io.Writer) { + Write(fd, int32(len(data))) + Write(fd, []byte(data)) +} +func (data *String) nslcdRead(fd io.Reader) { + var len int32 + Read(fd, &len) + buf := make([]byte, len) + Read(fd, &buf) + *data = String(buf) +} + // Write an object to a stream. In the event of an error, this // function may panic! Handle it! func Write(fd io.Writer, data interface{}) { @@ -60,10 +79,7 @@ func Write(fd io.Writer, data interface{}) { panic(err) } // composite datatypes - case string: - Write(fd, int32(len(data))) - Write(fd, []byte(data)) - case []string: + case []String: Write(fd, int32(len(data))) for _, item := range data { Write(fd, item) @@ -123,16 +139,10 @@ func Read(fd io.Reader, data interface{}) { panic(err) } // composite datatypes - case *string: - var len int32 - Read(fd, &len) - buf := make([]byte, len) - Read(fd, &buf) - *data = string(buf) - case *[]string: + case *[]String: var num int32 Read(fd, &num) - *data = make([]string, num) + *data = make([]String, num) for i := 0; i < int(num); i++ { Read(fd, &((*data)[i])) } diff --git a/proto/nslcd_h.go b/proto/nslcd_h.go index cb210cd..ab82f26 100644 --- a/proto/nslcd_h.go +++ b/proto/nslcd_h.go @@ -83,7 +83,7 @@ type Request_Config_Get struct { } /* the result value is: */ type Config struct { - Value string /* interpretation depending on request */ + Value String /* interpretation depending on request */ } const NSLCD_ACTION_CONFIG_GET int32 = 0x00010001 @@ -96,44 +96,44 @@ const ( /* Email alias (/etc/aliases) NSS requests. The result values for a single entry are: */ type Alias struct { - Name string - Recipients []string + Name String + Recipients []String } -const NSLCD_ACTION_ALIAS_BYNAME int32 = 0x00020001; type Request_Alias_ByName struct { Name string } +const NSLCD_ACTION_ALIAS_BYNAME int32 = 0x00020001; type Request_Alias_ByName struct { Name String } const NSLCD_ACTION_ALIAS_ALL int32 = 0x00020008; type Request_Alias_All struct {} /* Ethernet address/name mapping NSS requests. The result values for a single entry are: */ type Ether struct { - Name string + Name String Address [6]byte } -const NSLCD_ACTION_ETHER_BYNAME int32 = 0x00030001; type Request_Ether_ByName struct { Name string } +const NSLCD_ACTION_ETHER_BYNAME int32 = 0x00030001; type Request_Ether_ByName struct { Name String } const NSLCD_ACTION_ETHER_BYETHER int32 = 0x00030002; type Request_Ether_ByEther struct { Ether [6]byte } const NSLCD_ACTION_ETHER_ALL int32 = 0x00030008; type Request_Ether_All struct {} /* Group and group membership related NSS requests. The result values for a single entry are: */ type Group struct { - Name string - PwHash string + Name String + PwHash String ID int32 - Members []string + Members []String } /* (note that the BYMEMER call returns an emtpy members list) */ -const NSLCD_ACTION_GROUP_BYNAME int32 = 0x00040001; type Request_Group_ByName struct { Name string } +const NSLCD_ACTION_GROUP_BYNAME int32 = 0x00040001; type Request_Group_ByName struct { Name String } const NSLCD_ACTION_GROUP_BYGID int32 = 0x00040002; type Request_Group_ByGid struct { Gid int32 } -const NSLCD_ACTION_GROUP_BYMEMBER int32 = 0x00040006; type Request_Group_ByMember struct { Member string } +const NSLCD_ACTION_GROUP_BYMEMBER int32 = 0x00040006; type Request_Group_ByMember struct { Member String } const NSLCD_ACTION_GROUP_ALL int32 = 0x00040008; type Request_Group_All struct {} /* Hostname (/etc/hosts) lookup NSS requests. The result values for an entry are: */ type Host struct { - Name string - Aliases []string + Name String + Aliases []String Addresses []net.IP } -const NSLCD_ACTION_HOST_BYNAME int32 = 0x00050001; type Request_Host_ByName struct { Name string } +const NSLCD_ACTION_HOST_BYNAME int32 = 0x00050001; type Request_Host_ByName struct { Name String } const NSLCD_ACTION_HOST_BYADDR int32 = 0x00050002; type Request_Host_ByAddr struct { Addr net.IP } const NSLCD_ACTION_HOST_ALL int32 = 0x00050008; type Request_Host_All struct {} @@ -153,12 +153,12 @@ const NSLCD_ACTION_HOST_ALL int32 = 0x00050008; type Request_Host_All INT32 NSLCD_NETGROUP_TYPE_END */ type Netgroup_Netgroup struct { - Name string + Name String } type Netgroup_Triple struct { - Host string - User string - Domain string + Host String + User String + Domain String } type Netgroup_PartList []interface{} func (data Netgroup_PartList) nslcdWrite(fd io.Writer) { @@ -201,10 +201,10 @@ func (data *Netgroup_PartList) nslcdRead(fd io.Reader) { var _ nslcdObject = Netgroup_PartList{} var _ nslcdObjectPtr = &Netgroup_PartList{} type Netgroup struct { - Name string + Name String Parts Netgroup_PartList } -const NSLCD_ACTION_NETGROUP_BYNAME int32 = 0x00060001; type Request_Netgroup_ByName struct { Name string } +const NSLCD_ACTION_NETGROUP_BYNAME int32 = 0x00060001; type Request_Netgroup_ByName struct { Name String } const NSLCD_ACTION_NETGROUP_ALL int32 = 0x00060008; type Request_Netgroup_All struct {} const ( NSLCD_NETGROUP_TYPE_NETGROUP int32 = 1 @@ -215,45 +215,45 @@ const ( /* Network name (/etc/networks) NSS requests. Result values for a single entry are: */ type Network struct { - Name string - Aliases []string + Name String + Aliases []String Addresses []net.IP } -const NSLCD_ACTION_NETWORK_BYNAME int32 = 0x00070001; type Request_Network_ByName struct { Name string } +const NSLCD_ACTION_NETWORK_BYNAME int32 = 0x00070001; type Request_Network_ByName struct { Name String } const NSLCD_ACTION_NETWORK_BYADDR int32 = 0x00070002; type Request_Network_ByAddr struct { Addr net.IP } const NSLCD_ACTION_NETWORK_ALL int32 = 0x00070008; type Request_Network_All struct {} /* User account (/etc/passwd) NSS requests. Result values are: */ type Passwd struct { - Name string - PwHash string + Name String + PwHash String UID int32 GID int32 - GECOS string - HomeDir string - Shell string + GECOS String + HomeDir String + Shell String } -const NSLCD_ACTION_PASSWD_BYNAME int32 = 0x00080001; type Request_Passwd_ByName struct { Name string } +const NSLCD_ACTION_PASSWD_BYNAME int32 = 0x00080001; type Request_Passwd_ByName struct { Name String } const NSLCD_ACTION_PASSWD_BYUID int32 = 0x00080002; type Request_Passwd_ByUID struct { UID int32 } const NSLCD_ACTION_PASSWD_ALL int32 = 0x00080008; type Request_Passwd_All struct {} /* Protocol information requests. Result values are: */ type Protocol struct { - Name string - Aliases []string + Name String + Aliases []String Number int32 } -const NSLCD_ACTION_PROTOCOL_BYNAME int32 = 0x00090001; type Request_Protocol_ByName struct { Name string } +const NSLCD_ACTION_PROTOCOL_BYNAME int32 = 0x00090001; type Request_Protocol_ByName struct { Name String } const NSLCD_ACTION_PROTOCOL_BYNUMBER int32 = 0x00090002; type Request_Protocol_ByNumber struct { Number int32 } const NSLCD_ACTION_PROTOCOL_ALL int32 = 0x00090008; type Request_Protocol_All struct {} /* RPC information requests. Result values are: */ type RPC struct { - Name string - Aliases []string + Name String + Aliases []String Number int32 } -const NSLCD_ACTION_RPC_BYNAME int32 = 0x000a0001; type Request_RPC_ByName struct { Name string } +const NSLCD_ACTION_RPC_BYNAME int32 = 0x000a0001; type Request_RPC_ByName struct { Name String } const NSLCD_ACTION_RPC_BYNUMBER int32 = 0x000a0002; type Request_RPC_ByNumber struct { Number int32 } const NSLCD_ACTION_RPC_ALL int32 = 0x000a0008; type Request_RPC_All struct {} @@ -261,12 +261,12 @@ const NSLCD_ACTION_RPC_ALL int32 = 0x000a0008; type Request_RPC_All requests contain an extra protocol string in the request which, if not blank, will filter the services by this protocol. Result values are: */ type Service struct { - Name string - Aliases []string + Name String + Aliases []String PortNumber int32 - Protocol string + Protocol String } -const NSLCD_ACTION_SERVICE_BYNAME int32 = 0x000b0001; type Request_Service_ByName struct { Name string } +const NSLCD_ACTION_SERVICE_BYNAME int32 = 0x000b0001; type Request_Service_ByName struct { Name String } const NSLCD_ACTION_SERVICE_BYNUMBER int32 = 0x000b0002; type Request_Service_ByNumber struct { Number int32 } const NSLCD_ACTION_SERVICE_ALL int32 = 0x000b0008; type Request_Service_All struct {} @@ -275,8 +275,8 @@ const NSLCD_ACTION_SERVICE_ALL int32 = 0x000b0008; type Request_Service_Al type Shadow struct { // It is my understanding that an empty value for an INT32 // field is expressed with a negative number. -- lukeshu - Name string - PwHash string + Name String + PwHash String LastChangeDate int32 MinDays int32 MaxDays int32 @@ -285,17 +285,17 @@ type Shadow struct { ExpireDate int32 Flag int32 } -const NSLCD_ACTION_SHADOW_BYNAME int32 = 0x000c0001; type Request_Shadow_ByName struct { Name string } +const NSLCD_ACTION_SHADOW_BYNAME int32 = 0x000c0001; type Request_Shadow_ByName struct { Name String } const NSLCD_ACTION_SHADOW_ALL int32 = 0x000c0008; type Request_Shadow_All struct {} /* PAM-related requests. The request parameters for all these requests begin with: */ type PAM_Base struct { - UserName string - ServiceName string - RUser string - RHost string - TTY string + UserName String + ServiceName String + RUser String + RHost String + TTY String } /* If the user is not known in LDAP no result may be returned (immediately return NSLCD_RESULT_END instead of a PAM error code). */ @@ -303,14 +303,14 @@ type PAM_Base struct { /* PAM authentication check request. The extra request values are: */ type Request_PAM_Authentication struct { PAM_Base - Password string + Password String } /* and the result value consists of: */ type PAM_Authentication struct { AuthenticationResult int32 - UserName string + UserName String AuthorizationResult int32 - AuthorizationError string + AuthorizationError String } /* If the username is empty in this request an attempt is made to authenticate as the administrator (set using rootpwmoddn). @@ -321,7 +321,7 @@ const NSLCD_ACTION_PAM_AUTHENTICATION int32 = 0x000d0001 /* PAM authorisation check request. The result value consists of: */ type PAM_Authorization struct { Result int32 - Error string + Error String } /* The authentication check may have already returned some authorisation information. The authorisation error message, if supplied, will be used @@ -331,7 +331,7 @@ const NSLCD_ACTION_PAM_AUTHORIZATION int32 = 0x000d0002; type Request_PAM_Author /* PAM session open request. The result value consists of: */ type PAM_SessionOpen struct { - SessionID string + SessionID String } /* This session id may be used to close this session with. */ const NSLCD_ACTION_PAM_SESSIONOPEN int32 = 0x000d0003; type Request_PAM_SessionOpen PAM_Base @@ -340,7 +340,7 @@ const NSLCD_ACTION_PAM_SESSIONOPEN int32 = 0x000d0003; type Request_PAM_Sessio extra request value: */ type Request_PAM_SessionClose struct { PAM_Base - SessionID string + SessionID String } /* and this calls only returns an empty response value. */ type PAM_SessionClose struct {} @@ -351,13 +351,13 @@ const NSLCD_ACTION_PAM_SESSIONCLOSE int32 = 0x000d0004 type Request_PAM_PwMod struct { PAM_Base AsRoot int32 /* 0=oldpasswd is user passwd, 1=oldpasswd is root passwd */ - OldPassword string - NewPassword string + OldPassword String + NewPassword String } /* and returns the result values: */ type PAM_PwMod struct { Result int32 - Error string + Error String } const NSLCD_ACTION_PAM_PWMOD int32 = 0x000d0005 @@ -374,12 +374,12 @@ const NSLCD_ACTION_PAM_PWMOD int32 = 0x000d0005 by NSLCD_USERMOD_END: INT32 NSLCD_USERMOD_* STRING response - (if the response is blank, the change went OK, otherwise the string + (if the response is blank, the change went OK, otherwise the String contains an error message) */ type UserMod_Item struct { Key int32 - Value string + Value String } type UserMod_ItemList []UserMod_Item func (data UserMod_ItemList) nslcdWrite(fd io.Writer) { @@ -404,9 +404,9 @@ func (data *UserMod_ItemList) nslcdRead(fd io.Reader) { var _ nslcdObject = UserMod_ItemList{} var _ nslcdObjectPtr = &UserMod_ItemList{} type Request_UserMod struct { - UserName string + UserName String AsRoot int32 - Password string + Password String Items UserMod_ItemList } type UserMod struct { diff --git a/proto/server/func_handlerequest.go.sh b/proto/server/func_handlerequest.go.sh index d6160e9..cb2856a 100755 --- a/proto/server/func_handlerequest.go.sh +++ b/proto/server/func_handlerequest.go.sh @@ -32,6 +32,8 @@ import ( s "syscall" ) +var sensitive = p.String("") + // Handle a request to nslcd func HandleRequest(backend Backend, in io.Reader, out io.Writer, cred s.Ucred) (err error) { err = nil @@ -67,13 +69,29 @@ while read -r request; do var req p.Request_${request} p.Read(in, &req) $( - if [[ $request == PAM_Authentication ]]; then - echo '_req := req' - echo '_req.Password = ""' - echo 'fmt.Fprintf(os.Stderr, "Request: %#v\n", _req)' - else - echo 'fmt.Fprintf(os.Stderr, "Request: %#v\n", req)' - fi + case "$request" in + PAM_Authentication) + echo '_req := req' + echo '_req.Password = sensitive' + echo 'fmt.Fprintf(os.Stderr, "Request: %#v\n", _req)' + ;; + PAM_PwMod) + echo '_req := req' + echo 'if len(_req.OldPassword) > 0 {' + echo ' _req.OldPassword = sensitive' + echo '}' + echo '_req.NewPassword = sensitive' + echo 'fmt.Fprintf(os.Stderr, "Request: %#v\n", _req)' + ;; + PAM_UserMod) + echo '_req := req' + echo '_req.Password = sensitive' + echo 'fmt.Fprintf(os.Stderr, "Request: %#v\n", _req)' + ;; + *) + echo 'fmt.Fprintf(os.Stderr, "Request: %#v\n", req)' + ;; + esac ) _ch := backend.${request}(cred, req) go func() { -- cgit v1.2.3