1 /*
2  * The Spread Toolkit.
3  *
4  * The contents of this file are subject to the Spread Open-Source
5  * License, Version 1.0 (the ``License''); you may not use
6  * this file except in compliance with the License.  You may obtain a
7  * copy of the License at:
8  *
9  * http://www.spread.org/license/
10  *
11  * or in the file ``license.txt'' found in this distribution.
12  *
13  * Software distributed under the License is distributed on an AS IS basis,
14  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15  * for the specific language governing rights and limitations under the
16  * License.
17  *
18  * The Creators of Spread are:
19  *  Yair Amir, Michal Miskin-Amir, Jonathan Stanton, John Schultz.
20  *
21  *  Copyright (C) 1993-2012 Spread Concepts LLC <info@spreadconcepts.com>
22  *
23  *  All Rights Reserved.
24  *
25  * Major Contributor(s):
26  * ---------------
27  *    Ryan Caudy           rcaudy@gmail.com - contributions to process groups.
28  *    Claudiu Danilov      claudiu@acm.org - scalable wide area support.
29  *    Cristina Nita-Rotaru crisn@cs.purdue.edu - group communication security.
30  *    Theo Schlossnagle    jesus@omniti.com - Perl, autoconf, old skiplist.
31  *    Dan Schoenblum       dansch@cnds.jhu.edu - Java interface.
32  *
33  */
34 
35 
36 
37 
38 #include <string.h>
39 #include "arch.h"
40 #include "spread_params.h"
41 #include "session.h"
42 #include "configuration.h"
43 #include "spu_events.h"
44 #include "status.h"
45 #include "log.h"
46 #include "spu_alarm.h"
47 
48 #ifndef ARCH_PC_WIN95
49 #include <grp.h>
50 #include <pwd.h>
51 #include <unistd.h>
52 #include <sys/types.h>
53 #include <sys/stat.h>
54 #endif
55 
56 #ifdef	ARCH_PC_WIN95
57 
58 #include	<winsock.h>
59 
60 WSADATA		WSAData;
61 
62 #endif	/* ARCH_PC_WIN95 */
63 
64 static	char		*My_name;
65 static	char		My_name_buf[80];
66 static	char		Config_file[80];
67 static	int		Log;
68 
69 static  const char            Spread_build_date[] = SPREAD_BUILD_DATE;
70 
71 static	void	Invalid_privilege_decrease(char *user, char *group);
72 static	void	Usage(int argc, char *argv[]);
73 
74 /* auth-null.c: */
75 void null_init(void);
76 /* auth-ip.c: */
77 void ip_init(void);
78 /* acp-permit.c: */
79 void permit_init(void);
80 
main(int argc,char * argv[])81 int main(int argc, char *argv[])
82 {
83 #ifdef	ARCH_PC_WIN95
84 	int	ret;
85 #endif
86 
87 #ifndef ARCH_PC_WIN95
88 	struct group  *grp;
89 	struct passwd *pwd;
90 #endif
91 
92 	Alarm_set_types( CONF_SYS );
93         Alarm_set_priority( SPLOG_INFO );
94 
95 	Alarmp( SPLOG_PRINT, SYSTEM, "/===========================================================================\\\n");
96 	Alarmp( SPLOG_PRINT, SYSTEM, "| The Spread Toolkit.                                                       |\n");
97 	Alarmp( SPLOG_PRINT, SYSTEM, "| Copyright (c) 1993-2012 Spread Concepts LLC                               |\n");
98 	Alarmp( SPLOG_PRINT, SYSTEM, "| All rights reserved.                                                      |\n");
99 	Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
100 	Alarmp( SPLOG_PRINT, SYSTEM, "| The Spread toolkit is licensed under the Spread Open-Source License.      |\n");
101 	Alarmp( SPLOG_PRINT, SYSTEM, "| You may only use this software in compliance with the License.            |\n");
102 	Alarmp( SPLOG_PRINT, SYSTEM, "| A copy of the license can be found at http://www.spread.org/license       |\n");
103         Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
104         Alarmp( SPLOG_PRINT, SYSTEM, "| This product uses software developed by Spread Concepts LLC for use       |\n");
105         Alarmp( SPLOG_PRINT, SYSTEM, "| in the Spread toolkit. For more information about Spread,                 |\n");
106         Alarmp( SPLOG_PRINT, SYSTEM, "| see http://www.spread.org                                                 |\n");
107 	Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
108 	Alarmp( SPLOG_PRINT, SYSTEM, "| This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF     |\n");
109 	Alarmp( SPLOG_PRINT, SYSTEM, "| ANY KIND, either express or implied.                                      |\n");
110 	Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
111 	Alarmp( SPLOG_PRINT, SYSTEM, "| Creators:                                                                 |\n");
112 	Alarmp( SPLOG_PRINT, SYSTEM, "|    Yair Amir             yairamir@cs.jhu.edu                              |\n");
113 	Alarmp( SPLOG_PRINT, SYSTEM, "|    Michal Miskin-Amir    michal@spreadconcepts.com                        |\n");
114 	Alarmp( SPLOG_PRINT, SYSTEM, "|    Jonathan Stanton      jstanton@gwu.edu                                 |\n");
115         Alarmp( SPLOG_PRINT, SYSTEM, "|    John Schultz          jschultz@spreadconcepts.com                      |\n");
116 	Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
117 	Alarmp( SPLOG_PRINT, SYSTEM, "| Major Contributors:                                                       |\n");
118         Alarmp( SPLOG_PRINT, SYSTEM, "|    Ryan Caudy           rcaudy@gmail.com - contribution to process groups.|\n");
119         Alarmp( SPLOG_PRINT, SYSTEM, "|    Claudiu Danilov      claudiu@acm.org - scalable, wide-area support.    |\n");
120         Alarmp( SPLOG_PRINT, SYSTEM, "|    Cristina Nita-Rotaru crisn@cs.purdue.edu - GC security.                |\n");
121         Alarmp( SPLOG_PRINT, SYSTEM, "|    Theo Schlossnagle    jesus@omniti.com - Perl, autoconf, old skiplist.  |\n");
122 	Alarmp( SPLOG_PRINT, SYSTEM, "|    Dan Schoenblum       dansch@cnds.jhu.edu - Java interface.             |\n");
123 	Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
124 	Alarmp( SPLOG_PRINT, SYSTEM, "| Special thanks to the following for discussions and ideas:                |\n");
125 	Alarmp( SPLOG_PRINT, SYSTEM, "|    Ken Birman, Danny Dolev, Jacob Green, Mike Goodrich, Ben Laurie,       |\n");
126         Alarmp( SPLOG_PRINT, SYSTEM, "|    David Shaw, Gene Tsudik, Robbert VanRenesse.                           |\n");
127 	Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
128         Alarmp( SPLOG_PRINT, SYSTEM, "| Partial funding provided by the Defense Advanced Research Project Agency  |\n");
129         Alarmp( SPLOG_PRINT, SYSTEM, "| (DARPA) and the National Security Agency (NSA) 2000-2004. The Spread      |\n");
130         Alarmp( SPLOG_PRINT, SYSTEM, "| toolkit is not necessarily endorsed by DARPA or the NSA.                  |\n");
131         Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
132 	Alarmp( SPLOG_PRINT, SYSTEM, "| For a full list of contributors, see Readme.txt in the distribution.      |\n");
133 	Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
134 	Alarmp( SPLOG_PRINT, SYSTEM, "| WWW:     www.spread.org     www.spreadconcepts.com                        |\n");
135 	Alarmp( SPLOG_PRINT, SYSTEM, "| Contact: info@spreadconcepts.com                                          |\n");
136 	Alarmp( SPLOG_PRINT, SYSTEM, "|                                                                           |\n");
137 	Alarmp( SPLOG_PRINT, SYSTEM, "| Version %d.%02d.%02d Built %-17s                                   |\n",
138 		(int)SP_MAJOR_VERSION, (int)SP_MINOR_VERSION, (int)SP_PATCH_VERSION, Spread_build_date );
139 	Alarmp( SPLOG_PRINT, SYSTEM, "\\===========================================================================/\n");
140 
141 	Usage( argc, argv );
142 
143 #ifdef	ARCH_PC_WIN95
144 
145 	ret = WSAStartup( MAKEWORD(1,1), &WSAData );
146 	if( ret != 0 )
147             Alarmp( SPLOG_FATAL, NETWORK, "Spread: winsock initialization error %d\n", ret );
148 
149 #endif	/* ARCH_PC_WIN95 */
150 
151         /* initialize each valid authentication protocol */
152         null_init();
153         ip_init();
154 #ifdef  ENABLE_PASSWORD
155         pword_init();
156 #endif
157         permit_init();
158 
159         /* Initialize Access Control & Authentication */
160         Acm_init();
161 
162 	Conf_init( Config_file, My_name );
163 
164 	E_init();
165 
166 #ifndef	ARCH_PC_WIN95
167         /* Verify that unix socket dir is safe if runing as root user */
168         if (geteuid() == (uid_t) 0) {
169             struct stat usock_stat;
170             Alarmp( SPLOG_INFO, SECURITY, "Spread is running as root so check file locations\n");
171             if (stat( SP_UNIX_SOCKET, &usock_stat)) {
172                 Alarmp( SPLOG_FATAL, SECURITY, "Spread unable to stat the unix domain socket dir (%s). Please verify the selected directory and restart the daemon\n", SP_UNIX_SOCKET );
173                 exit( 0 );
174             }
175 
176             if ( (usock_stat.st_mode & S_IWOTH) || !(usock_stat.st_uid == (uid_t) 0) )
177                 Alarmp( SPLOG_WARNING, PRINT, "Spread: SECURITY RISK! running as root, but unix domain socket is not in a root-only writable directory. May risk denial of service or malicious deletion of unexpected file in directory: %s\n", SP_UNIX_SOCKET );
178 	}
179 #endif
180 
181 	Sess_init();
182 
183 	Stat_init();
184 	if( Log ) Log_init();
185 
186 #ifndef	ARCH_PC_WIN95
187 
188 	/* Yupp, we're paranoid */
189 
190 	if (geteuid() != (uid_t) 0) {
191             Alarmp( SPLOG_WARNING, SECURITY, "Spread: not running as root, won't chroot\n" );
192 	}
193 	else if ( (grp = getgrnam(Conf_get_group())) == NULL
194                   || (pwd = getpwnam(Conf_get_user())) == NULL ) {
195             Invalid_privilege_decrease(Conf_get_user(), Conf_get_group());
196 	}
197 	else if (chdir(Conf_get_runtime_dir()) < 0
198                   || chroot(Conf_get_runtime_dir()) < 0 ) {
199             Alarmp( SPLOG_FATAL, SECURITY, "Spread: FAILED chroot to '%s'\n",
200                    Conf_get_runtime_dir() );
201 	}
202 	else if ( setgroups(1, &grp->gr_gid) < 0
203                   || setgid(grp->gr_gid) < 0
204                   || setuid(pwd->pw_uid) < 0) {
205             Invalid_privilege_decrease(Conf_get_user(), Conf_get_group());
206 	} else {
207             Alarmp( SPLOG_INFO, SECURITY, "Spread: setugid and chroot successeful\n" );
208 	}
209 
210 #endif	/* ARCH_PC_WIN95 */
211 
212 	E_handle_events();
213 
214 	return 0;
215 }
216 
Print_help(void)217 static  void    Print_help(void)
218 {
219     Alarmp( SPLOG_FATAL, SYSTEM, "Usage: spread\n%s\n%s\n%s\n",
220            "\t[-l y/n]          : print log",
221            "\t[-n <proc name>]  : force computer name",
222            "\t[-c <file name>]  : specify configuration file" );
223 }
224 
225 
Invalid_privilege_decrease(char * user,char * group)226 static	void	Invalid_privilege_decrease(char *user, char *group)
227 {
228     Alarmp( SPLOG_FATAL, SECURITY, "Spread: FAILED privilege drop to user/group "
229            "'%s/%s' (defined in spread.conf or spread_params.h)\n",
230            user, group );
231 }
232 
Usage(int argc,char * argv[])233 static	void	Usage(int argc, char *argv[])
234 {
235 	My_name = 0; /* NULL */
236 	Log	= 0;
237 	strcpy( Config_file, "spread.conf" );
238 
239 	while( --argc > 0 )
240 	{
241 		argv++;
242 
243 		if( !strncmp( *argv, "-n", 2 ) )
244 		{
245                         if (argc < 2) Print_help();
246 			if( strlen( argv[1] ) > MAX_PROC_NAME-1 ) /* -1 for the null */
247                               Alarmp( SPLOG_FATAL, SYSTEM, "Usage: proc name %s too long\n",
248 					argv[1] );
249 
250 			memcpy( My_name_buf, argv[1], strlen( argv[1] ) );
251 			My_name = My_name_buf;
252 
253 			argc--; argv++;
254 
255 		}else if( !strncmp( *argv, "-c", 2 ) ){
256                         if (argc < 2) Print_help();
257 			strcpy( Config_file, argv[1] );
258 
259 			argc--; argv++;
260 
261 		}else if( !strncmp( *argv, "-l", 2 ) ){
262                         if (argc < 2) Print_help();
263 			if( !strcmp( argv[1], "y" ) )
264 				Log = 1;
265 			else if( !strcmp( argv[1], "n" ) )
266 				Log = 0;
267 			else Print_help();
268 
269 			argc--; argv++;
270 
271 		}else{
272                         Print_help();
273 		}
274 	}
275 }
276