]> git.lizzy.rs Git - go-anidb.git/blob - udp/auth.go
c78e8001eba9a633233aff072c86770136888121
[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) (err error) {
17         if a.session != "" {
18                 if err = (<-a.Uptime()).Error(); err == nil {
19                         return nil
20                 }
21         }
22
23         a.session = ""
24         if udpKey != "" {
25                 if err = a.encrypt(user, udpKey); err != nil {
26                         return err
27                 }
28         }
29         r := <-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 r.Code() {
40         case 200, 201:
41                 f := strings.Fields(r.Text())
42                 a.session = f[0]
43         }
44         return r.Error()
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) (err error) {
57         if reply := <-a.SendRecv("ENCRYPT", ParamMap{"user": user, "type": 1}); reply.Error() != nil {
58                 return reply.Error()
59         } else {
60                 switch reply.Code() {
61                 case 209:
62                         salt := []byte(strings.Fields(reply.Text())[0])
63
64                         // Yes, AniDB works in ECB mode
65                         a.ecb = newECBState(udpKey, salt)
66                 }
67                 return reply.Error()
68         }
69 }