Socks5署理处事
当前位置:以往代写 > C/C++ 教程 >Socks5署理处事
2019-06-13

Socks5署理处事

Socks5署理处事

副标题#e#

假期的时候把socks5署理的RFC全部读完了,有些体会不敢独享,在这里写出来各人一起评论评论,如有错误敬请提出。

下面假设利用TCP毗连方法。首先需要和署理处事器之间成立毗连,这里没什么巨大的,简朴的connect(serverIP, serverPort)就可以了。毗连乐成之后,需要利用send()发送呼吁字,以便确定是否需要验证,下面是RFC内里的呼吁字名目:

项目 版本 方法数目 毗连方法
项目长度 1 1 1-255

首先"版本"这一项牢靠是 X"05"(socks version 5),方法数目汇报server毕竟提交了几种毗连方法的请求,至于毗连方法则可以有多个。下面就是方法列表:

毗连方法 寄义
X’00’ 无需验证,直接继承
X’01’ GSSAPI
X’02’ 需要用户名/暗码
X’03’ to X’7F’ IANA ASSIGNED
X’80’ to X’FE’ 保存方法,可以本身机动选用
X’FF’ 未包括切合要求的方法

接下来是server的回应:

项目 版本 答允的毗连方法
项目长度 1 1

版本不必说,仍然牢靠是 X"05",答允的毗连方法则是在你提交的浩瀚毗连方法中,由server选出一个可以接管的,然后返返来;假如没有,那么返回就是 X"FF"。个中一般用到的就是 X"00"和 X"02"了。它们之间的区别就在于 X"02"方法需要发送用户名/暗码,验证通事后的进程则和 X"00"方法没有任何区别。

客户端识别到server返回 X"02"之后,发送下列名目验证字串:

项目 VER 用户名长度 用户名 暗码长度 暗码
项目长度 1 1 1-255 1 1-255

留意:这里的VER有别于上边,牢靠是 X"01"。用户名/暗码最大长度是255。

server端验证完毕后返回功效:

项目 VER 验证功效
项目长度 1 1

验证功效是 X"00"的话,就暗示验证通过,不然都是不外…

接下来的进程一样,就是发送请求呼吁字了:

项目 版本 呼吁字 保存 地点范例 地点 端口
项目长度 1 1 X"00" 1 不牢靠 2

#p#分页标题#e#

版本牢靠 X"05";呼吁字分三种: CONNECT X"01",BIND X"02",UDP X"03"。CONNECT就是普通的TCP毗连;BIND要求你的client支持接管server的毗连请求(FTP协议就是一个典范的例子);UDP则是一个特例,我还没有完全领略… 保存项牢靠是 X"00"。

地点范例有三种:X"01"、X"03"、X"04",别离对应IP-V4、DOMAINNAME、IP-V6,而接下来的地点长度也按照地点范例的差异而变革。IP-V4的长度是4位,DOMAINNAME的长度则按照实际环境变革,可是地点的第一位的内容要设成域名字符串的长度,IP-V6就是16位。

端口长度牢靠两位,没什么可说的。

而server返回的内容名目也大抵沟通

项目 版本 返回值 保存 地点范例 地点(BND) 端口
项目长度 1 1 X"00" 1 不牢靠 2

返回值大概是下列值中的一个:

毗连方法 寄义
X’00’ 乐成
X’01’ general SOCKS server failure
X’02’ 毗连不切合server规格
X’03’ 方针网络无法达到
X’04’ 方针主机无法达到
X’05’ 毗连拒绝
X’06’ TTL expired
X’07’ 呼吁不支持
X’08’ 地点名目不支持
X’09 to X’FF’ 保存


#p#副标题#e#

预计列位看完上面的解读之后仍然是一头雾水,那么我就来贴一段代码,各人就大白了

///////////////////////////////////////////////////////////////////
//
// socks 5 典型
//
//
unsigned char command[10];//筹备毗连呼吁字
memset(command,0,10);
command[0]=5;//版本号 05
command[1]=m_bUseSocks5Logon?2:1;//假如需要验证的话,要发送两位方法字
command[2]=m_bUseSocks5Logon?2:0;
TRY
{
  Send(command,m_bUseSocks5Logon?4:3,0);
  int num=Receive(command,2);
  if (num!=2)
  {
   m_nProxyError=PROXYERROR_REQUESTFAILED;
   return FALSE;
  }
}
CATCH_ALL(e)
{
  m_nProxyError=PROXYERROR_REQUESTFAILED;
  return FALSE;
}
END_CATCH_ALL
if (command[1]==0xFF)
{
  m_nProxyError=PROXYERROR_AUTHREQUIRED;// 0xFF暗示失败,没有符合的毗连方法
  return FALSE;
}
if (command[1])
{
  if (command[1]!=2)
  {
   m_nProxyError=PROXYERROR_AUTHTYPEUNKNOWN;// 验证方法未知
   return FALSE;
  }
  if (m_bUseSocks5Logon)
  {
   unsigned char *buffer=new unsigned
      char[3+m_ProxyUser.GetLength()+m_ProxyPass.GetLength()];
   sprintf((char *)buffer," %s %s",m_ProxyUser,m_ProxyPass);//分派用户名暗码缓冲区
   buffer[0]=5;
   buffer[1]=m_ProxyUser.GetLength();
   buffer[2+m_ProxyUser.GetLength()]=m_ProxyPass.GetLength();
   TRY
   {
    Send(buffer,3+m_ProxyUser.GetLength()+m_ProxyPass.GetLength(),0);
    //Get auth response
    int num=Receive(command,2);
    if (num!=2)
    {
     delete [] buffer;
     m_nProxyError=PROXYERROR_AUTHFAILED;
     return FALSE;
    }
   }
   CATCH_ALL(e)
   {
    delete [] buffer;
    m_nProxyError=PROXYERROR_AUTHFAILED;
    return FALSE;
   }
   END_CATCH_ALL
if (command[1]!=0x00)
   {
    delete [] buffer;
    m_nProxyError=PROXYERROR_AUTHFAILED;
    return FALSE;
   }
   delete [] buffer;
  }
  else
  {
   m_nProxyError=PROXYERROR_AUTHNOLOGON;
   return FALSE;
  }
}
//构建请求
memset(command,0,10);
command[0]=5;
command[1]=1;
command[2]=0;
command[3]=1;
memcpy(&command[4],&sockAddr->sin_addr.S_un.S_addr,4);
memcpy(&command[8],&sockAddr->sin_port,2);
//上面只提供了IP-4地点方法,其他的可以自行变动代码
TRY
{
  Send(command,10,0);
  int num=Receive(command,10);
  if (num!=10)
  {
   m_nProxyError=PROXYERROR_REQUESTFAILED;
   return FALSE;
  }
}
CATCH_ALL(e)
{
  m_nProxyError=PROXYERROR_REQUESTFAILED;
  return FALSE;
}
END_CATCH_ALL
if (command[1]!=0x00)
{
  m_nProxyError=PROXYERROR_REQUESTFAILED;
  return FALSE;
}

总之就是这个样子了,假如尚有不大白的处所.

    关键字:

在线提交作业