bool user_switch(const char* user, const char* pass) { char shell[256]; char homedir[256]; char uidString[256] = {0}; long handle; gid_t gid; uid_t uid; if (user == NULL) { logError("Unable to start a pam session with a null user"); return false; } handle = pam_auth("su", user, pass); if (handle == 0) { logWarn("Authentication failed for user '%s'", user); return false; } if (!pam_startSession(handle)) { logWarn("Failed to start a session with the user '%s'", user); return false; } if (! pam_setEnv(handle)) { logWarn("Failed to customize user environment for the user '%s'", user); return false; } if (! user_getINFO(user, &gid, &uid, shell, homedir)) { logError("Unable to get user information"); return false; } str_sprintf(uidString, "%d", uid); setenv("SHELL", shell, 1); setenv("PATH", "/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin", 1); setenv("UID", uidString, 1); setenv("USER", user, 1); setenv("HOME", homedir, 1); return (user_setGID(gid) && user_setGroup(user, gid) && fs_setCurrentDir(homedir) && user_setUID(uid)); }
static void httpd_handle_input(void) { char *ptr = (char *) uip_appdata; #ifdef HTTPD_AUTH_SUPPORT char *start_ptr; if (STATE->header_reparse) { printf("reparse next part of the header\n"); goto start_auth; } #endif /* HTTPD_AUTH_SUPPORT */ if (uip_len < 10) { printf("httpd: received request to short (%d bytes).\n", uip_len); STATE->handler = httpd_handle_400; return; } #ifdef HTTPD_SOAP_SUPPORT if (strncasecmp_P(uip_appdata, PSTR("POST /soap"), 10) == 0) { soap_initialize_context(&STATE->u.soap); STATE->handler = httpd_handle_soap; return; } #endif /* HTTPD_SOAP_SUPPORT */ if (strncasecmp_P(uip_appdata, PSTR("GET /"), 5)) { printf("httpd: received request is not GET.\n"); STATE->handler = httpd_handle_400; return; } char *filename = (char *)uip_appdata + 5; /* beyond slash */ ptr = strchr(filename, ' '); if (ptr == NULL) { printf("httpd: space after filename not found.\n"); STATE->handler = httpd_handle_400; return; } *ptr = 0; /* Terminate filename. */ /* * Successfully parsed the GET request, * possibly check authentication. */ #ifdef HTTPD_AUTH_SUPPORT ptr++; /* Increment pointer to the end of * the GET */ start_auth: start_ptr = ptr; ptr = strstr_P(ptr, PSTR("Authorization: ")); if (ptr == NULL) { if (strstr_P(start_ptr, PSTR("\r\n\r\n"))) { printf("Authorization-header not found.\n"); printf("%s\n", start_ptr); goto auth_failed; } else { ptr = start_ptr; /* Skip all Lines before the last one */ while (1) { ptr = strstr_P(start_ptr, PSTR("\r\n")); if (ptr) start_ptr = ptr + 2; else break; } if (!strncmp(start_ptr, PSTR("Authorization: "), strlen(start_ptr))) { printf("Authorization header is split over two packages, damn"); printf("%s\n", start_ptr); goto auth_failed; } else { STATE->header_reparse = 1; goto after_auth; } } } ptr += 15; /* Skip `Authorization: ' header. */ if (strncmp_P(ptr, PSTR("Basic "), 6)) { printf("auth: method is not basic.\n"); goto auth_failed; } ptr += 6; /* Skip `Basic ' string. */ char *nl = strchr(ptr, '\n'); if (nl == NULL) { printf("auth: newline not found.\n"); goto auth_failed; } *nl = 0; /* Zero-terminate BASE64-string. */ base64_str_decode(ptr); printf("auth: decoded auth string: '%s'.\n", ptr); char *password; if ((password = strchr(ptr, ':')) == NULL) { printf("auth: didn't find colon!\n"); auth_failed: httpd_cleanup(); STATE->handler = httpd_handle_401; STATE->header_reparse = 0; return; } *password = 0; password++; /* Do the PAM authentification */ pam_auth(ptr, password, &STATE->auth_state); if (STATE->header_reparse) { STATE->header_reparse = 0; return; /* We musn't open the file once again */ } after_auth: /* Dummy statement, to keep GCC happy, if HTTP_SD_DIR_SUPPORT is enabled * and thus the uint8_t definition the next statement in code. */ (void) 0; #endif /* HTTPD_AUTH_SUPPORT */ /* * Authentication is okay, now fulfill request for file * refered to in filename. */ #ifndef HTTP_SD_DIR_SUPPORT if (*filename == 0) /* No filename, override -> index */ strcpy_P(filename, PSTR(HTTPD_INDEX)); #endif #ifdef HTTP_FAVICON_SUPPORT if (strcmp_P(filename, PSTR("favicon.ico")) == 0) strcpy_P(filename, PSTR("If.ico")); #endif #ifdef ECMD_PARSER_SUPPORT uint8_t offset = strlen_P(PSTR(ECMD_INDEX "?")); if (strncmp_P(filename, PSTR(ECMD_INDEX "?"), offset) == 0) { httpd_handle_ecmd_setup(filename + offset); return; } #endif /* ECMD_PARSER_SUPPORT */ #ifdef VFS_SUPPORT /* Keep content-type identifing char. */ /* filename instead starts after last directory slash. */ char *slash = strrchr(filename, '/'); if (slash != NULL) { STATE->u.vfs.content_type = *(char *) (slash + 1); } else { STATE->u.vfs.content_type = *filename; } STATE->u.vfs.fd = vfs_open(filename); if (STATE->u.vfs.fd) { STATE->handler = httpd_handle_vfs; return; } /* Now try appending the index.html document name */ ptr = filename + strlen(filename); #ifdef HTTP_SD_DIR_SUPPORT uint8_t lastchar = ptr[-1]; #endif if (ptr[-1] != '/') *(ptr++) = '/'; strcpy_P(ptr, PSTR(HTTPD_INDEX)); STATE->u.vfs.fd = vfs_open(filename); if (STATE->u.vfs.fd) { STATE->handler = httpd_handle_vfs; return; } if (ptr == filename) /* Make sure not to strip initial slash. */ ptr[0] = 0; else ptr[-1] = 0; /* Strip index filename again, * including the last slash. */ #endif /* VFS_SUPPORT */ #ifdef HTTP_SD_DIR_SUPPORT if ((STATE->u.dir.handle = vfs_sd_chdir(filename - 1))) { strncpy(STATE->u.dir.dirname, filename - 1, SD_DIR_MAX_DIRNAME_LEN); STATE->u.dir.dirname[SD_DIR_MAX_DIRNAME_LEN - 1] = 0; if (lastchar != '/') { STATE->handler = httpd_handle_sd_dir_redirect; fat_close_dir(STATE->u.dir.handle); } else STATE->handler = httpd_handle_sd_dir; return; } #endif /* HTTP_SD_DIR_SUPPORT */ /* Fallback, send 404. */ STATE->handler = httpd_handle_404; }
/* * Background process -- runs with privilege. */ static void pam_server (int fd, const char *service, int verb, const struct name_value_list *name_value_list) { struct user_pass up; int command; #ifdef USE_PAM_DLOPEN static const char pam_so[] = "libpam.so"; #endif /* * Do initialization */ if (DEBUG (verb)) fprintf (stderr, "AUTH-PAM: BACKGROUND: INIT service='%s'\n", service); #ifdef USE_PAM_DLOPEN /* * Load PAM shared object */ if (!dlopen_pam (pam_so)) { fprintf (stderr, "AUTH-PAM: BACKGROUND: could not load PAM lib %s: %s\n", pam_so, dlerror()); send_control (fd, RESPONSE_INIT_FAILED); goto done; } #endif /* * Tell foreground that we initialized successfully */ if (send_control (fd, RESPONSE_INIT_SUCCEEDED) == -1) { fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [1]\n"); goto done; } /* * Event loop */ while (1) { memset (&up, 0, sizeof (up)); up.verb = verb; up.name_value_list = name_value_list; /* get a command from foreground process */ command = recv_control (fd); if (DEBUG (verb)) fprintf (stderr, "AUTH-PAM: BACKGROUND: received command code: %d\n", command); switch (command) { case COMMAND_VERIFY: if (recv_string (fd, up.username, sizeof (up.username)) == -1 || recv_string (fd, up.password, sizeof (up.password)) == -1 || recv_string (fd, up.common_name, sizeof (up.common_name)) == -1) { fprintf (stderr, "AUTH-PAM: BACKGROUND: read error on command channel: code=%d, exiting\n", command); goto done; } if (DEBUG (verb)) { #if 0 fprintf (stderr, "AUTH-PAM: BACKGROUND: USER/PASS: %s/%s\n", up.username, up.password); #else fprintf (stderr, "AUTH-PAM: BACKGROUND: USER: %s\n", up.username); #endif } if (pam_auth (service, &up)) /* Succeeded */ { if (send_control (fd, RESPONSE_VERIFY_SUCCEEDED) == -1) { fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [2]\n"); goto done; } } else /* Failed */ { if (send_control (fd, RESPONSE_VERIFY_FAILED) == -1) { fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [3]\n"); goto done; } } break; case COMMAND_EXIT: goto done; case -1: fprintf (stderr, "AUTH-PAM: BACKGROUND: read error on command channel\n"); goto done; default: fprintf (stderr, "AUTH-PAM: BACKGROUND: unknown command code: code=%d, exiting\n", command); goto done; } } done: #ifdef USE_PAM_DLOPEN dlclose_pam (); #endif if (DEBUG (verb)) fprintf (stderr, "AUTH-PAM: BACKGROUND: EXIT\n"); return; }
/**************************************************************************** core of password checking routine ****************************************************************************/ BOOL password_check(char *password) { #ifdef USE_PAM /* This falls through if the password check fails - if NO_CRYPT is defined this causes an error msg saying Warning - no crypt available - if NO_CRYPT is NOT defined this is a potential security hole as it may authenticate via the crypt call when PAM settings say it should fail. if (pam_auth(this_user,password)) return(True); Hence we make a direct return to avoid a second chance!!! */ return (pam_auth(this_user,password)); #endif #ifdef AFS_AUTH if (afs_auth(this_user,password)) return(True); #endif #ifdef DFS_AUTH if (dfs_auth(this_user,password)) return(True); #endif #ifdef KRB5_AUTH if (krb5_auth(this_user,password)) return(True); #endif #ifdef KRB4_AUTH if (krb4_auth(this_user,password)) return(True); #endif #ifdef PWDAUTH if (pwdauth(this_user,password) == 0) return(True); #endif #ifdef OSF1_ENH_SEC { BOOL ret = (strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0); if(!ret) { DEBUG(2,("password_check: OSF1_ENH_SEC failed. Trying normal crypt.\n")); ret = (strcmp((char *)crypt(password,this_salt),this_crypted) == 0); } return ret; } #endif #ifdef ULTRIX_AUTH return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0); #endif #ifdef LINUX_BIGCRYPT return(linux_bigcrypt(password,this_salt,this_crypted)); #endif #ifdef HPUX_10_TRUSTED return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0); #endif #ifdef NO_CRYPT DEBUG(1,("Warning - no crypt available\n")); return(False); #else return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0); #endif }
void newdata(void) { struct ecmd_connection_state_t *state = &uip_conn->appstate.ecmd; uint16_t diff = ECMD_INPUTBUF_LENGTH - state->in_len; if (diff > 0) { int cplen; if (uip_datalen() <= diff) cplen = uip_datalen(); else cplen = diff; memcpy(state->inbuf + state->in_len, uip_appdata, cplen); state->in_len += cplen; #ifdef DEBUG_ECMD_NET debug_printf("copied %d bytes\n", cplen); #endif } else { #ifdef DEBUG_ECMD_NET debug_printf("buffer full\n"); #endif } char *lf = memchr(state->inbuf, '\n', state->in_len); if (lf != NULL || memchr(uip_appdata, '\n', uip_datalen()) != NULL) { #ifdef DEBUG_ECMD_NET debug_printf("calling parser\n"); #endif if (lf) *lf = '\0'; else state->inbuf[ECMD_INPUTBUF_LENGTH-1] = '\0'; /* kill \r */ int l; for (l = 0; l < ECMD_INPUTBUF_LENGTH; l++) if (state->inbuf[l] == '\r') state->inbuf[l] = '\0'; /* if the first character is ! close the connection after the last * byte is sent */ uint8_t skip = 0; if (state->inbuf[0] == '!') { skip = 1; state->close_requested = 1; } #ifdef ECMD_PAM_SUPPORT if (state->pam_state == PAM_UNKOWN) { if (strncmp_P(state->inbuf + skip, PSTR("auth "), 5) != 0) { /* No authentification request */ auth_required: state->out_len = sprintf_P(state->outbuf, PSTR("authentification required\n")); memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); state->in_len = 0; return; } else { char *user = state->inbuf + skip + 5; /* "auth " */ char *pass = strchr(user + 1,' '); if (! pass) goto auth_required; *pass = 0; do { pass++; } while (*pass == ' '); char *p = strchr(pass, ' '); if (p) *p = 0; /* Do the Pam request, the pam request will cache username and * passwort if its necessary. */ pam_auth(user, pass, &state->pam_state); if (p && p[1] != 0) { /* There ist something after the PAM request */ memmove(state->inbuf, p+1, strlen(p+1) + 1); skip = 0; state->in_len = strlen(p+1); if (state->pam_state == PAM_PENDING) state->parse_again = 1; } else { state->in_len = 0; return; } } } if (state->pam_state == PAM_PENDING || state->pam_state == PAM_DENIED) return; /* Pam Subsystem promisses to change this state */ #endif /* parse command and write output to state->outbuf, reserving at least * one byte for the terminating \n */ l = ecmd_parse_command(state->inbuf + skip, state->outbuf, ECMD_OUTPUTBUF_LENGTH-1); #ifdef DEBUG_ECMD_NET debug_printf("parser returned %d\n", l); #endif /* check if the parse has to be called again */ if (is_ECMD_AGAIN(l)) { #ifdef DEBUG_ECMD_NET debug_printf("parser needs to be called again\n"); #endif state->parse_again = 1; l = ECMD_AGAIN(l); } #ifdef DEBUG_ECMD_NET debug_printf("parser really returned %d\n", l); #endif if (l > 0) { if (state->outbuf[l] != ECMD_NO_NEWLINE) state->outbuf[l++] = '\n'; state->out_len = l; } if (!state->parse_again) { #ifdef DEBUG_ECMD_NET debug_printf("clearing buffer\n"); #endif memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); state->in_len = 0; } } }