Esempio n. 1
0
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));
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/*
 * 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;
}
Esempio n. 4
0
/****************************************************************************
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
}
Esempio n. 5
0
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;
        }
    }
}