网络安全传输系统(5)—账号管理子系统设计

1.登录模块设计

  1. 输入用户名和密码
  2. 根据用户名从数据库提取密码
  3. 比较用户输入密码和数据库提取密码,以决定是否登录成功

2.编译客户端程序

  • arm-linux-gcc
  • -L ../../008/openssl-1.0.0s/_install/lib/ -lssl -lcrypto
  • -I ../../008/openssl-1.0.0s/_install/include/
  • -L ../../010/sqlite-autoconf-3070800/_install/lib/ -lsqlite3
  • -I ../../010/sqlite-autoconf-3070800/_install/include/
  • client.c -o client

3.创建数据库

  • ./test_db user.db "create table tb0(name varchar(10),passwd varchar(10));".

4.插入数据

  • ./test_db user.db "insert into tb0 values('xxx','123');"
  • ./test_db user.db "insert into tb0 values('xxx','456');"
  • ./test_db user.db "insert into tb0 values('xxx','789');"

5.改进的客户端代码

#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sqlite3.h> 

#define port 3333
 
int  sockclient;
struct sockaddr_in sockaddr1;
char ipaddr[15];

SSL_CTX *ctx;
SSL *ssl;

int linkS() 
{	
	if((sockclient=socket(AF_INET,SOCK_STREAM,0))==-1)
	{
	    perror("socket");	
	    exit(0);
	}
		
	memset(&sockaddr1,0,sizeof(sockaddr1));
	sockaddr1.sin_family = AF_INET;
	sockaddr1.sin_addr.s_addr = inet_addr(ipaddr);
	sockaddr1.sin_port = htons(port);
	
	if(connect(sockclient,(struct sockaddr* )&sockaddr1,sizeof(sockaddr1))==-1)
	{
	    perror("connect");
	    exit(0);
	}
	
	// 创建SSL
	ssl = SSL_new(ctx);
	SSL_set_fd(ssl, sockclient);
	SSL_connect(ssl);

	return 1;
}

//~~~~~~~~~~~~~~~~~~~~~~~上传文件~~~~~~~~~~~~~~~~~~~~~~~~~
void upload_file(char *filename)
{	
	int fd;
	char buf[1024];
	int count=0;
	int size = strlen(filename);
	char cmd = 'U';

	struct stat fstat;
		
	if((fd=open(filename,O_RDONLY))==-1)
	{
		perror("open: ");
		return;
	}
	
	/*发送上传命令*/
	// write(sockclient,&cmd,1);
	SSL_write(ssl,&cmd,1);
	
	/*发送文件名*/
	// write(sockclient,(void *)&size,4);
	// write(sockclient,filename,size);
	SSL_write(ssl,(void *)&size,4);
	SSL_write(ssl,filename,size);
	
	/*发送文件长度*/
	if(stat(filename,&fstat)==-1)
		return;
	
	// write(sockclient,(void *)&(fstat.st_size),4);
	SSL_write(ssl,(void *)&(fstat.st_size),4);
	
	/*发送文件内容*/
	while((count=read(fd,(void *)buf,1024))>0)
	{
		// write(sockclient,&buf,count);	
		SSL_write(ssl,&buf,count);	
	}		
	
	close(fd);

}
//~~~~~~~~~~~~~~~~~~~~~~~下载文件~~~~~~~~~~~~~~~~~~~~~~~~~
void download_file(char *filename)
{
	int fd;
	char buf[1024];
	int count=0;
	int filesize = 0;
	int tmpsize = 0;
	int namesize = 0;
	char cmd = 'D';
	
	int size = strlen(filename);
	
	/*发送下载命令*/
	// write(sockclient,(void *)&cmd,1);
	SSL_write(ssl,(void *)&cmd,1);
	
	/*发送文件名*/
	// write(sockclient,&size,4);
	// write(sockclient,filename,size);
	SSL_write(ssl,&size,4);
	SSL_write(ssl,filename,size);
	
	/*创建文件*/
	if((fd=open(filename,O_RDWR|O_CREAT,0777))<0)
	{
		perror("open error:\n");	
	}
	
	/*接收文件长度*/
	// read(sockclient,&filesize,4);
	SSL_read(ssl,&filesize,4);

	while((count=SSL_read(ssl,(void *)buf,1024))>0)
	{
		write(fd,&buf,count);
		tmpsize += count;
		if(tmpsize==filesize)
			break;	

	}
	
	close(fd);	
}

void quit()
{
	char cmd = 'Q';
	
	// write(sockclient,(void *)&cmd,1);
	SSL_write(ssl,(void *)&cmd,1);
	
	system("clear");
	
	// 关闭SSL
	SSL_shutdown(ssl);
	SSL_free(ssl);
	close(sockclient);
	SSL_CTX_free(ctx);
    			
	exit(0);	
}

void menu()
{
	char command;
	char file_u[30];
	char file_d[30];
	char tmp;
	char c;
	
	while(1)
	{
		printf("\n------------------------------  1.Upload Files  ------------------------------\n");
		printf("------------------------------  2.Download Files  ------------------------------\n");
		printf("------------------------------      3.Exit   ------------------------------------\n");
		printf("Please input the Client command:");	

		command=getchar();
		
		switch(command)
		{
			case '1':
			{
					printf("Upload File:");
					
					while ((c=getchar()) != '\n' && c != EOF);
					
					fgets(file_u,30,stdin);
					
					file_u[strlen(file_u)-1]='\0';

					upload_file(file_u);
		  	}
			break;
				
			case '2':
				{
					printf("Download Files:");
					
					while ((c=getchar()) != '\n' && c != EOF);
					
					fgets(file_d,sizeof(file_d),stdin);
					
					file_d[strlen(file_d)-1]='\0';
					
					download_file(file_d);
			  	}
				break;
				
			case '3':
				quit();
				
				break;
			
			default:
				printf("Please input right command\n");
				break;
		}
	}
}

char passwd_d[10];

static int callback(void *NotUsed, int argc, char **argv, char **azColName) 
{ 
	int i; 
    for (i=0; i<argc; i++) 
    { 
    	// printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 
        strcpy(passwd_d, argv[i]);
    } 
    printf("\n"); 
    return 0;
} 

int login()
{
     char username[10];
     char passwd[10];
     sqlite3 *db;
     char sql[50];
     
     int success;
     
     //1. 通知用户输入用户名和密码
     printf("User name: ");
     scanf("%s",username);
     
     printf("Password: ");
     scanf("%s",passwd);

     //2. 根据用户名,从数据库提取正确的密码
     sprintf(sql, "select passwd from tb0 where name='%s';", username); 
     sqlite3_open("user.db", &db); 
     sqlite3_exec(db, sql, callback, 0, NULL);
     sqlite3_close(db); 

     //3. 比较用户输入的密码和数据库提取出的密码,以决定是否登录成功
     success = strcmp(passwd, passwd_d);
     	
     return success;	
}

int main(int argc,char *args[])
{
    if(argc!=2)
    {
	    printf("format error: you mast enter ipaddr like this : client 192.168.0.111\n");
	    exit(0);
    }
    
    strcpy(ipaddr,args[1]); 
    
    if (login() != 0)
    {
         printf("wrong username or password!\n");
         exit(0);	
    }
	
    // SSL库初始化
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(SSLv23_client_method());
    
    linkS();
    
    menu();
    
    return 0;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值