eperl
view release on metacpan or search on metacpan
eperl_main.c view on Meta::CPAN
if ((stat(source, &st)) != 0) {
PrintError(mode, source, NULL, NULL, "File `%s' not exists", source);
CU(mode == MODE_FILTER ? EX_IOERR : EX_OK);
}
/*
* Security Checks for the CGI modes
*/
if (mode == MODE_CGI || mode == MODE_NPHCGI) {
/*
*
* == General Security ==
*
*/
/* general security check: allowed file extension */
if (CGI_NEEDS_ALLOWED_FILE_EXT) {
allow = FALSE;
n = strlen(source);
for (i = 0; allowed_file_ext[i] != NULL; i++) {
k = strlen(allowed_file_ext[i]);
if (strcmp(source+n-k, allowed_file_ext[i]) == 0)
allow = TRUE;
}
if (!allow) {
PrintError(mode, source, NULL, NULL, "File `%s' is not allowed to be interpreted by ePerl (wrong extension!)", source);
CU(EX_OK);
}
}
/*
*
* == Perl Security ==
*
*/
/* perhaps force Taint mode */
if (CGI_MODES_FORCE_TAINTING)
fTaint = TRUE;
/* perhaps force Warnings */
if (CGI_MODES_FORCE_WARNINGS)
fWarn = TRUE;
/*
*
* == UID/GID switching ==
*
*/
/* we can only do a switching if we have euid == 0 (root) */
if (geteuid() == 0) {
fOkSwitch = TRUE;
/* get our real user id (= caller uid) */
uid = getuid();
/* security check: valid caller uid */
pw = getpwuid(uid);
if (SETUID_NEEDS_VALID_CALLER_UID && pw == NULL) {
if (DO_FOR_FAILED_STEP == STOP_AND_ERROR) {
PrintError(mode, source, NULL, NULL, "Invalid UID %d of caller", uid);
CU(EX_OK);
}
else
fOkSwitch = FALSE;
}
else {
/* security check: allowed caller uid */
if (SETUID_NEEDS_ALLOWED_CALLER_UID) {
allow = FALSE;
for (i = 0; allowed_caller_uid[i] != NULL; i++) {
if (isdigit(allowed_caller_uid[i][0]))
pw2 = getpwuid(atoi(allowed_caller_uid[i]));
else
pw2 = getpwnam(allowed_caller_uid[i]);
if (strcmp(pw->pw_name, pw2->pw_name) == 0) {
allow = TRUE;
break;
}
}
if (!allow) {
if (DO_FOR_FAILED_STEP == STOP_AND_ERROR) {
PrintError(mode, source, NULL, NULL, "UID %d of caller not allowed", uid);
CU(EX_OK);
}
else
fOkSwitch = FALSE;
}
}
}
/* security check: valid owner UID */
pw = getpwuid(st.st_uid);
if (SETUID_NEEDS_VALID_OWNER_UID && pw == NULL)
if (DO_FOR_FAILED_STEP == STOP_AND_ERROR) {
PrintError(mode, source, NULL, NULL, "Invalid UID %d of owner", st.st_uid);
CU(EX_OK);
}
else
fOkSwitch = FALSE;
else
uid = pw->pw_uid;
/* security check: valid owner GID */
gr = getgrgid(st.st_gid);
if (SETUID_NEEDS_VALID_OWNER_GID && gr == NULL)
if (DO_FOR_FAILED_STEP == STOP_AND_ERROR) {
PrintError(mode, source, NULL, NULL, "Invalid GID %d of owner", st.st_gid);
CU(EX_OK);
}
else
fOkSwitch = FALSE;
else
gid = gr->gr_gid;
/* security check: file has to stay below owner homedir */
if (fOkSwitch && SETUID_NEEDS_BELOW_OWNER_HOME) {
/* preserve current working directory */
cwd2 = getcwd(NULL, 1024);
/* determine physical homedir of owner */
pw = getpwuid(st.st_uid);
if (chdir(pw->pw_dir) == -1) {
if (DO_FOR_FAILED_STEP == STOP_AND_ERROR) {
PrintError(mode, source, NULL, NULL, "Invalid homedir ``%s'' of file owner", pw->pw_dir);
CU(EX_OK);
}
else
fOkSwitch = FALSE;
}
else {
dir_home = getcwd(NULL, 1024);
/* determine physical dir of file */
strcpy(dir_tmp, source);
if ((cp = strrchr(dir_tmp, '/')) == NULL) {
if (DO_FOR_FAILED_STEP == STOP_AND_ERROR) {
PrintError(mode, source, NULL, NULL, "Invalid script ``%s'': no absolute path", source);
CU(EX_OK);
}
else
fOkSwitch = FALSE;
}
else {
*cp = NUL;
if (chdir(dir_tmp) == -1) {
if (DO_FOR_FAILED_STEP == STOP_AND_ERROR) {
PrintError(mode, source, NULL, NULL, "Invalid script ``%s'': cannot chdir to its location", source);
CU(EX_OK);
}
else
fOkSwitch = FALSE;
}
else {
dir_script = getcwd(NULL, 1024);
/* dir_home has to be a prefix of dir_script */
if (strncmp(dir_script, dir_home, strlen(dir_home)) < 0) {
if (DO_FOR_FAILED_STEP == STOP_AND_ERROR) {
PrintError(mode, source, NULL, NULL, "Invalid script ``%s'': does not stay below homedir of owner", source);
CU(EX_OK);
}
else
fOkSwitch = FALSE;
}
free(dir_script);
}
}
free(dir_home);
}
/* restore original cwd */
chdir(cwd2);
free(cwd2);
}
if (fOkSwitch && uid != 0 && gid != 0) {
/* switch to new uid/gid */
if (((setgid(gid)) != 0) || (initgroups(pw->pw_name,gid) != 0)) {
PrintError(mode, source, NULL, NULL, "Unable to set GID %d: setgid/initgroups failed", gid);
eperl_main.c view on Meta::CPAN
setuid(uid);
#endif
#ifdef HAVE_SETEGID
setegid(uid);
#else
/* HP/UX and others eliminate the effective GID with setgid(gid) ! */
setgid(gid);
#endif
}
/* read source file into internal buffer */
if ((cpBuf = ePerl_ReadSourceFile(source, &cpBuf, &nBuf)) == NULL) {
PrintError(mode, source, NULL, NULL, "Cannot open source file `%s' for reading\n%s", source, ePerl_GetError);
CU(mode == MODE_FILTER ? EX_IOERR : EX_OK);
}
/* strip shebang prefix */
if (strncmp(cpBuf, "#!", 2) == 0) {
for (cpScript = cpBuf;
(*cpScript != ' ' && *cpScript != '\t' && *cpScript != '\n') && (cpScript-cpBuf < nBuf);
cpScript++)
;
for (cpScript = cpBuf;
*cpScript != '\n' && (cpScript-cpBuf < nBuf);
cpScript++)
;
cpScript++;
}
else
cpScript = cpBuf;
/* now set the additional env vars */
env = mysetenv(env, "SCRIPT_SRC_PATH", "%s", abspath(source));
env = mysetenv(env, "SCRIPT_SRC_PATH_FILE", "%s", filename(source));
env = mysetenv(env, "SCRIPT_SRC_PATH_DIR", "%s", abspath(dirname(source)));
if ((cpPath = getenv("PATH_INFO")) != NULL) {
if ((cpHost = getenv("SERVER_NAME")) == NULL)
cpHost = "localhost";
cpPort = getenv("SERVER_PORT");
if (strcmp(cpPort, "80") == 0)
cpPort = NULL;
sprintf(ca, "http://%s%s%s%s",
cpHost, cpPort != NULL ? ":" : "", cpPort != NULL ? cpPort : "", cpPath);
env = mysetenv(env, "SCRIPT_SRC_URL", "%s", ca);
env = mysetenv(env, "SCRIPT_SRC_URL_FILE", "%s", filename(ca));
env = mysetenv(env, "SCRIPT_SRC_URL_DIR", "%s", dirname(ca));
}
else {
env = mysetenv(env, "SCRIPT_SRC_URL", "file://%s", abspath(source));
env = mysetenv(env, "SCRIPT_SRC_URL_FILE", "%s", filename(source));
env = mysetenv(env, "SCRIPT_SRC_URL_DIR", "file://%s", abspath(source));
}
env = mysetenv(env, "SCRIPT_SRC_SIZE", "%d", nBuf);
stat(source, &st);
env = mysetenv(env, "SCRIPT_SRC_MODIFIED", "%d", st.st_mtime);
cp = ctime(&(st.st_mtime));
cp[strlen(cp)-1] = NUL;
env = mysetenv(env, "SCRIPT_SRC_MODIFIED_CTIME", "%s", cp);
env = mysetenv(env, "SCRIPT_SRC_MODIFIED_ISOTIME", "%s", isotime(&(st.st_mtime)));
if ((pw = getpwuid(st.st_uid)) != NULL)
env = mysetenv(env, "SCRIPT_SRC_OWNER", "%s", pw->pw_name);
else
env = mysetenv(env, "SCRIPT_SRC_OWNER", "unknown-uid-%d", st.st_uid);
env = mysetenv(env, "VERSION_INTERPRETER", "%s", ePerl_WebID);
env = mysetenv(env, "VERSION_LANGUAGE", "Perl/%s", AC_perl_vers);
/* optionally run the ePerl preprocessor */
if (fPP) {
/* switch to directory where script stays */
getcwd(cwd, MAXPATHLEN);
strcpy(sourcedir, source);
for (cp = sourcedir+strlen(sourcedir); cp > sourcedir && *cp != '/'; cp--)
;
*cp = NUL;
chdir(sourcedir);
/* run the preprocessor */
if ((cpBuf3 = ePerl_PP(cpScript, RememberedINC)) == NULL) {
PrintError(mode, source, NULL, NULL, "Preprocessing failed for `%s': %s", source, ePerl_PP_GetError());
CU(mode == MODE_FILTER ? EX_IOERR : EX_OK);
}
cpScript = cpBuf3;
/* switch to previous dir */
chdir(cwd);
}
/* convert bristled source to valid Perl code */
if ((cpBuf2 = ePerl_Bristled2Plain(cpScript)) == NULL) {
PrintError(mode, source, NULL, NULL, "Cannot convert bristled code file `%s' to pure HTML", source);
CU(mode == MODE_FILTER ? EX_IOERR : EX_OK);
}
cpScript = cpBuf2;
/* write buffer to temporary script file */
strcpy(perlscript, mytmpfile("ePerl.script"));
#ifndef DEBUG_ENABLED
unlink(perlscript);
#endif
if ((fp = fopen(perlscript, "w")) == NULL) {
PrintError(mode, source, NULL, NULL, "Cannot open Perl script file `%s' for writing", perlscript);
CU(mode == MODE_FILTER ? EX_IOERR : EX_OK);
}
fwrite(cpScript, strlen(cpScript), 1, fp);
fclose(fp); fp = NULL;
/* in Debug mode output the script to the console */
if (fDebug) {
if ((fp = fopen("/dev/tty", "w")) == NULL) {
PrintError(mode, source, NULL, NULL, "Cannot open /dev/tty for debugging message");
CU(mode == MODE_FILTER ? EX_IOERR : EX_OK);
}
fprintf(fp, "----internally created Perl script-----------------------------------\n");
fwrite(cpScript, strlen(cpScript)-1, 1, fp);
if (cpScript[strlen(cpScript)-1] == '\n')
fprintf(fp, "%c", cpScript[strlen(cpScript)-1]);
else
fprintf(fp, "%c\n", cpScript[strlen(cpScript)-1]);
fprintf(fp, "----internally created Perl script-----------------------------------\n");
fclose(fp); fp = NULL;
}
( run in 2.520 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )