代码改变世界

thttpd源码分析

2011-11-16 17:12  Aga.J  阅读(1663)  评论(0编辑  收藏  举报

最近多了个看源码的嗜好

  main函数已经分析好了,找时间分离好代码,待续...

thttpd Web Server模块
thttpd Web Server

Chroot安全模块

chroot
  1 /*
2 chroot是一个系统调用,将程序的可见文件视图限制到当前目录及其下面的其他目录。这样其他远程user就无法访问初始目录外的文件。
3 子进程也会有这样的属性,所以CGI文件也会有这样的效果。
4 但是只有root才可以调用chroot,所以这意味程序只能由root启动,但是thttpd中最后root可以转换为其他user,也保证了这点。
5 1.限制被CHROOT的使用者所能执行的程序
6 2.防止使用者存取某些特定档案,如/etc/passwd。
7 3.防止入侵者/bin/rm -rf /。
8 4.提供Guest服务以及处罚恶意的使用者。
9 5.增进系统的安全。
10 文章:http://hi.baidu.com/alsrt/blog/item/de74f8389c36a32796ddd8be.html
11 http://hi.baidu.com/alsrt/blog/item/04ccce43711280159213c6bd.html
12 http://blog.csdn.net/hfw_1987/article/details/5362078
13 */
14 #include<pwd.h>
15 #include<sys/types.h>
16 #include<unistd.h>
17 #include<stdlib.h>
18 #include<sys/file.h>
19 #include<string.h>
20 #include<sys/types.h>
21 #include<grp.h>
22 #include<stdio.h>
23 #include<errno.h>
24
25 #define DEFAULT_USER "nobody"
26 #ifndef MAXPATHLEN
27 #define MAXPATHLEN 1024
28 #endif
29
30 void printCwd(char* cwd)
31 {
32 memset(cwd,0,sizeof(cwd));
33 (void) getcwd(cwd,sizeof(cwd)-1);
34 if(cwd[strlen(cwd)-1]!='/')
35 (void) strcat(cwd,"/");
36 printf("%s\n",cwd);
37 }
38 int main()
39 {
40 char* user=(char *)"aga"; //DEFAULT_USER
41 struct passwd* pwd;
42 uid_t uid=32767;
43 gid_t gid=32767;
44
45 //如果是root权限,获取将要托管的user的uid和pid
46 if( getuid()==0)
47 {
48 pwd=getpwnam(user);
49 if(pwd==(struct passwd*)0)
50 {
51 //error
52 printf("error pwd\n");
53 exit(1);
54 }
55 uid=pwd->pw_uid;
56 gid=pwd->pw_gid;
57 }
58
59 #ifdef USE_USER_DIR
60 if( getuid()==0)
61 {
62 if( chdir(pwd->pw_dir)<0 )
63 {
64 //error
65 printf("error chdir\n");
66 exit(1);
67 }
68 }
69 #endif
70
71 //当前工作目录
72 char cwd[MAXPATHLEN+1];
73 printCwd(cwd);
74
75 //系统的目录结构将以指定的位置作为'/'的位置
76 //作用:
77 //增加了系统安全性,新根下访问不到旧根目录和文件
78 //建立一个与原系统隔离的系统目录结构,方便用户开发
79 //引导linux系统启动以及急救系统等
80 //详细见IBM文章
81 if(chroot(cwd)<0)
82 //将当前程序的工作目录作为新的文件夹root,成功后getcwd变为"/"
83 {
84 printf("error chroot\n");
85 exit(1);
86 }
87
88 //当前的工作目录变为"/"
89 printCwd(cwd);
90
91 //在新的"/"目录下跳转到a文件夹
92 if ( chdir( "a" ) < 0 )
93 {
94 //error
95 printf("error chdir2\n,%s",strerror(errno));
96 exit( 1 );
97 }
98
99 //路径 "/a/"
100 printCwd(cwd);
101
102 //root完成chroot调用后,转换身份
103 if ( getuid() == 0 )
104 {
105 /*
106 // Set aux groups to null.
107 if ( setgroups( 0, (const gid_t*) 0 ) < 0 )
108 {
109 printf("error setgroups\n");
110 exit( 1 );
111 }
112 */
113
114 if ( setgid( gid ) < 0 )
115 {
116 printf("error setgid\n");
117 exit( 1 );
118 }
119
120 #ifdef HAVE_SETLOGIN
121 (void) setlogin( user );
122 #endif
123
124 if ( setuid( uid ) < 0 )
125 {
126 printf("error syslog\n");
127 exit( 1 );
128 }
129 }
130 }

 其他模块