Опытный
 
Профиль
Группа: Участник
Сообщений: 275
Регистрация: 17.6.2006
Репутация: нет Всего: 1
|
Делаю курсовой, есть код но не понятно что он делает, прошу помощи, может кто разъеснит.. Знач есть клиент и сервер, при запуске сервер ждет подключений клиентов, затем как клиент подключился, начинается вычисление ключа по алгоритму Диффи-Хеллмана, сам алгоритм понимаю, но не могу разобраться в реализации: в функции main вызов key_dh(pg); в нем функции h,a - совсем не понимаю что они делают. Также преподаватель сказал что названия у функций ужасные, оно и верно, ведь не понятно что они делают((( Хочу разобратья, прошу помощи! Код | /* server.c */ #include <arpa/inet.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/time.h> #include <sys/resource.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <signal.h> #include <netinet/in.h> #include <netdb.h> #include <fcntl.h> #include <stdint.h>
// source string ["Hello, clients!"] uint32_t source_str [4] = {0x48656C6C,0x6F2C2063, 0x6C69656E, 0x74732100};
// pointers to source string uint32_t* psource_str=&source_str[0]; char* char_str=(char*)&source_str;
// encrypt string uint32_t encrypt_str[4];
// pointer to encrypt string uint32_t* pencrypt_str=&encrypt_str[0];
// encrypt key [128 bits] uint32_t keys [4] = {0x00000000, 0x00000000, 0x00000000, 0x0000DED4};
// pointer to encrypt key uint32_t* pkey=&keys[0];
// encrypt function [works with 64 bits slice of source string] void encrypt_string (uint32_t* v, uint32_t* k,int cnt) { uint32_t v0=v[0], v1=v[1], sum=0, i; uint32_t delta=0x9e3779b9; uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; for (i=0; i < 32; i++) { sum += delta; v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); } v[0]=v0; v[1]=v1;
printf(" %X %X",v[0],v[1]); encrypt_str[cnt]=v[0]; encrypt_str[cnt+1]=v[1]; }
/* PREDEFINED VARIABLES*/ #define PORT "5555" // the port users(clients) will be connecting to #define BACKLOG 10 // how many pending connections queue will hold
unsigned char m[1024]; unsigned char g[1024]; unsigned char e[1024]; unsigned char b[1024];
int n,v,d,z,S=129;
unsigned char key[2]; // public key or secret session key unsigned char pg [128] = "3" ; // public generator unsigned char ppm[128] = "10001"; // public prime modulus unsigned char se [128] = "9A2E"; // secret exponent unsigned char see[128] = "6246";
char buffer[1024];
a(unsigned char *x,unsigned char *y,int o) { d=0; for(v=S;v--;) { d+=x[v]+y[v]*o; x[v]=d;d=d>>8; } }
s(unsigned char *x) { for(v=0;(v<S-1)&&(x[v]==m[v]);) v++; if(x[v]>=m[v]) a(x,m,-1); }
r(unsigned char *x) { d=0; for(v=0;v<S;) { d|=x[v]; x[v++]=d/2; d=(d&1)<<8; } }
M(unsigned char *x,unsigned char *y) { unsigned char X[1024],Y[1024]; bcopy(x,X,S); bcopy(y,Y,S); bzero(x,S); for(z=S*8;z--;) { if(X[S-1]&1) { a(x,Y,1); s(x); } r(X); a(Y,Y,1); s(Y); } }
h(char *x,unsigned char *y) { bzero(y,S); for(n=0;x[n]>0;n++) { for(z=4;z--;) a(y,y,1); x[n]|=32; y[S-1]|=x[n]-48-(x[n]>96)*39; } }
p(unsigned char *x) { for(n=0;!x[n];) n++; for(;n<S;n++); key[0]=b[127]; key[1]=b[128]; }
void key_dh(char* pk) { h(pk,g); // public generator h(se,e); // secret exponent h(ppm,m); // public prime modulus bzero(b,S); b[S-1]=1; for(n=S*8;n--;) { if(e[S-1]&1)M(b,g); M(g,g); r(e); } p(b); }
void sigchld_handler( int s ) { while( waitpid(-1, NULL, WNOHANG) > 0 ); }
/* GET SOCKADDR, IPv4 or IPv6*/ void* get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); } int main(int argc, char** argv, char** envp) {
int sockfd, new_fd; // server "listen" on sock_fd, new connection on new_fd struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; // connector's address information socklen_t sin_size; struct sigaction sa; int yes=1; char s[INET6_ADDRSTRLEN]; int rv; unsigned char key_buf[2]; int numbytes;
memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP if( (rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0 ) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for ( p = servinfo; p != NULL; p = p->ai_next ) { if ( (sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1 ) { perror("server: socket"); continue; } if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1 ) { perror("setsockopt"); exit(1); } if ( bind(sockfd, p->ai_addr,p->ai_addrlen) == -1 ) { close(sockfd); perror("server: bind"); continue; } break; } if ( p == NULL ) { fprintf(stderr, "server: failed to bind\n"); return 2; } freeaddrinfo(servinfo); // all done with this structure if ( listen(sockfd, BACKLOG) == -1 ) { perror("listen"); exit(1); } sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if ( sigaction(SIGCHLD, &sa, NULL) == -1 ) { perror("sigaction"); exit(1); } printf("server: waiting for connections...\n"); while( 1 ) { sin_size = sizeof their_addr; new_fd = accept( sockfd, (struct sockaddr*)&their_addr, &sin_size ); if ( new_fd == -1 ) { perror("accept"); continue; } inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr*)&their_addr), s, sizeof s ); printf("server: got conection from %s\n", s); if ( !fork() ) { close(sockfd); printf("server: generating public key..."); key_dh(pg); printf("%X%X\n", key[0],key[1]); if( send(new_fd, key, 2, 0) == -1 ) perror("send"); printf("server: received client's public key: %s\n", see); printf("server: generating private key..."); key_dh(see); printf("%X%X\n", key[0],key[1]); printf("server: communication channel is protected... OK\n"); printf("wait next request..."); int i=0; static int si=0; for( i=0; i < 100000; i++ ) { printf("."); si++; if(si == 5) break; } int flags;
/*if ((flags = fcntl(new_fd, F_GETFL, 0)) < 0) { perror("fcntl"); } if (fcntl(new_fd, F_SETFL, flags | O_NONBLOCK) < 0) { perror("fcntl"); }*/ char ok[1024]="NO"; char* pok=&ok[0]; while(1) { if(recv(new_fd, pok, 3, 0) > 0); break; } ok[2]='\0'; printf("%s",ok); printf("\nserver: "); int cnt=0; static int counter=0; for( i=0; i<2; i++ ) { if( counter == 0) { printf("encrypt string:"); } encrypt_string(psource_str,pkey,cnt); psource_str+=2; cnt+=2; counter++; } printf("\nserver: transmission of encrypted data..."); if( send(new_fd, pencrypt_str, 16, 0) == -1 ) perror("send"); printf("%s",ok); printf("\nbye!!!\n"); printf("wait next request..."); close(new_fd); exit(0); } close(new_fd); } return 0; }
|
|