You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Socks5Client.cs 2.2 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO.Pipelines;
  4. using System.Net;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace Shadowsocks.Protocol.Socks5
  8. {
  9. class Socks5Client : IStreamClient
  10. {
  11. NetworkCredential _credential;
  12. public Socks5Client(NetworkCredential credential = null)
  13. {
  14. _credential = credential;
  15. }
  16. public async Task Connect(EndPoint destination, IDuplexPipe client, IDuplexPipe server)
  17. {
  18. var pmp = new ProtocolMessagePipe(server);
  19. await pmp.WriteAsync(new Socks5VersionIdentifierMessage
  20. {
  21. Auth = _credential == null ? new [] { Socks5Message.AuthNone } : new [] { Socks5Message.AuthNone, Socks5Message.AuthUserPass }
  22. });
  23. var msm = await pmp.ReadAsync<Socks5MethodSelectionMessage>();
  24. switch (msm.SelectedAuth)
  25. {
  26. case Socks5Message.AuthNone:
  27. break;
  28. case Socks5Message.AuthUserPass:
  29. Debug.Assert(_credential != null);
  30. var name = _credential.UserName;
  31. var password = _credential.Password;
  32. await pmp.WriteAsync(new Socks5UserPasswordRequestMessage
  33. {
  34. User = Encoding.UTF8.GetBytes(name),
  35. Password = Encoding.UTF8.GetBytes(password),
  36. });
  37. var upResp = await pmp.ReadAsync<Socks5UserPasswordResponseMessage>();
  38. if (!upResp.Success) throw new UnauthorizedAccessException("Wrong username / password");
  39. break;
  40. default:
  41. throw new NotSupportedException("Server not support our authencation method");
  42. }
  43. await pmp.WriteAsync(new Socks5RequestMessage
  44. {
  45. Command = Socks5Message.CmdConnect,
  46. EndPoint = destination,
  47. });
  48. var reply = await pmp.ReadAsync<Socks5ReplyMessage>();
  49. if (reply.Reply != Socks5Message.ReplySucceed) throw new Exception();
  50. await DuplexPipe.CopyDuplexPipe(client, server);
  51. }
  52. }
  53. }