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

📄 sys_ssl.c

📁 ssl vpn系统.web服务器不支持ssl的情况下,browser可以使用ssl建立连接.
💻 C
字号:
#include <sys/un.h>
#include <setjmp.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/stat.h>

#include <sys/sysinfo.h>
//add for ssl
#include <openssl/rsa.h>       /* SSLeay stuff */
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "sys_status.h"

#include <zebra.h>
#include "sys_ssl.h"
#include "list.h"
#define dprintf printf
extern int verify_client;
static SSL_CTX* ctx=NULL;
extern int ssl_listen_fd;

struct list_head  sslsocks;
extern fd_set ssl_read_set;
SSL * create_ssl_con(int sd);
int ssl_serv_accept ();
void ssl_init()
{

 	SSL_METHOD *meth;
 	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();
//	meth = TLSv1_server_method();
 	meth = SSLv23_server_method();
	ctx = SSL_CTX_new (meth);
	if (!ctx) 
	{
		dprintf("init ctx error\n");
		exit(2);
	}
	dprintf("init ctx ok\n");
  
  	if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) 
	{
   	  	dprintf("init certificate file  error\n");
   	 	exit(3);
 	 }
   	dprintf("init certificate file  ok\n");
  	if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0)
	{
 	   dprintf("init private key file  error\n");
 	   exit(4);
	}
  	dprintf("init private key file  ok\n");
  	if (!SSL_CTX_check_private_key(ctx))
	{
  	dprintf("Private key does not match the certificate public key\n");
   	exit(5);
	}
 	dprintf("Private key  match the certificate public keyok \n");
     
 

 	if(NULL==SSL_load_client_CA_file(CAFP))
 	 { 
 		 dprintf(" load ca error\n");
 		 exit(1);
 	 }
	
 	dprintf("verify client =  %d       \n" ,verify_client);
	if(!verify_client) return;
	 SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
				SSL_VERIFY_CLIENT_ONCE,NULL);
	 SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAFP));
 	
	//else
 		//SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);


	if ((!SSL_CTX_load_verify_locations(ctx,CAFP,HOME)) ||
		(!SSL_CTX_set_default_verify_paths(ctx)))
	{
	   dprintf(" set default verify paths failed \n");
	   exit(1);
	}



}

inline struct ssl_client * sclient_alloc()
{
	 struct ssl_client * c= malloc(sizeof(struct ssl_client));
	 memset(c,0,sizeof(struct ssl_client));
	 return c;
}

intssl_serv_accept ()
{  int val;  SSL*ssl=NULL;
  int fd=-1;
  struct ssl_client * sclient;
  struct sockaddr_in client;
  socklen_t len;
  int accept_sock=ssl_listen_fd;

  len = sizeof (struct sockaddr_in);
  {

  	fd= accept (accept_sock, (struct sockaddr *) &client, &len);
  	if(fd==-1)
  	{
  	dprintf("\naccept error\n");
  	return -1;
  	}
   	dprintf("\naccept ok\n");
  	ssl=create_ssl_con(fd);
      if(ssl==NULL) {dprintf("\n ----------listen sock  ssl accept error \n");close(fd);}
  	else
  	{
  	sclient =sclient_alloc();//notice
  	if(sclient ==NULL) 
	{
		close(fd);
		
		exit(0);
	}
	else	{		val = fcntl (fd, F_GETFL, 0);   		fcntl ( fd, F_SETFL, (val | O_NONBLOCK)); 		sclient->fd=fd;  		sclient->ssl=ssl;
		add_fd_set(sclient->fd);
  		list_add (&(sclient->list),&sslsocks);
		
		dprintf("\n ----------ssl_listen_fd %d ssl accept fd %d ok \n",ssl_listen_fd,sclient->fd);
	}  }  }
  	//status_serv_event (SSL_SERV, ssl_listen_fd, NULL);
  	return 0;}
