mâinile proprii SOCKS5

Anonimatul pe net - nu este un subiect nou. Și tu cu siguranță setat la tipul A4Proxy lor prog calculator, SocksChain
și altele asemenea. Personal nu-mi place, atunci când să lucreze cu proxy nevoie de nici un prog separat. în primul rând
urât, atunci când o mulțime de ferestre de pe bara de activități sau pictograma din tava de sistem, și a doua îndoiți aceste fisuri necesită și lor
prea leneș să se uite 🙂 de ce am scris clase pentru a sprijini SOCKS5-servere pe care le pot zayuzat acum
în oricare dintre prog sale. Și acum vreau să spun tuturor cum să facă acest lucru.

Skonnektivshis la server, clientul trimite un pachet, care conține versiunea protocolului și a sprijinit
metode de autentificare. Acest pachet are următorul format:

Versiunea BYTE;
nMethods BYTE;
Metode BYTE [nMethods]

Versiunea trebuie să fie 5. metode Fiecare intrare nu numai determină metoda de autentificare, dar, de asemenea, o modalitate de a cripta datele,
în cazul în care acesta este utilizat. serverul selectează una dintre aceste metode. Puteți specifica orice număr de metode, dar în cazul în care serverul nu necesită autentificare, nicio metodă
cu excepția 0x00 (nu folosiți autentificare sau criptare) nu va fi necesară. Ca răspuns, serverul trimite pachetul după cum urmează:

Versiunea BYTE
Metoda BYTE,

metodă care - un server de metoda selectată sau 0xFF (nici una dintre metodele propuse nu este acceptată). În cazul în care metoda este 0x00, atunci puteți trimite imediat comanda.

Pachetul de comandă are următorul format:

Versiunea BYTE; // 5
BYTE Cmd; // 1 - CONNECT
BYTE Rezervat; // 0
AType BYTE; // 1 - IPv4; 3 - nume de domeniu; 4 - IPv6
BYTE adr [];
Port WORD; // octeți în comandă de rețea, și anume htons (Port) ..;

Dacă utilizați un nume de domeniu, trebuie să mergeți mai întâi octetul de lungime, și apoi șirul fără terminatorul de zero.

Serverul trimite acest răspuns:

Versiunea BYTE; // 5
BYTE Rep; // 0 - Ok
BYTE Rezervat; // 0
AType BYTE; // 1 - IPv4; 3 - nume de domeniu; 4 - IPv6
BYTE adr [];
Port WORD;

Deoarece șosete încapsulează TCP, este recomandabil să se facă șosete clasă de compuși derivați din
clasa Socket, dar MFCshny CSocket nu este potrivit, deoarece el are toate metodele
nu virtuale. Scrieți clasa soclu, și numesc, să zicem, CTSocket

privat:
ciorap dulie;
>;

clasa CSocksSocket. publice CTSocket
publice:
CreateSocket BOOL virtual ();
virtuale BOOL Connect (nesemnate ip lung, nesemnat portul scurt);
virtuale BOOL Connect (nume LPCSTR, nesemnat de port scurt);
int Trimitere virtuală (char const * str, int len);
virtuale int Recv (char * buf, int max);
virtuale BOOL Close ();
virtuale GetHost unsigned long ();

CTSocket * pSocket;
socks_ip unsigned long;
socks_port scurt unsigned;

// Implementare
BOOL CSocksSocket :: CreateSocket ()
if (! pSocket-> CreateSocket ()) return false;
în cazul în care (pSocket-> Connect (socks_ip, socks_port)!) return false;
tampon [0] = 5; // Ver
tampon [1] = 1; // metoda 1
tampon [2] = 0; // nici o autorizare
pSocket-> Trimitere (tampon, 3);
int n = pSocket-> Recv (tampon, 2);
dacă întoarce FALSE (n = 2!);
if (! tampon [1] = 0) return false; 0 // Metoda nu este acceptată
return true;
>

BOOL CSocksSocket :: Connect (nesemnate ip lung, nesemnat portul scurt)
tampon [0] = 5; // Ver
tampon [1] = 1; // CONNECT
tampon [2] = 0; // Rezervat
tampon [3] = 1; // IPv4
* ((Nesemnate lung *) (tampon + 4)) = ip;
* ((Nesemnate * scurt) (tampon + 8)) = portul;
pSocket-> Trimitere (tampon, 10);
int n = pSocket-> Recv (tampon, 10);
dacă întoarce FALSE (n = 10!);
if (! tampon [1] = 0) return false; // Nu se poate conecta
if (! tampon [3] = 1) return false; // Vom cere ca să spunem IP, și nu altceva.
l_ip = * ((unsigned long *) (tampon + 4));
return true;
>

BOOL CSocksSocket :: Connect (nume LPCSTR, nesemnat de port scurt)
tampon [0] = 5;
tampon [1] = 1;
tampon [2] = 0;
tampon [3] = 3; // nume de domeniu
int m = strlen (nume);
tampon [4] = m; // Lungime octet
memcpy (buffer + 5, nume, m); // Copiați șirul fără terminatorul de zero
* ((Nesemnate * scurt) (tampon + 5 + m)) = portul;
pSocket-> Trimitere (tampon, m + 7);
int n = pSocket-> Recv (tampon, 10);
dacă întoarce FALSE (n = 10!);
if (! tampon [1] = 0) return false;
if (! tampon [3] = 1) return false; // Vom cere ca să spunem IP, și nu altceva.
l_ip = * ((unsigned long *) (tampon + 4));
return true;
>

int CSocksSocket :: Trimite (char const * str, int len)
reveni pSocket-> Trimite (str, len);
>

int CSocksSocket :: Recv (char * buf, int max)
reveni pScoket-> Recv (buf, max);
>

void CSocksSocket :: Închide ()
pSocket-> Close ();
>

nesemnate CSocksSocket lung :: GetHost ()
l_ip reveni;
>

// Ei bine, testa acum programul
void main ()
WSAData WSAData;
tsock CTSocket;
CSocksSocket ssock (tsock);

în cazul în care (ssock.CreateSocket ()!) return; // Nu se poate conecta la șosete
// sau auth necesare
în cazul în retur (ssock.Connect ( «www.mail.ru», htons (80))!); // www.mail.ru
// este inaccesibil
LPSTR q = «HEAD / HTTP / 1.1 \ xD \ xAHost: www.mail.ru:80\xD\xAUser-Agent: xakep \ xD \ xA \ xD \ xA»;
ssock.Send (q, strlen (q));

char buf [1000];
int n = ssock.Recv (buf, 1000);
buf [n] = 0;
printf ( "% s", buf);

Arată acest articol unui prieten:

articole similare