?? sys_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);
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 + -