⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idsocksserver.pas

📁 photo.163.com 相册下载器 多线程下载
💻 PAS
📖 第 1 页 / 共 2 页
字号:
begin
  LSupportsAuth := false;
  for a := 1 to byte( AThread.Connection.IOHandler.ReadChar ) do
  begin
    if byte( AThread.Connection.IOHandler.ReadChar ) = IdSocksAuthUsernamePassword then
    begin
      LSupportsAuth := true;
    end;
  end;
  if not Socks5NeedsAuthentication then
  begin
    SendV5Response( AThread, IdSocksAuthNoAuthenticationRequired )
  end
  else
  begin
    if not LSupportsAuth then
    begin
      SendV5Response( AThread, IdSocksAuthNoAcceptableMethods ) ;
      AThread.Connection.disconnect; // not sure the server has to disconnect
      raise EIdSocksSvrNotSupported.create(RSSocksSvrNotSupported);
//      exit; //exception
    end
    else
    begin
      SendV5Response( AThread, IdSocksAuthUsernamePassword ) ;
      AThread.Connection.IOHandler.ReadChar; //subversion, we don't need it.
      LUsername := AThread.Connection.IOHandler.ReadString( byte( AThread.Connection.IOHandler.readchar ) ) ;
      LPassword := AThread.Connection.IOHandler.ReadString( byte( AThread.Connection.IOHandler.readchar ) ) ;
      LValidLogin := false;
      DoAuthenticate( TIdSocksServerContext( AThread ) , LUsername, LPassword, LValidLogin ) ;
      if LValidLogin then
      begin
        AThread.Connection.IOHandler.Write(#1+chr(IdSocksLoginSuccess) );
      end
      else
      begin
        AThread.Connection.IOHandler.Write(#1+chr(IdSocksLoginFailure )) ;
        AThread.Connection.disconnect;
        raise EIdSocksSvrNotSupported.create(RSSocksSvrInvalidLogin);
        //exit; //exception
      end;
    end;
  end;
  AThread.Connection.IOHandler.ReadChar; // socks version, should be 5

  Acommand := byte( AThread.Connection.IOHandler.ReadChar ) ;

  AThread.Connection.IOHandler.ReadChar; //reserved, should be 0

  LTyp := byte( AThread.Connection.IOHandler.ReadChar ) ;

  case LTyp of
    1:
      begin
        Lline := AThread.Connection.IOHandler.ReadString( 6 ) ;
        Ahost := inttostr( ord( Lline[1] ) ) + '.' + inttostr( ord( Lline[2] ) ) + '.' + inttostr( ord( Lline[3] ) ) + '.' + inttostr( ord( Lline[4] ) ) ;
        Aport := ord( Lline[5] ) * 256 + ord( Lline[6] ) ;
      end;
    3:
      begin
        Ahost := AThread.Connection.IOHandler.ReadString( byte( AThread.Connection.IOHandler.readchar ) ) ;
        Lline := AThread.Connection.IOHandler.ReadString( 2 ) ;
        Aport := ord( Lline[1] ) * 256 + ord( Lline[2] ) ;
      end;
    4:  // ip v6
      begin
        AThread.Connection.IOHandler.Readchar;// should be 18 (16 for host, and 2 for port)
        Lline := AThread.Connection.IOHandler.ReadString( 18 ) ;
todo;
//        Ahost:=GStack.TInAddrToString(lline[1],id_ipv6);
        Aport := ord( Lline[17] ) * 256 + ord( Lline[18] ) ;
      end;
  else
    raise EIdSocksSvrSocks5WrongATYP.Create( RSSocksSvrWrongATYP ) ;
  end;
end;

procedure TIdCustomSocksServer.HandleConnectV4( AThread: TIdSocksServerContext; var ACommand: byte; var AUserId, AHost: string; var Aport: integer ) ;
var
  Lline: string;
begin
  Acommand := byte( AThread.Connection.IOHandler.ReadChar ) ;
  Lline := AThread.Connection.IOHandler.ReadString( 2 ) ;
  Aport := ord( Lline[1] ) * 256 + ord( Lline[2] ) ;
  Lline := AThread.Connection.IOHandler.ReadString( 5 ) ;
  Ahost := inttostr( ord( Lline[1] ) ) + '.' + inttostr( ord( Lline[2] ) ) + '.' + inttostr( ord( Lline[3] ) ) + '.' + inttostr( ord( Lline[4] ) ) ;
end;

function TIdCustomSocksServer.DoExecute( AThread: TIdContext ) : boolean;
var
  LVersion: byte;
  LCommand: byte;
  LUserId: string;
  LHost: string;
  Lport: integer;
  LSocksServerThread: TIdSocksServerContext absolute AThread;
begin
  //just to keep the compiler happy
  Result := True;

  LVersion := byte( AThread.Connection.IOHandler.ReadChar ) ;
  TIdSocksServerContext( AThread ) .SocksVersion := LVersion;

  if not ( ( ( LVersion = 4 ) and AllowSocks4 ) or ( ( LVersion = 5 ) and AllowSocks5 ) ) then
    raise EIdSocksSvrWrongSocksVer.Create( RSSocksSvrWrongSocksVersion ) ;

  case LVersion of
    4: HandleConnectV4( TIdSocksServerContext( AThread ) , LCommand, LUserId, LHost, Lport ) ;
    5: HandleConnectV5( TIdSocksServerContext( AThread ) , LCommand, LUserId, LHost, Lport ) ;
  end;

  case LCommand of
    1: CommandConnect( TIdSocksServerContext( AThread ) , LUserId, LHost, LPort ) ;
    2: CommandBind( TIdSocksServerContext( AThread ) , LUserId, LHost, LPort ) ;
    //3: //udp bind
  else
    raise EIdSocksSvrWrongSocksCmd.Create( RSSocksSvrWrongSocksCommand ) ;
  end;
end;

procedure TIdSocksServer.CommandConnect( AThread: TIdSocksServerContext; AUserId, AHost: string; APort: integer ) ;
var
  LIdtcpclient: tidtcpclient;
  LAlowed: boolean;
begin
  LAlowed := true;
  DoBeforeConnectUser( AThread, AUserId, AHost, Aport, LAlowed ) ;
  if not LAlowed then
  begin
    if AThread.SocksVersion = 4 then
    begin
      AThread.Connection.IOHandler.write( #0#2#0#1 + #0#0#0#0#0#0 )
    end
    else
    begin
      AThread.Connection.IOHandler.write( chr( AThread.SocksVersion ) + #2#0#1 + #0#0#0#0#0#0 ) ;
    end;
    raise EIdSocksSvrAccessDenied.Create( RSSocksSvrAccessDenied ) ;
  end;

  LIdtcpclient := nil;
  try

    LIdtcpclient := tidtcpclient.create( nil ) ;
    LIdtcpclient.IOHandler:=TIdIOHandlerStack.Create(nil);
    LIdtcpclient.port := Aport;
    LIdtcpclient.host := Ahost;
    try
      if Length(MakeCanonicalIPv6Address(Ahost))>0 then
      begin
todo;
//        (LIdtcpclient.IOHandler as TIdIOHandlerStack).IPVersion:=Id_IPv6;
      end;
      LIdtcpclient.Connect;
      if AThread.SocksVersion = 4 then
      begin
        AThread.Connection.IOHandler.write( #4#90 + #0#0#0#0#0#0 )
      end
      else
      begin
        AThread.Connection.IOHandler.write( chr( AThread.SocksVersion ) + #0#0#1 + #0#0#0#0#0#0 )
      end;
    except
      if AThread.SocksVersion = 4 then
      begin
        AThread.Connection.IOHandler.write( #4#91#0#1 + #0#0#0#0#0#0 )
      end
      else
      begin
        AThread.Connection.IOHandler.write( chr( AThread.SocksVersion ) + #4#0#1 + #0#0#0#0#0#0 ) ;
        raise;
      end;
    end;
    TransferData( AThread.Connection, LIdtcpclient ) ;
    LIdtcpclient.Disconnect;
    AThread.Connection.Disconnect;
  finally
    if assigned(LIdtcpclient.IOHandler) then begin
    	LIdtcpclient.IOHandler.free;
    	LIdtcpclient.IOHandler:=nil;
    end;
    LIdtcpclient.free;
  end;
end;

function ipStrToStr( ip: string ) : string;
var
  a: integer;
begin
  setlength( result, 4 ) ;

  a := pos( '.', ip ) ;
  result[1] := chr( strtoint( copy( ip, 1, a - 1 ) ) ) ;
  ip := copy( ip, a + 1, maxint ) ;

  a := pos( '.', ip ) ;
  result[2] := chr( strtoint( copy( ip, 1, a - 1 ) ) ) ;
  ip := copy( ip, a + 1, maxint ) ;

  a := pos( '.', ip ) ;
  result[3] := chr( strtoint( copy( ip, 1, a - 1 ) ) ) ;
  ip := copy( ip, a + 1, maxint ) ;

  result[4] := chr( strtoint( ip ) ) ;
end;

function PortToStr( const port: word ) : string;
begin
  result := chr( Port div 256 ) + chr( Port mod 256 )
end;

procedure TIdSocksServer.CommandBind( AThread: TIdSocksServerContext; AUserId, AHost: string; APort: integer ) ;
var
  LIdSimpleServer: TIdSimpleServer;
  LAlowed: boolean;
begin
  LAlowed := true;
  DoBeforeBind( AThread, AUserId, AHost, Aport, LAlowed ) ;
  if not LAlowed then
  begin
    if AThread.SocksVersion = 4 then
    begin
      AThread.Connection.IOHandler.write( #0#2#0#1 + #0#0#0#0#0#0 )
    end
    else
    begin
      AThread.Connection.IOHandler.write( #5#2#0#1 + #0#0#0#0#0#0 ) ;
    end;
    raise EIdSocksSvrAccessDenied.Create( RSSocksSvrAccessDenied ) ;
  end;

  LIdSimpleServer := nil;
  try
    LIdSimpleServer := TIdSimpleServer.create( nil ) ;

    LIdSimpleServer.BeginListen;

    if AThread.SocksVersion = 4 then
    begin
      AThread.Connection.IOHandler.write( #0 + #90 + PortToStr( LIdSimpleServer.Binding.Port ) + ipstrtostr( LIdSimpleServer.Binding.IP ) )
    end
    else
    begin
      AThread.Connection.IOHandler.write( chr( AThread.SocksVersion ) + #0#0#1 + ipstrtostr( LIdSimpleServer.Binding.IP ) + chr( LIdSimpleServer.Binding.Port div 256 ) + chr( LIdSimpleServer.Binding.Port mod 256 ) ) ;
    end;

    //  while AThread.Connection.Connected do
    //    LIdSimpleServer.Listen(30000); // wait 30 secs
    LIdSimpleServer.Listen;

//    assert( LIdSimpleServer.binding.PeerIP = AHost ) ;

    if not AThread.Connection.Connected then
    begin
      raise EIdSocksSvrUnexpectedClose.create( RSSocksSvrUnexpectedClose ) ;
    end;
    TransferData( AThread.Connection, LIdSimpleServer ) ;

    LIdSimpleServer.Disconnect;
    AThread.Connection.Disconnect;
  finally
    LIdSimpleServer.free;
  end;
end;

procedure TIdEventSocksServer.CommandConnect( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) ;
begin
  if assigned( foncommandconnect ) then
  begin
    foncommandconnect( AThread, AUserId, AHost, Aport ) ;
  end;
end;

procedure TIdEventSocksServer.CommandBind( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) ;
begin
  if assigned( foncommandbind ) then
  begin
    foncommandbind( AThread, AUserId, AHost, Aport ) ;
  end;
end;

{ Constructor / Destructors }

procedure TIdCustomSocksServer.InitComponent;
begin
  inherited;
  FContextClass := TIdSocksServerContext;
  DefaultPort := IdPORT_SOCKS;
  AllowSocks4 := true;
  AllowSocks5 := true;
  Socks5NeedsAuthentication := false;
end;

destructor TIdCustomSocksServer.Destroy;
begin
  inherited;
end;

{ TIdSocksServerContext }

constructor TIdSocksServerContext.Create;
begin
  inherited;
  FUser := '';
  FPassword := '';
  FSocksVersion := 0;
end;

destructor TIdSocksServerContext.Destroy;
begin
  inherited;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -