private async Task AuthenticateAsync(Stream s) { await _negotiationRequest.WriteToAsync(s); await s.FlushAsync(); SocksProxyNegotiationReply negotiationReply = await SocksProxyNegotiationReply.ReadRequestAsync(s); if (!negotiationReply.IsVersionSupported) { throw new SocksProxyException("Socks version 5 is not supported by the proxy server."); } switch (negotiationReply.Method) { case SocksProxyAuthenticationMethod.UsernamePassword: if (_authRequest == null) { throw new SocksProxyAuthenticationFailedException("Socks proxy server requires authentication."); } await _authRequest.WriteToAsync(s); await s.FlushAsync(); SocksProxyAuthenticationReply authenticationReply = await SocksProxyAuthenticationReply.ReadRequestAsync(s); if (!authenticationReply.IsVersionSupported) { throw new SocksProxyAuthenticationFailedException("Socks proxy server does not support username/password method version 1."); } if (authenticationReply.Status != SocksProxyAuthenticationStatus.Success) { throw new SocksProxyAuthenticationFailedException("Socks proxy server authentication failed: invalid username or password."); } break; case SocksProxyAuthenticationMethod.NoAuthenticationRequired: break; case SocksProxyAuthenticationMethod.NoAcceptableMethods: if (_authRequest == null) { throw new SocksProxyAuthenticationFailedException("Socks proxy server requires authentication."); } else { throw new SocksProxyAuthenticationFailedException("Socks proxy server does not support username/password method."); } default: throw new SocksProxyException("Socks proxy server returned unknown method."); } }