登录模块设计
1.输入用户名和密码
2.根据用户名从数据库提取密码
3.比较用户输入密码和数据库提取密码,以决定是否登录成功
编译客户端程序
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
创建数据库
./db client.db "create table login(username varchar(20), password varchar(20));”
插入数据
./db client.db "insert into login values('yuan','123456');"
./db client.db "insert into login values('chen','654321');"
client.c
/******************************************************************** *名称:client.c *作者:D *时间:2016.04.03 *功能:网络安全传输系统客户端 *********************************************************************/ /******************************************************************** *头文件 *********************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/socket.h> #include <netinet/in.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <sqlite3.h> /******************************************************************** *宏定义 *********************************************************************/ #define SERVER_PORT 3333 //网络端口 /******************************************************************** *函数原型 *********************************************************************/ int main(int argc, char **argv); int login(); int callback(void *passback, int argc, char **argv, char **colName); void menu(SSL *ssl); void upload(SSL *ssl); void download(SSL *ssl); void quit(SSL *ssl); /******************************************************************** *名称:main *参数: * argc 参数数量 * argv 参数列表 *返回: * stat 0 成功 * -1 失败 *功能:主函数 *********************************************************************/ int main(int argc, char **argv){ //参数检查 if(argc != 2){ printf("Usage: ./client <ip address> "); return -1; } //用户登录 if(login() != 0){ printf("Wrong username or password! "); return -1; } //创建 SSL SSL_CTX *ctx; SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); ctx = SSL_CTX_new(SSLv23_client_method()); //客户端模式 //创建标识 int clientfd; clientfd = socket(AF_INET, SOCK_STREAM, 0); if(clientfd == -1){ printf("Can not create socket! "); return -1; } //建立连接 struct sockaddr_in serverAddr; int isConnect; serverAddr.sin_family = AF_INET; //设置协议 serverAddr.sin_port = htons(SERVER_PORT); //设置端口 serverAddr.sin_addr.s_addr = inet_addr(argv[1]); //设置地址 bzero(serverAddr.sin_zero, 8); //设置为零 isConnect = connect(clientfd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)); if(isConnect == -1){ printf("Can not connect to server! "); return -1; } //连接 SSL SSL *ssl; ssl = SSL_new(ctx); SSL_set_fd(ssl, clientfd); SSL_connect(ssl); //显示菜单 menu(ssl); //关闭 SSL SSL_shutdown(ssl); SSL_free(ssl); //关闭连接 close(clientfd); //释放 SSL SSL_CTX_free(ctx); return 0; } /******************************************************************** *名称:login *参数: * none *返回: * success 0 成功 * other 失败 *功能:用户登录 *********************************************************************/ int login(){ //输入用户名称 char username[20]; printf("Username: "); scanf("%s", &username); //输入用户密码 char password[20]; printf("Password: "); scanf("%s", &password); //打开数据库 sqlite3 *db; sqlite3_open("client.db", &db); //提取用户密码 char satement[80]; char passback[20]; sprintf(satement, "select password from login where username='%s';", username); sqlite3_exec(db, satement, callback, (void *)passback, NULL); //关闭数据库 sqlite3_close(db); //比较用户密码 int success; success = strcmp(password, passback); return success; } int callback(void *passback, int argc, char **argv, char **colName){ //提取用户密码 int i; for(i = 0; i < argc; i++){ if(strcmp(colName[i], "password") == 0){ strcpy((char *)passback, argv[i]); } } return 0; } /******************************************************************** *名称:menu *参数: * ssl 客户端标志 *返回: * none *功能:显示菜单 *********************************************************************/ void menu(SSL *ssl){ //显示菜单 while(1){ //打印菜单 printf(" "); printf("********************************************************************** "); printf("* Client * "); printf("*[1]Upload Files * "); printf("*[2]Download Files * "); printf("*[3]Exit * "); printf("********************************************************************** "); printf("Please Select: "); //输入命令 int num; scanf("%d", &num); //处理命令 switch(num){ //上传文件 case 1: upload(ssl); break; //下载文件 case 2: download(ssl); break; //退出程序 case 3: quit(ssl); break; //错误命令 default: printf(" Please input again! "); break; } //是否退出 if(num == 3){ break; } } } /******************************************************************** *名称:upload *参数: * ssl 客户端标志 *返回: * none *功能:上传文件 *********************************************************************/ void upload(SSL *ssl){ //输入文件名称 char filename[20]; printf(" Upload file: "); scanf("%s", &filename); //打开上传文件 int fd; fd = open(filename, O_RDONLY); if(fd == -1){ printf("Can not open file! "); return ; } //发送上传命令 char cmd = 'U'; SSL_write(ssl, (void *)&cmd, sizeof(cmd)); //发送文件名称 int namesize; namesize = strlen(filename) + 1; //加上字符串接收符 SSL_write(ssl, (void *)&namesize, sizeof(namesize)); SSL_write(ssl, (void *)&filename, namesize); //发送文件长度 struct stat fstat; int isState; isState = stat(filename, &fstat); if(isState == -1){ printf("Can not get file state! "); return ; } SSL_write(ssl, (void *)&(fstat.st_size), sizeof(fstat.st_size)); //发送文件内容 char buf[1024]; int num; num = read(fd, (void *)buf, sizeof(buf)); while(num > 0){ //发送文件内容 SSL_write(ssl, (void *)&buf, num); //读取文件内容 num = read(fd, (void *)buf, sizeof(buf)); } //关闭上传文件 close(fd); } /******************************************************************** *名称:download *参数: * ssl 客户端标志 *返回: * none *功能:下载文件 *********************************************************************/ void download(SSL *ssl){ //输入文件名称 char filename[20]; printf(" Download file: "); scanf("%s", &filename); //创建下载文件 int fd; fd = open(filename, O_RDWR | O_CREAT, 0777); if(fd == -1){ printf("Can not create file! "); return ; } //发送下载命令 char cmd = 'D'; SSL_write(ssl, (void *)&cmd, sizeof(cmd)); //发送文件名称 int namesize; namesize = strlen(filename) + 1; //加上字符串接收符 SSL_write(ssl, (void *)&namesize, sizeof(namesize)); SSL_write(ssl, (void *)&filename, namesize); //接收文件长度 int fileszie; SSL_read(ssl, &fileszie, sizeof(fileszie)); //接收文件内容 char buf[1024]; int num; num = SSL_read(ssl, (void *)buf, sizeof(buf)); while(num > 0){ //写入接收内容 write(fd, (void *)&buf, num); //是否接收结束 fileszie = fileszie - num; if(fileszie == 0){ break; } //接收文件内容 num = SSL_read(ssl, (void *)buf, sizeof(buf)); } //关闭下载文件 close(fd); } /******************************************************************** *名称:quit *参数: * ssl 客户端标志 *返回: * none *功能:退出程序 *********************************************************************/ void quit(SSL *ssl){ //发送退出命令 char cmd = 'Q'; SSL_write(ssl, (void *)&cmd, sizeof(cmd)); //清除屏幕显示 system("clear"); }