SSL * create_ssl_con(int sd)
{
  int verify_error;
  char * str=NULL;
  int err;
  X509*    client_cert;
 
  SSL *ssl = SSL_new (ctx);                          
  SSL_set_fd (ssl, sd);
  err = SSL_accept (ssl); 
  if(err<0) { 
  dprintf(" ssl con failed to create.%s\n",X509_verify_cert_error_string(err)); 
  return NULL;
  }

  verify_error=SSL_get_verify_result(ssl);
  if (verify_error != X509_V_OK)
 {
	dprintf("Client certificate verified failed :%s\n",
				X509_verify_cert_error_string(verify_error));
	SSL_free (ssl);
	return NULL;
 }
  
  /* Get the cipher - opt */

  dprintf ("SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get client's certificate (note: beware of dynamic allocation) - opt */

  client_cert = SSL_get_peer_certificate (ssl);
  if (client_cert != NULL) {
    dprintf ("Client certificate:\n");
    
    str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
   if(str!=NULL)
    dprintf ("\t subject: %s\n", str);
    OPENSSL_free (str);
    
    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);
   if(str!=NULL)
    dprintf ("\t issuer: %s\n", str);
    OPENSSL_free (str);
    
    /* We could do all sorts of certificate verification stuff here before
       deallocating the certificate. */
    
    X509_free (client_cert);
  } else
    dprintf ("Client does not have certificate.\n");
  return ssl;
}
int sslclient_close (struct ssl_client *client)
{  /* Close file descriptor. */  if (client->fd)    {      close (client->fd);      client->fd = -1;    } if(client->ssl)  SSL_free (client->ssl); free( client);
}

int ssl_serv_read (struct ssl_client * client)
{  int sock;  int rc;
  int nbytes=0,total=0;
  u_short length;  u_char command;  struct stream * ibuf=NULL;
  char buffer[BUFFERLEN]={0};
  /* Get thread data.  Reset reading thread because I'm running. */
  
  if(client->ssl!=NULL) dprintf("Start to read from client %d \n",client->fd);
  for(;;)
  {
	  nbytes= SSL_read (client->ssl, buffer, BUFFERLEN-1);
	  total+=nbytes;
	  if(nbytes>0)
	  {
	  			
	   		
				
				dprintf (" Read from Client byte= %d  \nmsg=%s\n",nbytes,buffer);
				//if((rc=http_transfer_ctos(buffer))!=0)
				//	dprintf("-------------------ctos error %d\n",rc);
				if(client->reverse_fd<=0)
					reverse_serv_connect(client,buffer,nbytes);
				else
					reverse_serv_send(client,buffer,nbytes);
				//       reverse_serv_read(client);
				if(nbytes==BUFFERLEN-1) 
					continue;
				else break;

	  }
	  if(nbytes==0&&total>0) break;
	   if(total==0||nbytes<0)
	  {
	  	remove_client(client);
	  	dprintf (" Read from Client error .byte= %d  \nmsg=%s\n",nbytes,buffer);
	  	return -1;
	  }
  	}

  	return 0;
}

void sendto_sslclient(struct ssl_client * client,char *buf, int len)
{    
	int nbyte;
       nbyte=SSL_write(client->ssl,buf,len);
      	if(nbyte>0)
      		dprintf("Send to client ok bytes=%d\n",nbyte);
	else
		dprintf("Send to client error bytes=%d\n",nbyte);
    

   }

