Authenticate authenticates a pair of username and password with the proxy server.
(ctx context.Context, rw io.ReadWriter, auth AuthMethod)
| 257 | // Authenticate authenticates a pair of username and password with the |
| 258 | // proxy server. |
| 259 | func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth AuthMethod) error { |
| 260 | switch auth { |
| 261 | case AuthMethodNotRequired: |
| 262 | return nil |
| 263 | case AuthMethodUsernamePassword: |
| 264 | if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) == 0 || len(up.Password) > 255 { |
| 265 | return errors.New("invalid username/password") |
| 266 | } |
| 267 | b := []byte{authUsernamePasswordVersion} |
| 268 | b = append(b, byte(len(up.Username))) |
| 269 | b = append(b, up.Username...) |
| 270 | b = append(b, byte(len(up.Password))) |
| 271 | b = append(b, up.Password...) |
| 272 | // TODO(mikio): handle IO deadlines and cancellation if |
| 273 | // necessary |
| 274 | if _, err := rw.Write(b); err != nil { |
| 275 | return err |
| 276 | } |
| 277 | if _, err := io.ReadFull(rw, b[:2]); err != nil { |
| 278 | return err |
| 279 | } |
| 280 | if b[0] != authUsernamePasswordVersion { |
| 281 | return errors.New("invalid username/password version") |
| 282 | } |
| 283 | if b[1] != authStatusSucceeded { |
| 284 | return errors.New("username/password authentication failed") |
| 285 | } |
| 286 | return nil |
| 287 | } |
| 288 | return errors.New("unsupported authentication method " + strconv.Itoa(int(auth))) |
| 289 | } |