This commit is contained in:
emersion 2017-08-22 10:16:20 +02:00
parent 653a8a0dc0
commit d964a951a0
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
4 changed files with 50 additions and 50 deletions

View File

@ -11,9 +11,9 @@ import (
func main() { func main() {
c := &protonmail.Client{ c := &protonmail.Client{
RootURL: "https://dev.protonmail.com/api", RootURL: "https://dev.protonmail.com/api",
AppVersion: "Web_3.11.1", AppVersion: "Web_3.11.1",
ClientID: "Web", ClientID: "Web",
ClientSecret: "4957cc9a2e0a2a49d02475c9d013478d", ClientSecret: "4957cc9a2e0a2a49d02475c9d013478d",
} }

View File

@ -8,28 +8,28 @@ import (
) )
type authInfoReq struct { type authInfoReq struct {
ClientID string ClientID string
ClientSecret string ClientSecret string
Username string Username string
} }
type AuthInfo struct { type AuthInfo struct {
TwoFactor int TwoFactor int
version int version int
modulus string modulus string
serverEphemeral string serverEphemeral string
salt string salt string
srpSession string srpSession string
} }
type AuthInfoResp struct { type AuthInfoResp struct {
resp resp
AuthInfo AuthInfo
Version int Version int
Modulus string Modulus string
ServerEphemeral string ServerEphemeral string
Salt string Salt string
SRPSession string SRPSession string
} }
func (resp *AuthInfoResp) authInfo() *AuthInfo { func (resp *AuthInfoResp) authInfo() *AuthInfo {
@ -44,9 +44,9 @@ func (resp *AuthInfoResp) authInfo() *AuthInfo {
func (c *Client) AuthInfo(username string) (*AuthInfo, error) { func (c *Client) AuthInfo(username string) (*AuthInfo, error) {
reqData := &authInfoReq{ reqData := &authInfoReq{
ClientID: c.ClientID, ClientID: c.ClientID,
ClientSecret: c.ClientSecret, ClientSecret: c.ClientSecret,
Username: username, Username: username,
} }
req, err := c.newJSONRequest(http.MethodPost, "/auth/info", reqData) req, err := c.newJSONRequest(http.MethodPost, "/auth/info", reqData)
@ -63,42 +63,42 @@ func (c *Client) AuthInfo(username string) (*AuthInfo, error) {
} }
type authReq struct { type authReq struct {
ClientID string ClientID string
ClientSecret string ClientSecret string
Username string Username string
SRPSession string SRPSession string
ClientEphemeral string ClientEphemeral string
ClientProof string ClientProof string
TwoFactorCode string TwoFactorCode string
} }
type PasswordMode int type PasswordMode int
const ( const (
PasswordSingle PasswordMode = 1 PasswordSingle PasswordMode = 1
PasswordTwo = 2 PasswordTwo = 2
) )
type Auth struct { type Auth struct {
AccessToken string AccessToken string
ExpiresIn int ExpiresIn int
TokenType string TokenType string
Scope string Scope string
UID string `json:"Uid"` UID string `json:"Uid"`
RefreshToken string RefreshToken string
EventID string EventID string
PasswordMode PasswordMode PasswordMode PasswordMode
privateKey string privateKey string
keySalt string keySalt string
} }
type authResp struct { type authResp struct {
resp resp
Auth Auth
ServerProof string ServerProof string
PrivateKey string PrivateKey string
KeySalt string KeySalt string
} }
func (resp *authResp) auth() *Auth { func (resp *authResp) auth() *Auth {
@ -116,21 +116,19 @@ func (c *Client) Auth(username, password, twoFactorCode string, info *AuthInfo)
} }
} }
log.Printf("%#v\n", info)
proofs, err := srp([]byte(password), info) proofs, err := srp([]byte(password), info)
if err != nil { if err != nil {
return nil, err return nil, err
} }
reqData := &authReq{ reqData := &authReq{
ClientID: c.ClientID, ClientID: c.ClientID,
ClientSecret: c.ClientSecret, ClientSecret: c.ClientSecret,
Username: username, Username: username,
SRPSession: info.srpSession, SRPSession: info.srpSession,
ClientEphemeral: base64.StdEncoding.EncodeToString(proofs.clientEphemeral), ClientEphemeral: base64.StdEncoding.EncodeToString(proofs.clientEphemeral),
ClientProof: base64.StdEncoding.EncodeToString(proofs.clientProof), ClientProof: base64.StdEncoding.EncodeToString(proofs.clientProof),
TwoFactorCode: twoFactorCode, TwoFactorCode: twoFactorCode,
} }
req, err := c.newJSONRequest(http.MethodPost, "/auth", reqData) req, err := c.newJSONRequest(http.MethodPost, "/auth", reqData)

View File

@ -9,7 +9,7 @@ import (
"strconv" "strconv"
) )
const Version = 2 const Version = 3
const headerAPIVersion = "X-Pm-Apiversion" const headerAPIVersion = "X-Pm-Apiversion"
@ -39,15 +39,17 @@ func (err apiError) Error() string {
// Client is a ProtonMail API client. // Client is a ProtonMail API client.
type Client struct { type Client struct {
HTTPClient *http.Client RootURL string
RootURL string
AppVersion string AppVersion string
ClientID string
ClientID string
ClientSecret string ClientSecret string
HTTPClient *http.Client
} }
func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) { func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) {
req, err := http.NewRequest(method, c.RootURL + path, body) req, err := http.NewRequest(method, c.RootURL+path, body)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -41,7 +41,7 @@ func reverse(b []byte) {
func itoa(i *big.Int, l int) []byte { func itoa(i *big.Int, l int) []byte {
b := i.Bytes() b := i.Bytes()
reverse(b) reverse(b)
padding := make([]byte, l/8 - len(b)) padding := make([]byte, l/8-len(b))
b = append(b, padding...) b = append(b, padding...)
return b return b
} }
@ -52,8 +52,8 @@ func atoi(b []byte) *big.Int {
} }
type proofs struct { type proofs struct {
clientEphemeral []byte clientEphemeral []byte
clientProof []byte clientProof []byte
expectedServerProof []byte expectedServerProof []byte
} }
@ -129,8 +129,8 @@ func generateProofs(l int, hash func([]byte) []byte, modulusBytes, hashedBytes,
serverProof = hash(serverProof) serverProof = hash(serverProof)
return &proofs{ return &proofs{
clientEphemeral: itoa(clientEphemeral, l), clientEphemeral: itoa(clientEphemeral, l),
clientProof: clientProof, clientProof: clientProof,
expectedServerProof: serverProof, expectedServerProof: serverProof,
}, nil }, nil
} }