go-tg-screenshot-bot

Форк
0
102 строки · 2.4 Кб
1
package dbus
2

3
import (
4
	"bufio"
5
	"bytes"
6
	"crypto/rand"
7
	"crypto/sha1"
8
	"encoding/hex"
9
	"os"
10
)
11

12
// AuthCookieSha1 returns an Auth that authenticates as the given user with the
13
// DBUS_COOKIE_SHA1 mechanism. The home parameter should specify the home
14
// directory of the user.
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
// getCookie searches for the cookie identified by id in context and returns
62
// the cookie content or nil. (Since HandleData can't return a specific error,
63
// but only whether an error occurred, this function also doesn't bother to
64
// return an error.)
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
// generateChallenge returns a random, hex-encoded challenge, or nil on error
89
// (see above).
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.