組長:B10415030、黃智威
組員:B10415022、賴麒文
組員:B10415041、曾增宇
github: https://github.com/Will03/xv6-public
我們希望建構出安全多人的權限管理系統,因此我們必須在proc新增uid/gid欄位,來存放是誰使用這個process。在inode中新增ownerid, groupid, permission(權限值), attribute(屬性值),並藉由操作proc 和 inode來完成,以此來提高資料安全的方法。


1. 開機登入
使用者必須輸入帳號密碼登入系統
xv6帳號密碼
帳號: root 密碼: root id: 0
帳號: Will 密碼: pass id: 1000
帳號: Peter 密碼: good id: 1001
程序流程

2. funciotn call: su(切換帳戶)

3. function call: useradd(新增使用者)

4. process UID/GID
1. 使用者進行檔案操作

2. systemcall: chmod

3. function call: mv


1. 將檔名首字為點的檔案進行隱藏,如:.userpasswd、.nowuserid

2. log 檔: 記錄登錄資訊
.bash_history 內容

3. systemcall: chattr(改變檔案屬性)、lsattr(列出目前檔案屬性)

4. 使用隨機數的XOR來加密密碼檔的密碼
1. 可在任何資料夾下下指令
2. 路徑標示














修改
file.h
fs.h
mkfs.c
proc.c
proc.h
sh.c
syscall.c
syscall.h
sysfile.c
usys.S
sysproc.c
user.h
defs.h
cat.c
ls.c
新增
chattr.c
chmod.c
lsattr.c
login.c
mv.c
passwork.h
ps.c
su.c
useradd.c
file.h
struct inode {
uint dev; // Device number
uint inum; // Inode number
int ref; // Reference count
struct sleeplock lock; // protects everything below here
int valid; // inode has been read from disk?
short type; // copy of disk inode
short major;
short minor;
short nlink;
uint size;
uint addrs[NDIRECT+1];
short ownerid; // The ID of the user who owns the file.
short groupid; // The ID of the group who owns the file.
short permission; // The files mode e.g. 0700
short attributes;
};
fs.h
struct dinode {
short type; // File type
short major; // Major device number (T_DEV only)
short minor; // Minor device number (T_DEV only)
short nlink; // Number of links to inode in file system
uint size; // Size of file (bytes)
uint addrs[NDIRECT+1]; // Data block addresses
short ownerid; // The ID of the user who owns the file.
short groupid; // The ID of the group who owns the file.
short permission; // The files mode e.g. 0700
short attributes; // The files attributes 0 or 1
};
mkfs.c
uint
ialloc(ushort type)
{
uint inum = freeinode++;
struct dinode din;
bzero(&din, sizeof(din));
din.type = xshort(type);
din.nlink = xshort(1);
din.size = xint(0);
// Set notable defaults for our permission attributes.
din.ownerid = xshort(0);
din.groupid = xshort(0);
din.permission = xshort(777);
din.attributes = xshort(0);
winode(inum, &din);
return inum;
}
proc.c
void
ps(void)
{
struct proc *p;
//sti();
acquire(&ptable.lock);
cprintf("UID\tGID\t\t name \t pid \t state \n\n");
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
{
if(p->state == SLEEPING)
{
cprintf("%d\t%d\t\t %s \t %d \t SLEEPING\n",p->gid,p->uid,p->name,p->pid);
}
else if(p->state == RUNNING)
{
cprintf("%d\t%d\t\t %s \t %d \t RUNNING\n",p->gid,p->uid,p->name,p->pid);
}
else if(p->state == RUNNABLE)
{
cprintf("%d\t%d\t\t %s \t %d \t RUNNABLE\n",p->gid,p->uid,p->name,p->pid);
}
}
release(&ptable.lock);
cprintf("\n");
}
int
setuid(int uid,int mod){
acquire(&ptable.lock);
if(mod == 0)
myproc()->uid = uid;
else if(mod == 1)
myproc()->parent->uid = uid;
release(&ptable.lock);
return uid;
}
int
setgid(int gid , int mod){
acquire(&ptable.lock);
if(mod == 0)
myproc()->gid = gid;
else if(mod == 1)
myproc()->parent->gid = gid;
release(&ptable.lock);
return gid;
}
int
getuid(void)
{
return myproc()->uid;
}
proc.h
struct proc {
uint sz; // Size of process memory (bytes)
pde_t* pgdir; // Page table
char *kstack; // Bottom of kernel stack for this process
enum procstate state; // Process state
int pid; // Process ID
struct proc *parent; // Parent process
struct trapframe *tf; // Trap frame for current syscall
struct context *context; // swtch() here to run process
void *chan; // If non-zero, sleeping on chan
int killed; // If non-zero, have been killed
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
int uid;
int gid;
};
sh.c
int
getnowid(char *id)
{
int fd,num,now = 0;
char buf[20];
if((fd = open("/.nowuserid", O_RDONLY))>=0)
{
if((num = read(fd,buf,sizeof(buf)))>0){
for(now = 0;now<num-1;now++){
if(buf[now] < 48 || buf[now]> 57)break;
id[now] = buf[now];
}
id[now] = '\0';
close(fd);
return 0;
}
close(fd);
return -2;
}
close(fd);
return -1;
}
int
main(int argc,char *argv[])
{
username= argv[0];
char *dir=malloc(100);
static char buf[100];
int fd, flag =0;
strcpy(dir, "/home/");
strcpy(dir + strlen(dir),username);
chdir(dir);
int i=0;
int lastPos =0;
int bash;
char id[5],idbuf[10];
for(i=0;i<strlen(dir); i++)
{
path[i]=dir[i];
}
path[i]='/';
lastPos =i;
// Ensure that three file descriptors are open.
while((fd = open("console", O_RDWR)) >= 0){
if(fd >= 3){
close(fd);
break;
}
}
bash = open("/.bash_history",O_CREATE | O_RDWR);
// Read and run input commands.
while(getcmd(buf, sizeof(buf)) >= 0){
if(buf[0]!='\n'){
getnowid(id);
strcpy(idbuf,"ID: ");
strcpy(idbuf+strlen(idbuf),id);
strcpy(idbuf+strlen(idbuf)," -> ");
write(bash,idbuf,strlen(idbuf));
write(bash, buf, strlen(buf));
}
if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){
// Chdir must be called by the parent, not the child.
buf[strlen(buf)-1] = 0; // chop \n
if(strlen(path)==1 && (buf[3]=='.' && buf[4]=='.'))
{
printf(1, "cannot cd ..\n");
}
else if((flag = chdir(buf+3)) < 0){
if(flag == -2)
{
printf(2, "cannot cd %s :permission deny\n", buf+3);
}
else
printf(2, "cannot cd %s\n", buf+3);
}
else
{
if(buf[3]=='.' && buf[4] == '.')
{
path[strlen(path)-1]='\0';
while(path[lastPos]!='/')
{
path[lastPos--]='\0';
}
}
else if(buf[3]== '/' && (buf[4]== ' ' || buf[4]== '\0'))
{
path[0]='/';
int i;
for(i=1;i<strlen(path);i++)
{
path[i]=0;
}
lastPos=1;
}
else if(buf[3]=='.' && strlen(buf)==4)
{
continue;
}
else
{
int iter=3;
while(buf[iter]!='\0')
{
path[++lastPos]=buf[iter];
iter++;
}
path[++lastPos]='/';
iter=3;
}
}
continue;
}
if(fork1() == 0)
{
if(buf[0]=='\n')
{
runcmd(parsecmd(buf));
}
else
{
char p[sizeof(buf)+1];
p[0]='/';
int i=0;
while(buf[i]!='\0')
{
p[i+1]=buf[i];
i++;
}
runcmd(parsecmd(p));
}
}
wait();
}
exit();
}
syscall.c
extern int sys_chmod(void);
extern int sys_lsfstat(void);
extern int sys_chattr(void);
extern int sys_cat(void);
extern int sys_ps(void);
extern int sys_getuid(void);
extern int sys_setuid(void);
extern int sys_setgid(void);
extern int sys_mv(void);
[SYS_chmod] sys_chmod,
[SYS_lsfstat] sys_lsfstat,
[SYS_chattr] sys_chattr,
[SYS_cat] sys_cat,
[SYS_ps] sys_ps,
[SYS_getuid] sys_getuid,
[SYS_setuid] sys_setuid,
[SYS_setgid] sys_setgid,
[SYS_mv] sys_mv,
syscall.h
#define SYS_chmod 22
#define SYS_lsfstat 23
#define SYS_su 24
#define SYS_useradd 25
#define SYS_lsattr 26
#define SYS_chattr 27
#define SYS_cat 28
#define SYS_ps 29
#define SYS_setuid 30
#define SYS_setgid 31
#define SYS_getuid 32
#define SYS_mv 33
usys.S
SYSCALL(chmod)
SYSCALL(lsfstat)
SYSCALL(su)
SYSCALL(useradd)
SYSCALL(lsattr)
SYSCALL(chattr)
SYSCALL(cat)
SYSCALL(ps)
SYSCALL(getuid)
SYSCALL(setuid)
SYSCALL(setgid)
SYSCALL(mv)
user.h
int chmod(char*,int);
int lsfstat(int fd, struct stat*);
int chattr(char*,int);
int cat(char*);
int ps(void);
int setuid(int,int);
int setgid(int,int);
int getuid(void);
int mv(char*,char*);
sysfile.c
checkPermission(const struct inode *ip, int P_type)
{
int nowid,idmode = 3;
short premis = ip->permission;
short attri = ip->attributes;
if(attri && P_type==P_write)
{
return 0;
}
//use file to get uid/gid
struct inode *id;
char userid[30];
int num,now;
begin_op();
if((id = namei("/.nowuserid\0"))==0){
end_op();
return -1;
}
ilock(id);
num = readi(id,userid,0,sizeof(userid));
end_op();
iunlockput(id);
nowid = 0;
now = 0;
for(now = 0;now<num-1;now++){
if(userid[now] < 48 || userid[now]> 57)break;
nowid *=10;
nowid += (int)userid[now] - 48;
}
if(ip->ownerid == nowid || nowid == 0)
{
idmode = 1;
}
else
{
for(;now<num-1;){
nowid = 0;
now++;
for(;now<num-1 ;now++){
if(userid[now] < 48 || userid[now]> 57)break;
nowid *=10;
nowid += (int)userid[now] - 48;
}
if(ip->groupid == nowid){
idmode = 2;
break;
}
if(userid[now]!=';')break;
}
}
//use process to get uid/gid
// nowid = getuid();
// if(ip->ownerid == nowid || nowid == 0)
// {
// idmode = 1;
// }
// else if(ip->groupid == nowid){
// idmode = 2;
// }
// else {
// idmode = 3;
// }
switch(idmode)
{
case 1:
premis = premis/100;
break;
case 2:
premis = ((premis % 100) - (premis % 10))/10;
break;
case 3:
premis = premis % 10;
break;
}
switch(P_type)
{
case P_read:
if(premis>3)
return 1;
else
return 0;
break;
case P_write:
if(premis == 2 ||premis == 3 || premis == 6 || premis == 7 )
return 1;
else
return 0;
break;
case P_execute:
if(premis%2 > 0)
return 1;
else
return 0;
break;
default:
return 0;
}
}
//change the file's attribute
int
sys_chattr(void)
{
struct inode *id;
char *path;
int mod,num;
char userid[30];
int nowid,now;
begin_op();
if((id = namei("/.nowuserid\0"))==0){
end_op();
return -1;
}
ilock(id);
num = readi(id,userid,0,sizeof(userid));
end_op();
iunlockput(id);
nowid = 0;
now = 0;
begin_op();
for(now = 0;now<num-1;now++){
if(userid[now] < 48 || userid[now]> 57)break;
nowid *=10;
nowid += (int)userid[now] - 48;
}
if(argstr(0, &path) < 0 || argint(1, &mod) < 0){
end_op();
return -1;
}
if((id = namei(path))==0){
end_op();
return -2;
}
if(mod<0 || mod > 100)
{
end_op();
return -3;
}
if(nowid!=0){
end_op();
return -4;
}
ilock(id);
id->attributes = mod;
iupdate(id);
iunlockput(id);
end_op();
return mod;
}
//change the file's permission
int
sys_chmod(void)
{
struct inode *id;
char *path;
int mod,num;
char userid[30];
int nowid,now;
begin_op();
if((id = namei("/.nowuserid\0"))==0){
end_op();
return -1;
}
ilock(id);
num = readi(id,userid,0,sizeof(userid));
end_op();
iunlockput(id);
nowid = 0;
now = 0;
begin_op();
for(now = 0;now<num-1;now++){
if(userid[now] < 48 || userid[now]> 57)break;
nowid *=10;
nowid += (int)userid[now] - 48;
}
if(argstr(0, &path) < 0 || argint(1, &mod) < 0){
end_op();
return -1;
}
if((id = namei(path))==0){
end_op();
return -2;
}
if(mod<100 || mod > 777)
{
end_op();
return -3;
}
ilock(id);
if(id->ownerid != nowid)
{
iupdate(id);
iunlockput(id);
end_op();
return -4;
}
id->permission = mod;
iupdate(id);
iunlockput(id);
end_op();
return mod;
}
int
sys_cat(void)
{
char *path;
struct inode *id;
begin_op();
if(argstr(0, &path) < 0 ){
end_op();
return -1;
}
if((id = namei(path))==0){
end_op();
return -2;
}
if(checkPermission(id,P_read) == 0)
{
end_op();
return -3;
}
end_op();
return 0;
}
int
sys_mv(void)
{
char *path,*path2;
struct inode *id;
char name[DIRSIZ];
begin_op();
if(argstr(0, &path) < 0 ||argstr(1, &path2) < 0 ){
end_op();
return -1;
}
if((id = nameiparent(path,name))==0){
end_op();
return -2;
}
if(checkPermission(id,P_write) == 0)
{
end_op();
return -3;
}
end_op();
begin_op();
if((id = namei(path))==0){
end_op();
return -2;
}
if(checkPermission(id,P_read) == 0)
{
end_op();
return -3;
}
end_op();
begin_op();
if((id = nameiparent(path2,name))==0){
end_op();
return -2;
}
end_op();
if(checkPermission(id,P_write) == 0)
{
return -3;
}
return 0;
}
sysproc.c
int
sys_ps(void)
{
ps();
return 0;
}
int
sys_setuid(void)
{
int uid;
int mod;
if((argint(0, &uid) < 0))
return -1;
if((argint(1, &mod) < 0))
return -1;
return setuid(uid,mod);
}
int
sys_setgid(void)
{
int gid;
int mod;
if(argint(0, &gid) < 0 )
return -1;
if((argint(1, &mod) < 0))
return -1;
return setgid(gid,mod);
}
int
sys_getuid(void)
{
return getuid();
}
defs.h
void ps(void);
int setuid(int,int);
int setgid(int,int);
int getuid(void);
int getgid(void);
新增
chattr.c
#include "types.h"
#include "user.h"
#include "syscall.h"
int
main(int argc, char *argv[])
{
int flag = 0;
int attrmode = 0;
if(argc != 3)
{
printf(2,"chattr: You enter wrong input \nHelp: Please enter the fliename and mode\n");
exit();
}
if(!strcmp( argv[1],"-i"))
{
attrmode = 0;
}
else if(!strcmp( argv[1],"+i"))
{
attrmode = 1;
}
else
{
printf(2,"chattr: You enter wrong attrmode %s\n",argv[1]);
exit();
}
if((flag = chattr(argv[2],attrmode))>=0){
printf(2,"chattr flag = %d\n",flag);
}
else if(flag == -1)
{
printf(2,"chattr: You enter wrong input \nHelp: Please enter the fliename and mode\n");
}
else if(flag == -2)
{
printf(2,"chattr: Your input file %s is not exist\n",argv[2]);
}
else if(flag == -3)
{
printf(2,"chattr: You input mode not in the range\n");
}
else if(flag == -4)
{
printf(2,"chattr: permission deny\n");
}
exit();
}
chmod.c
#include "types.h"
#include "user.h"
#include "syscall.h"
int
main(int argc, char *argv[])
{
int flag = 0;
if(argc != 3)
{
printf(2,"chmod: You enter wrong input \nHelp: Please enter the fliename and mode\n");
exit();
}
if((flag = chmod(argv[2],atoi(argv[1])))>100){
printf(2,"chmod flag = %d\n",flag);
}
else if(flag == -1)
{
printf(2,"chmod: You enter wrong input \nHelp: Please enter the fliename and mode\n");
}
else if(flag == -2)
{
printf(2,"chmod: Your input file %s is not exist\n",argv[2]);
}
else if(flag == -3)
{
printf(2,"chmod: You input mode not in the range\n");
}
else if(flag == -4)
{
printf(2,"chattr: permission deny\n");
}
exit();
}
lsattr.c
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
char*
fmtname(char *path)
{
static char buf[DIRSIZ+1];
char *p;
// Find first character after last slash.
for(p=path+strlen(path); p >= path && *p != '/'; p--)
;
p++;
// Return blank-padded name.
if(strlen(p) >= DIRSIZ)
return p;
memmove(buf, p, strlen(p));
memset(buf+strlen(p), ' ', DIRSIZ-strlen(p));
return buf;
}
void
ls(char *path)
{
char buf[512], *p;
int fd , flag = 0;
struct dirent de;
struct stat st;
if((fd = open(path, 0)) < 0){
printf(2, "ls: cannot open %s\n", path);
return;
}
if((flag = (fstat(fd, &st))) < 0){
if(flag <= -2)
printf(2, "ls: cannot stat %s :permission deny\n", path);
else
printf(2, "ls: cannot stat %s\n", path);
close(fd);
return;
}
switch(st.type){
case T_FILE:
printf(1, "%s %d\n", fmtname(path), st.attribute);
break;
case T_DIR:
if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
printf(1, "ls: path too long\n");
break;
}
strcpy(buf, path);
p = buf+strlen(buf);
*p++ = '/';
while(read(fd, &de, sizeof(de)) == sizeof(de)){
if(de.inum == 0)
continue;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;
if(stat(buf, &st) < 0){
printf(1, "ls: cannot stat %s\n", buf);
continue;
}
printf(1, "%s %d\n", fmtname(buf), st.attribute);
}
break;
}
close(fd);
}
int
main(int argc, char *argv[])
{
int i;
if(argc < 2){
ls(".");
exit();
}
for(i=1; i<argc; i++)
ls(argv[i]);
exit();
}
login.c
#include "types.h"
#include "user.h"
#include "stat.h"
#include "fcntl.h"
#include "passwork.h"
#define MAXLEN 20
char *argv[] = { "sh", 0 };
int
CheckAccount(int fd ,int writefd, char *user , char *passwd)
{
char allWord[128];
char Auser[MAXLEN];
char AID[10];
char Apassword[MAXLEN];
char cipher[MAXLEN];
int num;
if(user[strlen(user)-1] == '\n'){
user[strlen(user)-1] = '\0';
}
if(passwd[strlen(passwd)-1] == '\n'){
passwd[strlen(passwd)-1] = '\0';
}
while((num = read(fd, allWord, sizeof(allWord))) > 0){
//printf(1,"%d\n",num);
for(int i =0;i<num;i++)
{
i = readpasswdfile(allWord,Auser,Apassword,AID,num,i);
if(i == -1)break;
encodepasswd(cipher,passwd);
if(!strcmp(user,Auser) && !strcmp(cipher,Apassword)){
if(write(writefd,AID,sizeof(AID)) <= 0)
printf(1,"error\n");
int now = 0,id = 0,mod = 0;
for(int i =0 ;AID[i]!=';'&& AID[i]!='\0';i++,now++){
id *= 10;
id += AID[i] - 48;
}
printf(2,"uid = %d gid = %d\n",setuid(id,mod),setgid(id,mod));
return 1;
}
//while(i <num && allWord[i++] != '\n');
}
}
return 0;
}
int
main(void)
{
int pid = 0,fd,writefd, wpid;
char * username;
char namebuf[MAXLEN];
char passwdbuf[MAXLEN];
char* password;
mkdir("/home/");
chmod("home",777);
while(1)
{
printf(1,"Username: ");
username = gets(namebuf, MAXLEN);
printf(1,"Password: ");
password = gets(passwdbuf, MAXLEN);
dup(0); // stdout
dup(0); // stderr
//printf(1, "init:
if((writefd = open("/.nowuserid", O_WRONLY)) < 0){
printf(1,"Login: can't open nowuserid\n");
break;
}
if((fd = open("/.userpasswd", O_RDONLY)) < 0){
printf(1,"Login: can't open Userpassword\n");
break;
}
if(CheckAccount(fd,writefd,username,password)){
close(fd);
close(writefd);
printf(2,"Hello %s, have a nice's day\n", username);
if((writefd = open("/.nowuserid", O_RDONLY)) < 0){
printf(1,"Login: can't open nowuserid\n");
break; }
char a[20];
if(read(writefd,a,sizeof(a))<=0)
printf(1,"error\n");
printf(2,"%s\n",a);
pid = fork();
if(pid < 0){
printf(1, "login: fork failed\n");
exit();
}
if(pid == 0){
char * uname[] = {username,0};
char * dirToCreate = "/home/";
strcpy(dirToCreate + strlen(dirToCreate), username);
mkdir(dirToCreate);
exec("sh", uname);
printf(1, "login: exec sh failed\n");
exit();
}
}
else{
close(fd);
close(writefd);
printf(1,"you print error username or password\n");
printf(1,"please input your account again\n");
}
close(fd);
while((wpid=wait()) >= 0 && wpid != pid)
printf(1, "zombie!\n");
}
wait();
exit();
return 0;
}
mv.c
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
#include "fcntl.h"
#define BUFFER_SIZE 256
int
main(int argc, char *argv[]){
if(argc != 3){
printf(1, "Command Error, please check the argument.\n");
exit();
}
int flag = mv(argv[1],argv[2]);
if(flag <0){
if(flag == -3){
printf(1, "mv: permission deny.\n");
}
else if(flag == -2){
printf(1, "mv: error to open the file.\n");
}
else if(flag == -1){
printf(1, "mv: error to open the file.\n");
}
exit();
}
else{
printf(1,"good\n");
}
int source = open(argv[1], 0);
if(source == -1){
printf(1, "Source file can not open.\n");
exit();
}
int distination = open(argv[2], O_WRONLY | O_CREATE);
if(distination == -1){
printf(1, "Distination file can not write, Please Contact the root.\n");
exit();
}
else if(distination == -2){
printf(1, "mv: permission deny.\n");
exit();
}
char buffer[BUFFER_SIZE];
int length = 0;
while((length = read(source, buffer, BUFFER_SIZE)) > 0)
write(distination, buffer, length);
close(source);
close(distination);
if(unlink(argv[1]) < 0)
printf(1, "Can not Delete Source file.\n");
exit();
}
passwork.h
#include "types.h"
#include "user.h"
#include "syscall.h"
#include "fcntl.h"
int
readpasswdfile(char* allWord,char* Auser,char* Apassword ,char* AID,int num,int i)
{
int now = 0;
for(;allWord[i]!=';'||i == num;i++,now++){
Auser[now] = allWord[i];
}
i++;
Auser[now] = '\0';
if(i>=num){
printf(1,"Login:AccountFile have error\n");
return -1;
}
now =0;
for(;allWord[i]!=';'||i == num;i++,now++){
Apassword[now] = allWord[i];
}
i++;
Apassword[now] = '\0';
if(i>=num){
printf(1,"Login:AccountFile have error\n");
return -1;
}
//,char* passwdkey
//Key string
for(;allWord[i]!=';'||i == num;i++,now++);
i++;
if(i>=num){
printf(1,"Login:AccountFile have error\n");
return -1;
}
now =0;
for(;allWord[i]!='\n' && allWord[i]!='\0' ;i++,now++){
AID[now] = allWord[i];
}
AID[now] = '\0';
// printf(1,"%s\n",Auser);
// printf(1,"%s\n",Apassword);
// printf(1,"%s\n",AID);
return i;
}
//set a radom string
void pseudoRandom(char key, char encodeKey[], int len) {
int i;
unsigned char ran;
unsigned char bnew;
encodeKey[0] = key;
for (i=1; i<len; i++) {
ran = (unsigned char) encodeKey[i-1];
bnew = (ran * 7) % 255;
encodeKey[i] = (char) bnew;
}
encodeKey[i] = '\0';
}
// start encrypt
void encrypt(char plan[], char cipher[], char encodeKey[], int len) {
int i;
for (i=0; i<len; i++) {
cipher[i] = plan[i] ^ encodeKey[i];
if(cipher[i]<0)cipher[i]*=-1;
cipher[i] = (cipher[i]%25)+65;
}
cipher[i] = '\0';
}
void encodepasswd(char* cipher, char* passwd)
{
char key = 0x6D;
char encodeKey[20];
pseudoRandom(key, encodeKey, strlen(passwd));
encrypt(passwd, cipher, encodeKey,strlen(passwd));
}
ps.c
#include "types.h"
#include "stat.h"
#include "user.h"
int
main()
{
ps();
wait();
exit();
return 0;
}
su.c
#include "types.h"
#include "user.h"
#include "syscall.h"
#include "fcntl.h"
#include "passwork.h"
#define MAXLEN 20
int
CheckUser( int fd,char *user , char *passwd, char *ID)
{
char allWord[128];
char Auser[MAXLEN];
char AID[MAXLEN];
char Apassword[MAXLEN];
int num = 0;
if(user[strlen(user)-1] == '\n'){
user[strlen(user)-1] = '\0';
}
while((num = read(fd, allWord, sizeof(allWord))) > 0){
for(int i =0;i<num;i++)
{
i = readpasswdfile(allWord,Auser,Apassword,AID,num,i);
if(i == -1)break;
if(!strcmp(user,Auser)){
strcpy(passwd,Apassword);
strcpy(ID,AID);
return 1;
}
}
}
return 0;
}
int
main(int argc, char *argv[])
{
int fd,writefd,flag = 0;
char *userpasswd,*user = "";
char password[MAXLEN],ID[MAXLEN];
if((writefd = open("/.nowuserid", O_WRONLY)) < 0){
printf(1,"su: can't open nowuserid\n");
exit();
}
if((fd = open("/.userpasswd", O_RDONLY)) < 0){
close(writefd);
printf(1,"su: can't open Userpassword\n");
exit();
}
if(argc == 1)
{
flag = CheckUser(fd,"root",password,ID);
strcpy(user,"root");
}
else if(argc == 2)
{
flag = CheckUser(fd, argv[1],password,ID);
strcpy(user,argv[1]);
}
else
{
close(fd);
close(writefd);
printf(2,"su: error\n");
exit();
}
if(flag == 1)
{
printf(1,"Password: ");
userpasswd = gets("password", MAXLEN);
if(userpasswd[strlen(userpasswd)-1] == '\n'){
userpasswd[strlen(userpasswd)-1] = '\0';
}
char cipher[MAXLEN];
encodepasswd(cipher,userpasswd);
if(!strcmp(cipher,password)){
if(write(writefd,ID,sizeof(ID)) <= 0)
{
printf(1,"su: write file error\n");
close(fd);
close(writefd);
exit();
}
if(write(writefd,ID,sizeof(ID)) <= 0)
printf(1,"error\n");
int now = 0,id = 0;
for(int i =0 ;ID[i]!=';'&& ID[i]!='\0';i++,now++){
id *= 10;
id += ID[i] - 48;
}
setuid(id,1);
setgid(id,1);
//printf(2,"uid = %d gid = %d\n",);
printf(2,"Welcome\n",user);
}
if(strcmp(cipher,password)!=0){
printf(2,"su: user password error\n");
}
}
else
{
printf(2,"su: no such user\n");
close(fd);
close(writefd);
exit();
}
close(fd);
close(writefd);
exit();
}
useradd.c
#include "types.h"
#include "user.h"
#include "syscall.h"
#include "fcntl.h"
#include "passwork.h"
#define MAXLEN 20
int
seachlastuserid(char* allWord,int num,char* newid)
{
int now = 0;
char AID[10];
for(int i =0;i<num;i++)
{
for(;allWord[i]!=';'||i == num;i++,now++);
i++;
if(i>=num){
printf(1,"Login:AccountFile have error\n");
return -1;
}
now =0;
for(;allWord[i]!=';'||i == num;i++,now++);
i++;
if(i>=num){
printf(1,"Login:AccountFile have error\n");
return -1;
}
now =0;
for(;allWord[i]!=';'||i == num;i++,now++);
i++;
if(i>=num){
printf(1,"Login:AccountFile have error\n");
return -1;
}
now =0;
for(;allWord[i]!=';'||i == num;i++,now++){
AID[now] = allWord[i];
}
for(;allWord[i]!='\n' && allWord[i]!='\0';i++,now++);
AID[now] = '\0';
//printf(1,"%s\n",AID);
}
int id = atoi(AID);
int number = 0;
char tem;
id+=1;
for(int n = 0;;number++)
{
n = id%10;
id/=10;
AID[number] = n+48;
if(id==0)break;
}
for(int i =0,j=number;;i++,j--)
{
if(i >= j)break;
tem = AID[i];
AID[i] = AID[j];
AID[j] = tem;
}
AID[number+1] = '\0';
strcpy(newid,AID);
return 1;
}
int main(int argc, char *argv[])
{
int fd,num,flag = 0;
char allWord[128],buf[64],newid[8],idbuf[17];
char cipher[MAXLEN];
if(argc != 3)
{
printf(2, "userpasswd: you need to input username and password\n");
exit();
}
if((fd = open("/.userpasswd", O_RDONLY)) < 0){
printf(1,"useradd: can't open Userpassword\n");
exit();
}
while((num = read(fd, allWord, sizeof(allWord))) > 0){
if(num>0){
flag = seachlastuserid(allWord,num,newid);
}
else{
printf(2,"useradd: error to read userpasswd\n");
close(fd);
exit();
}
}
if(flag >0){
printf(2,"id:%s\n",newid);
for(num = 0;newid[num] == '\0';num++);
num++;
strcpy(idbuf,newid);
strcpy(idbuf+strlen(idbuf),";");
strcpy(idbuf+strlen(idbuf),newid);
strcpy(idbuf+strlen(idbuf),"\n");
// printf(2,"%d\n",num);
// printf(2,"%s\n",idbuf);
close(fd);
if((fd = open("/.userpasswd", O_RDWR)) < 0){
printf(1,"useradd: can't open Userpassword\n");
exit();
}
if(read(fd, allWord, sizeof(allWord)) == 0){
printf(2,"useradd: error to add new user\n");
close(fd);
exit();
}
strcpy(buf,argv[1]);
strcpy(buf+strlen(buf),";");
encodepasswd(cipher,argv[2]);
strcpy(buf+strlen(buf),cipher);
strcpy(buf+strlen(buf),";0x6D;");
strcpy(buf+strlen(buf),idbuf);
printf(2,"%s",buf);
if( !write(fd, buf,strlen(buf))){
printf(2,"useradd: error to add new user\n");
}
close(fd);
}
exit();
}
利用process來得到目前user的id,這個做法可以讓此系統成為一個多人多工個環境,因為系統會根據登入時使用者的不同,使process有不同的權限。完成後我們思考如何可以讓密碼檔和其它重要的檔案變得安全。所以我們新增了幾個蠻重要linux的一些安全措施。
黃智威:
賴麒文:
曾增宇: