Takahiro Suzuki | d7bf820 | 2020-12-17 20:21:59 +0900 | [diff] [blame^] | 1 | package sarama |
| 2 | |
| 3 | import ( |
| 4 | "encoding/binary" |
| 5 | "encoding/hex" |
| 6 | "gopkg.in/jcmturner/gokrb5.v7/credentials" |
| 7 | "gopkg.in/jcmturner/gokrb5.v7/gssapi" |
| 8 | "gopkg.in/jcmturner/gokrb5.v7/iana/keyusage" |
| 9 | "gopkg.in/jcmturner/gokrb5.v7/messages" |
| 10 | "gopkg.in/jcmturner/gokrb5.v7/types" |
| 11 | ) |
| 12 | |
| 13 | type KafkaGSSAPIHandler struct { |
| 14 | client *MockKerberosClient |
| 15 | badResponse bool |
| 16 | badKeyChecksum bool |
| 17 | } |
| 18 | |
| 19 | func (h *KafkaGSSAPIHandler) MockKafkaGSSAPI(buffer []byte) []byte { |
| 20 | // Default payload used for verify |
| 21 | err := h.client.Login() // Mock client construct keys when login |
| 22 | if err != nil { |
| 23 | return nil |
| 24 | } |
| 25 | if h.badResponse { // Returns trash |
| 26 | return []byte{0x00, 0x00, 0x00, 0x01, 0xAD} |
| 27 | } |
| 28 | |
| 29 | var pack = gssapi.WrapToken{ |
| 30 | Flags: KRB5_USER_AUTH, |
| 31 | EC: 12, |
| 32 | RRC: 0, |
| 33 | SndSeqNum: 3398292281, |
| 34 | Payload: []byte{0x11, 0x00}, // 1100 |
| 35 | } |
| 36 | // Compute checksum |
| 37 | if h.badKeyChecksum { |
| 38 | pack.CheckSum = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} |
| 39 | } else { |
| 40 | err = pack.SetCheckSum(h.client.ASRep.DecryptedEncPart.Key, keyusage.GSSAPI_ACCEPTOR_SEAL) |
| 41 | if err != nil { |
| 42 | return nil |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | packBytes, err := pack.Marshal() |
| 47 | if err != nil { |
| 48 | return nil |
| 49 | } |
| 50 | lenBytes := len(packBytes) |
| 51 | response := make([]byte, lenBytes+4) |
| 52 | copy(response[4:], packBytes) |
| 53 | binary.BigEndian.PutUint32(response, uint32(lenBytes)) |
| 54 | return response |
| 55 | } |
| 56 | |
| 57 | type MockKerberosClient struct { |
| 58 | asReqBytes string |
| 59 | asRepBytes string |
| 60 | ASRep messages.ASRep |
| 61 | credentials *credentials.Credentials |
| 62 | mockError error |
| 63 | errorStage string |
| 64 | } |
| 65 | |
| 66 | func (c *MockKerberosClient) Login() error { |
| 67 | if c.errorStage == "login" && c.mockError != nil { |
| 68 | return c.mockError |
| 69 | } |
| 70 | c.asRepBytes = "6b8202e9308202e5a003020105a10302010ba22b30293027a103020113a220041e301c301aa003020112a1131b114" + |
| 71 | "558414d504c452e434f4d636c69656e74a30d1b0b4558414d504c452e434f4da4133011a003020101a10a30081b06636c69656e7" + |
| 72 | "4a5820156618201523082014ea003020105a10d1b0b4558414d504c452e434f4da220301ea003020102a11730151b066b7262746" + |
| 73 | "7741b0b4558414d504c452e434f4da382011430820110a003020112a103020101a28201020481ffdb9891175d106818e61008c51" + |
| 74 | "d0b3462bca92f3bf9d4cfa82de4c4d7aff9994ec87c573e3a3d54dcb2bb79618c76f2bf4a3d006f90d5bdbd049bc18f48be39203" + |
| 75 | "549ca02acaf63f292b12404f9b74c34b83687119d8f56552ccc0c50ebee2a53bb114c1b4619bb1d5d31f0f49b4d40a08a9b4c046" + |
| 76 | "2e1398d0b648be1c0e50c552ad16e1d8d8e74263dd0bf0ec591e4797dfd40a9a1be4ae830d03a306e053fd7586fef84ffc5e4a83" + |
| 77 | "7c3122bf3e6a40fe87e84019f6283634461b955712b44a5f7386c278bff94ec2c2dc0403247e29c2450e853471ceababf9b8911f" + |
| 78 | "997f2e3010b046d2c49eb438afb0f4c210821e80d4ffa4c9521eb895dcd68610b3feaa682012c30820128a003020112a282011f0" + |
| 79 | "482011bce73cbce3f1dd17661c412005f0f2257c756fe8e98ff97e6ec24b7bab66e5fd3a3827aeeae4757af0c6e892948122d8b2" + |
| 80 | "03c8df48df0ef5d142d0e416d688f11daa0fcd63d96bdd431d02b8e951c664eeff286a2be62383d274a04016d5f0e141da58cb86" + |
| 81 | "331de64063062f4f885e8e9ce5b181ca2fdc67897c5995e0ae1ae0c171a64493ff7bd91bc6d89cd4fce1e2b3ea0a10e34b0d5eda" + |
| 82 | "aa38ee727b50c5632ed1d2f2b457908e616178d0d80b72af209fb8ac9dbaa1768fa45931392b36b6d8c12400f8ded2efaa0654d0" + |
| 83 | "da1db966e8b5aab4706c800f95d559664646041fdb38b411c62fc0fbe0d25083a28562b0e1c8df16e62e9d5626b0addee489835f" + |
| 84 | "eedb0f26c05baa596b69b17f47920aa64b29dc77cfcc97ba47885" |
| 85 | apRepBytes, err := hex.DecodeString(c.asRepBytes) |
| 86 | if err != nil { |
| 87 | return err |
| 88 | } |
| 89 | err = c.ASRep.Unmarshal(apRepBytes) |
| 90 | if err != nil { |
| 91 | return err |
| 92 | } |
| 93 | c.credentials = credentials.New("client", "EXAMPLE.COM").WithPassword("qwerty") |
| 94 | _, err = c.ASRep.DecryptEncPart(c.credentials) |
| 95 | if err != nil { |
| 96 | return err |
| 97 | } |
| 98 | return nil |
| 99 | } |
| 100 | |
| 101 | func (c *MockKerberosClient) GetServiceTicket(spn string) (messages.Ticket, types.EncryptionKey, error) { |
| 102 | if c.errorStage == "service_ticket" && c.mockError != nil { |
| 103 | return messages.Ticket{}, types.EncryptionKey{}, c.mockError |
| 104 | } |
| 105 | return c.ASRep.Ticket, c.ASRep.DecryptedEncPart.Key, nil |
| 106 | } |
| 107 | |
| 108 | func (c *MockKerberosClient) Domain() string { |
| 109 | return "EXAMPLE.COM" |
| 110 | } |
| 111 | func (c *MockKerberosClient) CName() types.PrincipalName { |
| 112 | var p = types.PrincipalName{ |
| 113 | NameType: KRB5_USER_AUTH, |
| 114 | NameString: []string{ |
| 115 | "kafka", |
| 116 | "kafka", |
| 117 | }, |
| 118 | } |
| 119 | return p |
| 120 | } |
| 121 | func (c *MockKerberosClient) Destroy() { |
| 122 | // Do nothing. |
| 123 | } |