...
1 package dbus
2
3 import (
4 "bufio"
5 "bytes"
6 "crypto/rand"
7 "crypto/sha1"
8 "encoding/hex"
9 "os"
10 )
11
12
13
14
15 func AuthCookieSha1(user, home string) Auth {
16 return authCookieSha1{user, home}
17 }
18
19 type authCookieSha1 struct {
20 user, home string
21 }
22
23 func (a authCookieSha1) FirstData() ([]byte, []byte, AuthStatus) {
24 b := make([]byte, 2*len(a.user))
25 hex.Encode(b, []byte(a.user))
26 return []byte("DBUS_COOKIE_SHA1"), b, AuthContinue
27 }
28
29 func (a authCookieSha1) HandleData(data []byte) ([]byte, AuthStatus) {
30 challenge := make([]byte, len(data)/2)
31 _, err := hex.Decode(challenge, data)
32 if err != nil {
33 return nil, AuthError
34 }
35 b := bytes.Split(challenge, []byte{' '})
36 if len(b) != 3 {
37 return nil, AuthError
38 }
39 context := b[0]
40 id := b[1]
41 svchallenge := b[2]
42 cookie := a.getCookie(context, id)
43 if cookie == nil {
44 return nil, AuthError
45 }
46 clchallenge := a.generateChallenge()
47 if clchallenge == nil {
48 return nil, AuthError
49 }
50 hash := sha1.New()
51 hash.Write(bytes.Join([][]byte{svchallenge, clchallenge, cookie}, []byte{':'}))
52 hexhash := make([]byte, 2*hash.Size())
53 hex.Encode(hexhash, hash.Sum(nil))
54 data = append(clchallenge, ' ')
55 data = append(data, hexhash...)
56 resp := make([]byte, 2*len(data))
57 hex.Encode(resp, data)
58 return resp, AuthOk
59 }
60
61
62
63
64
65 func (a authCookieSha1) getCookie(context, id []byte) []byte {
66 file, err := os.Open(a.home + "/.dbus-keyrings/" + string(context))
67 if err != nil {
68 return nil
69 }
70 defer file.Close()
71 rd := bufio.NewReader(file)
72 for {
73 line, err := rd.ReadBytes('\n')
74 if err != nil {
75 return nil
76 }
77 line = line[:len(line)-1]
78 b := bytes.Split(line, []byte{' '})
79 if len(b) != 3 {
80 return nil
81 }
82 if bytes.Equal(b[0], id) {
83 return b[2]
84 }
85 }
86 }
87
88
89
90 func (a authCookieSha1) generateChallenge() []byte {
91 b := make([]byte, 16)
92 n, err := rand.Read(b)
93 if err != nil {
94 return nil
95 }
96 if n != 16 {
97 return nil
98 }
99 enc := make([]byte, 32)
100 hex.Encode(enc, b)
101 return enc
102 }
103
View as plain text