mysu的实现
来源:互联网 发布:淘宝卖文艺女装的模特 编辑:程序博客网 时间:2024/05/12 23:18
命令解释器:http://blog.csdn.net/qq_35256722/article/details/53316066
ls的实现: http://blog.csdn.net/qq_35256722/article/details/53323238
pwd和clear 的实现:http://blog.csdn.net/qq_35256722/article/details/53322604
su,切换目录的,首先切换目录 ,通过切换uid来实现的,切换uid后,我们就得到了一个表面看起来是切换的名字,但是你的gid还没切换过来,所以你还没有全部是那个用户。切换过的用户,一定是新的用户完全替换old用户,那么exec又来了。
1. struct passwd *p = getpwnam(s); 根据用户名得到更多信息,例如:id
2. struct spwd * sp = getspnam(s); //从shadow里面读出加密的密码
3.int tcgetattr(int fd, struct termios *termios_p); 把当前终端的变量信息,写到termios_p这个结构体中。
4.char *crypt(const char *key, const char *salt);加密函数:key加密的密钥是 salt,
函数分析完了,那么大体思路,
先从根据用户名获得当前用户的详细信息,从shadow里面读取该用户的密文,和用相同的密钥加密用户输入的密码后,作比较,相同开辟子进程,否则退出。
1.比较密码:
那么从shadow里面读取密文要分割用$分割,分割前两个$,一个加密方式,一个是加密的密钥,第三个那$是密文,用户输入的密码,在crypt函数的作用下,利用从shadow里面读取的密钥和加密方式,对用户所输入的密码加密,屏和系统的作比较。
2.设置密码不可见
在我们每次输入密码时,系统的密码总是什么都没有,所以我们在这里对用户输入的密码加以处理,nts.c_lflag 宏nts.c_lflag &= ~(ECHO|ICANON),将nts 的设置成不回显隐藏起来。
3.输入完成后,设置回显
在输入完成后,提取密码时,记得回显,这样子才能把密码读到,后续 可以正常工作。
代码实现:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>#include<unistd.h>#include<sys/stat.h>#include<pwd.h>#include<shadow.h>#include<termios.h>int main(int argc,char *argv[]){char *s = "root";if(argc == 2){s = argv[1];}struct passwd *p = getpwnam(s);if(p == NULL){perror("username error");exit(0);} struct spwd * sp = getspnam(s); //从shadow里面读出加密的密码if(sp == NULL){printf("sp is error\n");exit(0);}printf("input passwd:");fflush(stdout); struct termios ts,nts;tcgetattr(0,&ts); //把当前终端端口变量的值,写入ts这个结构体中,如果这些值其后被修改,你可能通过调用函数tcsetattr 来重新配置终端接口 nts = ts;// tcflag_t c_iflag; /* input modes */nts.c_lflag &= ~(ECHO|ICANON); c_iflag 的宏 // ECHO 输入字符串的本地回显功能 // ICANON 启用标准输入处理 /*TCSANOW 立即对值进行修改。 TCSADRAIN 等当前的输出完成后再对值进行后,修改 TCSAFLUSH 等当前的输出完成后再对值进行修改,但丢弃还未从read调用返回的当前可用的任何输入。*/tcsetattr(0,TCSANOW,&nts); //密码隐藏char buff[128] = {0};int j = 0;char ch;while((ch=getchar()) !='\n'){buff[j++] = ch;}//fgets(buff,128,stdin);//buff[strlen(buff)-1] = 0;char lt[128]= {0};int i = 0;int num = 0;tcsetattr(0,TCSANOW,&ts); //密码回显for(;i < strlen(sp->sp_pwdp);i ++){if(sp->sp_pwdp[i] == '$'){num ++;if(num ==3){break;}}lt[i] = sp->sp_pwdp[i];}char *fg = crypt(buff,lt); //加密函数if(strcmp(fg,sp->sp_pwdp) != 0) //采用相同的密钥来加密,最后来比较密文就可以了{printf("fg error\n");exit(0);}printf("succes!\n");pid_t pid = fork();assert(pid != -1);if(pid == 0){setuid(p->pw_uid);setgid(p->pw_gid);setenv("HOME",p->pw_dir,1);//加上u+s 无论谁调起来,调起来就变成来rootexecl(p->pw_shell,p->pw_shell,(char*)0);//启动当前的终端perror("exec error");exit(0);}wait(NULL);}
- mysu的实现
- Linux环境下模拟shell终端:mybash、mysu、myclear
- 三子棋的实现的实现的实现
- JAVA实现的时钟实现
- 模态框的的实现
- 杀毒软件的简单实现的简单实现
- android的实现电话号码的实现
- 音频的实现音乐声音的实现
- malloc的实现、内存池的实现
- 异形窗体的实现
- 个性化的分页实现
- ASP数据库连接的实现
- Struts单选框的实现
- 梅西迭代算法的实现
- 翻页功能的实现
- Struts,MVC 的实现
- 实现JavaScript的继承
- 接口的显示实现
- 关于开源资料的寻找,避免重复造轮子:
- yii2 cookie
- ES:cluster.routing.allocation.disk.watermark.low
- Java Concurrency in Practice :基础知识(重排序与可见性)
- struts功能简要汇总
- mysu的实现
- ubuntu忘记忘记密码并恢复
- 用 Xcode 7 建立依赖其它第三方库静态库
- apache的ftpServer安装步骤:
- 通过rpm查看软件安装的目录步骤
- 学习一些陌生组件的套路:
- 编码
- 一些自成系统、完备的博客教程
- linux的hostname的问题: