]> git.lizzy.rs Git - go-anidb.git/blob - udp/auth.go
udp, anidb: Lock shared data, return APIReply for authentication
[go-anidb.git] / udp / auth.go
1 package udpapi
2
3 import (
4         "strings"
5 )
6
7 // Authenticates the supplied user with the supplied password. Blocks until we have a reply.
8 // Needed before almost any other API command can be used.
9 //
10 // If the udpKey is not "", then the connection will be encrypted, but the protocol's
11 // encryption uses the VERY weak ECB mode.
12 //
13 // http://wiki.anidb.net/w/UDP_API_Definition#AUTH:_Authing_to_the_AnimeDB
14 //
15 // http://wiki.anidb.net/w/UDP_API_Definition#ENCRYPT:_Start_Encrypted_Session
16 func (a *AniDBUDP) Auth(user, password, udpKey string) (reply APIReply) {
17         if a.session != "" {
18                 if reply = <-a.Uptime(); reply.Error() == nil {
19                         return reply
20                 }
21         }
22
23         a.session = ""
24         if udpKey != "" {
25                 if reply = a.encrypt(user, udpKey); reply.Error() != nil {
26                         return reply
27                 }
28         }
29         reply = <-a.SendRecv("AUTH", ParamMap{
30                 "user":      user,
31                 "pass":      password,
32                 "protover":  3,
33                 "client":    "goanidbudp",
34                 "clientver": 1,
35                 "nat":       1,
36                 "comp":      1,
37                 "enc":       "UTF-8",
38         })
39         switch reply.Code() {
40         case 200, 201:
41                 f := strings.Fields(reply.Text())
42                 a.session = f[0]
43         }
44         return reply
45 }
46
47 // Ends the API session. Blocks until we have confirmation.
48 //
49 // http://wiki.anidb.net/w/UDP_API_Definition#LOGOUT:_Logout
50 func (a *AniDBUDP) Logout() (err error) {
51         r := <-a.SendRecv("LOGOUT", ParamMap{})
52         a.session = ""
53         return r.Error()
54 }
55
56 func (a *AniDBUDP) encrypt(user, udpKey string) (reply APIReply) {
57         a.ecb = nil
58         if reply = <-a.SendRecv("ENCRYPT", ParamMap{"user": user, "type": 1}); reply.Error() == nil {
59                 switch reply.Code() {
60                 case 209:
61                         salt := []byte(strings.Fields(reply.Text())[0])
62
63                         // Yes, AniDB works in ECB mode
64                         a.ecb = newECBState(udpKey, salt)
65                 }
66         }
67         return reply
68 }