From 80a7509e4e880c39a0d3a9db5dee19edcad32210 Mon Sep 17 00:00:00 2001 From: Etienne Stalmans Date: Tue, 2 May 2017 20:43:05 +0100 Subject: [PATCH] fixes to RPC and process status code in responses differently. some older servers return statuscode 3 instead of 0 --- forms/rulerforms.go | 4 ++- mapi/datastructs.go | 3 ++ mapi/mapi.go | 60 +++++++++++++++++++--------------------- rpc-http/packets.go | 3 ++ rpc-http/rpctransport.go | 18 +++++++----- utils/utils.go | 2 +- 6 files changed, 49 insertions(+), 41 deletions(-) diff --git a/forms/rulerforms.go b/forms/rulerforms.go index 7700957..22ec793 100644 --- a/forms/rulerforms.go +++ b/forms/rulerforms.go @@ -123,7 +123,9 @@ func CreateFormMessage(suffix string) ([]byte, error) { } //the small icon for the message propertyTagx[4] = mapi.TaggedPropertyValue{PropertyTag: mapi.PidTag6823, PropertyValue: append(utils.COUNT(len(data)), data...)} - _, err = mapi.SetMessageProperties(folderid, msg.MessageID, propertyTagx) + if _, err = mapi.SetMessageProperties(folderid, msg.MessageID, propertyTagx); err != nil { + return nil, err + } propertyTagx = make([]mapi.TaggedPropertyValue, 4) data, err = utils.ReadFile("templates/img1.bin") diff --git a/mapi/datastructs.go b/mapi/datastructs.go index 0f3a3d5..23e2f2a 100644 --- a/mapi/datastructs.go +++ b/mapi/datastructs.go @@ -1162,6 +1162,9 @@ func (execResponse *ExecuteResponse) Unmarshal(resp []byte) error { execResponse.ErrorCode, pos = utils.ReadUint32(pos, resp) //error code if MAPIHTTP else this is also the buffer size execResponse.Flags, pos = utils.ReadUint32(pos, resp) execResponse.RopBufferSize, pos = utils.ReadUint32(pos, resp) + if len(resp) < pos+int(execResponse.RopBufferSize) { + return nil + } buf, pos = utils.ReadBytes(pos, int(execResponse.RopBufferSize), resp) execResponse.RopBuffer = buf execResponse.AuxilliaryBufSize, _ = utils.ReadUint32(pos, resp) diff --git a/mapi/mapi.go b/mapi/mapi.go index 3e13d8a..da5162a 100644 --- a/mapi/mapi.go +++ b/mapi/mapi.go @@ -74,7 +74,7 @@ func Init(config *utils.Session, lid, URL, ABKURL string, transport int) { AuthSession.Transport = transport AuthSession.ClientSet = false AuthSession.ReqCounter = 1 - AuthSession.LogonID = 0x09 + AuthSession.LogonID = 0x08f AuthSession.Authenticated = false //default to Encrypt + Sign for NTLM @@ -417,7 +417,7 @@ func AuthenticateFetchMailbox(essdn []byte) (*RopLogonResponse, error) { return nil, &TransportError{err} } - if execResponse.StatusCode == 0 || execResponse.StatusCode == 3 { + if execResponse.StatusCode != 255 { AuthSession.Authenticated = true logonResponse := RopLogonResponse{} @@ -467,7 +467,7 @@ func ReleaseObject(inputHandle byte) (*RopReleaseResponse, error) { return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { ropReleaseResponse := RopReleaseResponse{} if _, e := ropReleaseResponse.Unmarshal(execResponse.RopBuffer[10:]); e != nil { return nil, e @@ -736,7 +736,7 @@ func SetMessageStatus(folderid, messageid []byte) (*RopSetMessageStatusResponse, return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 setStatusResp := RopSetMessageStatusResponse{} @@ -809,7 +809,7 @@ func CreateMessageRequest(folderID []byte, properties []TaggedPropertyValue, ass return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error @@ -901,7 +901,7 @@ func CreateMessageAttachment(folderid, messageid []byte, properties []TaggedProp return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error @@ -941,14 +941,6 @@ func CreateMessageAttachment(folderid, messageid []byte, properties []TaggedProp saveMessageResponse := RopSaveChangesMessageResponse{} e = saveMessageResponse.Unmarshal(execResponse.RopBuffer[bufPtr:]) - /* - utils.Debug.Println("Get Message: ", getMessageResp) - utils.Debug.Println("Get AttachTbl: ", getAttachmentTblResp) - utils.Debug.Println("Create Attach: ", createAttachmentResp) - utils.Debug.Println("Set Props: ", propertiesResponse) - utils.Debug.Println("Save Attach: ", saveAttachmentResp) - utils.Debug.Println("Save Message: ", saveMessageResponse) - */ return &createAttachmentResp, e } @@ -998,7 +990,7 @@ func WriteAttachmentProperty(folderid, messageid []byte, attachmentid uint32, pr return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error @@ -1133,7 +1125,7 @@ func WriteAttachmentProperty(folderid, messageid []byte, attachmentid uint32, pr return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error @@ -1163,6 +1155,7 @@ func WriteAttachmentProperty(folderid, messageid []byte, attachmentid uint32, pr return &RopSaveChangesAttachmentResponse{}, ErrUnknown } +//SetMessageProperties is used to update the properties of a message func SetMessageProperties(folderid, messageid []byte, propertyTags []TaggedPropertyValue) (*RopSaveChangesMessageResponse, error) { execRequest := ExecuteRequest{} @@ -1207,7 +1200,7 @@ func SetMessageProperties(folderid, messageid []byte, propertyTags []TaggedPrope return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error @@ -1264,7 +1257,7 @@ func SetPropertyFast(folderid []byte, messageid []byte, property TaggedPropertyV return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { //we probably need to get the handles here to pass them down into the ServerObjectHandleTable serverHandles := execResponse.RopBuffer[len(execResponse.RopBuffer)-8:] @@ -1350,7 +1343,7 @@ func SaveMessageFast(inputHandle, responseHandle byte, serverHandles []byte) (*R } //fmt.Println("Complete") - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 saveMessageResponse := RopSaveChangesMessageResponse{} @@ -1397,7 +1390,7 @@ func DeleteMessages(folderid []byte, messageIDCount int, messageIDs []byte) (*Ro return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 openFolder := RopOpenFolderResponse{} p, err := openFolder.Unmarshal(execResponse.RopBuffer[bufPtr:]) @@ -1448,7 +1441,7 @@ func EmptyFolder(folderid []byte) (*RopEmptyFolderResponse, error) { return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 openFolder := RopOpenFolderResponse{} p, err := openFolder.Unmarshal(execResponse.RopBuffer[bufPtr:]) @@ -1489,7 +1482,7 @@ func DeleteFolder(folderid []byte) (*RopDeleteFolderResponse, error) { return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 deleteFolder := RopDeleteFolderResponse{} if _, e := deleteFolder.Unmarshal(execResponse.RopBuffer[bufPtr:]); e != nil { @@ -1604,7 +1597,7 @@ func GetMessage(folderid, messageid []byte, columns []PropertyTag) (*RopGetPrope return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int @@ -1674,7 +1667,7 @@ func GetMessageFast(folderid, messageid []byte, columns []PropertyTag) (*RopFast return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int @@ -1741,7 +1734,7 @@ func FastTransferFetchStep(handles []byte) ([]byte, error) { return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { if execResponse.RopBuffer[2] == 0x05 { //compression //decompress } @@ -1818,11 +1811,13 @@ func GetContentsTableRequest(folderid []byte, tableFlags byte) (*RopGetContentsT return nil, nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error - + if bufPtr > len(execResponse.RopBuffer) { + return nil, nil, fmt.Errorf("Empty table") + } openFolder := RopOpenFolderResponse{} if p, e = openFolder.Unmarshal(execResponse.RopBuffer[bufPtr:]); e != nil { return nil, nil, e @@ -1833,7 +1828,8 @@ func GetContentsTableRequest(folderid []byte, tableFlags byte) (*RopGetContentsT if p, e = ropContents.Unmarshal(execResponse.RopBuffer[bufPtr:]); e != nil { return nil, nil, e } - bufPtr += p + 8 + bufPtr += p + return &ropContents, execResponse.RopBuffer[bufPtr:], nil } @@ -1869,7 +1865,7 @@ func GetFolderHierarchy(folderid []byte) (*RopGetHierarchyTableResponse, []byte, return nil, nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error @@ -1923,7 +1919,7 @@ func GetSubFolders(folderid []byte) (*RopQueryRowsResponse, error) { return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error @@ -1987,7 +1983,7 @@ func CreateFolder(folderName string, hidden bool) (*RopCreateFolderResponse, err return nil, ErrTransport //&TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 createFolder := RopCreateFolderResponse{} if _, e := createFolder.Unmarshal(execResponse.RopBuffer[bufPtr:]); e != nil { @@ -2068,7 +2064,7 @@ func GetTableContents(folderid []byte, assoc bool, columns []PropertyTag) (*RopQ return nil, &TransportError{err} } - if execResponse.StatusCode == 0 { + if execResponse.StatusCode != 255 { bufPtr := 10 var p int var e error diff --git a/rpc-http/packets.go b/rpc-http/packets.go index 192e3f8..400066c 100644 --- a/rpc-http/packets.go +++ b/rpc-http/packets.go @@ -476,6 +476,9 @@ func (response *RPCResponse) Unmarshal(raw []byte) (int, error) { } else { if len(raw) > int(response.Header.FragLen-response.Header.AuthLen-24) { response.PDU, pos = utils.ReadBytes(pos, int(response.Header.FragLen-response.Header.AuthLen-24), raw) + if len(raw) < pos+int(response.Header.AuthLen) { + return pos, nil + } response.SecTrailer, pos = utils.ReadBytes(pos, int(response.Header.AuthLen), raw) } else { diff --git a/rpc-http/rpctransport.go b/rpc-http/rpctransport.go index 3fbee0c..e1ab332 100644 --- a/rpc-http/rpctransport.go +++ b/rpc-http/rpctransport.go @@ -39,6 +39,7 @@ func setupHTTP(rpctype string, URL string, ntlmAuth bool, full bool) (net.Conn, } if err != nil { + utils.Error.Println("RPC Setup Err", err) return nil, err } var request string @@ -87,7 +88,7 @@ func setupHTTP(rpctype string, URL string, ntlmAuth bool, full bool) (net.Conn, if full == false { return nil, fmt.Errorf("Failed with initial setup for %s : %s\n", rpctype, err) } - utils.Trace.Printf("Failed with initial setup for %s trying again...\n", rpctype) + //utils.Trace.Printf("Failed with initial setup for %s trying again...\n", rpctype) return setupHTTP(rpctype, URL, ntlmAuth, false) } @@ -101,7 +102,7 @@ func setupHTTP(rpctype string, URL string, ntlmAuth bool, full bool) (net.Conn, } } } - utils.Trace.Println(string(data)) + //utils.Trace.Println(string(data)) ntlmChallengeString := strings.Replace(ntlmChallengeHeader, "NTLM ", "", 1) challengeBytes, err := utils.DecBase64(ntlmChallengeString) @@ -131,7 +132,7 @@ func setupHTTP(rpctype string, URL string, ntlmAuth bool, full bool) (net.Conn, authenticate, err = session.GenerateAuthenticateMessage() if err != nil { - //panic(err) + utils.Error.Println("Authentication Err") return nil, err } } @@ -183,7 +184,7 @@ func RPCOpen(URL string, readySignal chan bool, errOccurred chan error) (err err readySignal <- false errOccurred <- err return err - case <-time.After(time.Second * 2): // call timed out + case <-time.After(time.Second * 20): // call timed out readySignal <- true } @@ -194,7 +195,7 @@ func RPCOpen(URL string, readySignal chan bool, errOccurred chan error) (err err _, err = rpcInConn.Write(data[:n]) } if err != nil && err != io.EOF { - utils.Error.Println(err) + utils.Error.Println("RPCIN_ERROR: ", err) break } } @@ -493,7 +494,9 @@ func RPCWrite(data []byte) { //RPCOutWrite function writes to the RPC_OUT_DATA channel, //this should only happen once, for ConnA1 func RPCOutWrite(data []byte) { - rpcOutConn.Write(data) + if rpcOutConn != nil { + rpcOutConn.Write(data) + } } //RPCRead function takes a call ID and searches for the response in @@ -518,7 +521,8 @@ func RPCRead(callID int) (RPCResponse, error) { select { case resp := <-c: return resp, nil - case <-time.After(time.Second * 10): // call timed out + case <-time.After(time.Second * 15): // call timed out + utils.Error.Println("RPC Timeout") //check if there is a 401 or other error message for k, v := range httpResponses { st := string(v) diff --git a/utils/utils.go b/utils/utils.go index c2ee5cd..62619ca 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -214,7 +214,7 @@ func ReadByte(pos int, buff []byte) (byte, int) { func ReadUnicodeString(pos int, buff []byte) ([]byte, int) { //stupid hack as using bufio and ReadString(byte) would terminate too early //would terminate on 0x00 instead of 0x0000 - index := bytes.Index(buff[pos:], []byte{0x00, 0x00, 0x00}) + 1 + index := bytes.Index(buff[pos:], []byte{0x00, 0x00, 0x00}) str := buff[pos : pos+index] return []byte(str), pos + index + 2 }