int
inet_pton(int family, const char *strptr, void *addrptr)
{
    if (family == AF_INET) {
    	struct in_addr  in_val;

        if (inet_aton(strptr, &in_val)) {
            memcpy(addrptr, &in_val, sizeof(struct in_addr));
            return (1);
        }
		return(0);
    }
	errno = EAFNOSUPPORT;
    return (-1);
}
int 
reverse_serv_connect(struct ssl_client * client,char *buf, int len)
{
	struct sockaddr_in	servaddr;
	int n;
	if((client->reverse_fd = socket(AF_INET, SOCK_STREAM, 0))<0)
	{
		dprintf(" failed to init reverse socket\n");
		client->reverse_fd =-1;
		return -1;
	}
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(80);
	inet_pton(AF_INET, "192.168.19.217", &servaddr.sin_addr);
	if ( (n = connect(client->reverse_fd , (struct sockaddr *)&servaddr, sizeof(servaddr)) )< 0) 
	{
		close(client->reverse_fd );
		client->reverse_fd=-1;
		dprintf("Connect to  server failed \n");
		return -1;
	}

	dprintf("Connect to  reverse server ok %d\n",client->reverse_fd);
	add_fd_set(client->reverse_fd);
	reverse_serv_send(client, buf,len);
//	reverse_serv_read( client);

	
	return 0;
}


int 
reverse_serv_send(struct ssl_client * client,char *buf,int len)
{

	
	if (  write(client->reverse_fd, buf, len) <= 0) 
		dprintf("Send to  server failed rfd=%d\n",client->reverse_fd);
	else
		dprintf("SEND to  server ok rfd=%d\n",client->reverse_fd);
	

	
	return 0;
}
int reverse_serv_read(struct ssl_client * client)
{
	int total=0,nbytes=0;
	char buffer[BUFFERLEN]={0};
	dprintf("Receive from  Server ..................................... \n");
	for(;;)
	{
		nbytes=read(client->reverse_fd,buffer,BUFFERLEN-1);
		total+=nbytes;
		if(nbytes>0)
		{		
			dprintf("\nRecieve from  server bytes=%d\n",nbytes);//%s\n",htmlbuf);
			
			sendto_sslclient(client,buffer,nbytes);
			if(nbytes==BUFFERLEN-1) 
					continue;
			else break;
		}
		
		if(nbytes==0&&total>0) break;
		if(total==0||nbytes<0)
		{
			dprintf("Receive from   Server failed \n");
		
			if(client->reverse_fd>0)
			{
				close(client->reverse_fd);
				del_fd_set(client->reverse_fd);
				client->reverse_fd=-1;
			}
			return -1;
		}
	
	
	}
	return 0;
}
 int proxy_forwarding(struct ssl_client *client,char * buf ,int direction)
{
	return 0;
}

int   http_transfer_ctos(char *buf)
{
	char *p1,p2,p3,p4,p5,p6;
	char dn[500]={0};
	char *line =buf;
	int l;
	int i=0;
	printf("\n--%d\n",i++);
	p1=strchr(buf,'/');
	printf("\n--%d\n",i++);
	if(p1==0)return -1;
	printf("\n--%d\n",i++);
	p1++;
	if(strncmp(p1,"http/",5)&&strncmp(p1,"HTTP/",5)) return -2;
	printf("\n--%d\n",i++);
	p2=strchr(p1+5,'/');
	printf("\n--%d\n",i++);
	
	if(p2==0)return -3;
	printf("--p1= %s \n",p2);
	printf("\n--%d\n",i++);
	l=(unsigned long)p2-(unsigned long)p1-5;
	printf("\n--%d\n",i++);
	printf("\n domain name len =%d \n",l);
	strncpy(dn,p1+5,l);
	printf("\n--%d\n",i++);
	printf("\n domain name =%s \n",dn);
	p2++;
	strcpy(p1,p2);
	p2=strstr(p1,"Referer");
	if(p2==0) return -4;
	
	strcpy(p2+13,p2+14);
	
	printf("\n html buffer=%s \n",buf);
	return 0;
	
	
	
}

int   http_transfer_ctos2(char *buf)
{
	char *p2=NULL;
	
	p2=strstr(buf,"Referer");
	if(p2<=0) return -4;
	
	strcpy(p2+13,p2+14);
	//printf("\n domain name =%s \n",dn);
	//printf("\n html buffer=%s \n",buf);
//	printf("\n refer buffer=%s \n",p2);
	return 0;
	
}
	

void  http_transfer_stoc(char *buf)
{
	;
}
 	
 

⌨️ 快捷键说明

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