Beispiel #1
0
bool XProcess::startXSession(){
  //Returns true if the session can continue, or false if it needs to be closed down
  qDebug() << "Starting X Session:" << xuser << xcmd << xhome << xde << VT;
  //Check that the necessary info to start the session is available
  if( xuser.isEmpty() || xcmd.isEmpty() || xhome.isEmpty() || xde.isEmpty() ){
    emit InvalidLogin();  //Make sure the GUI knows that it was a failure
    return true;
  }
  //Backend::log("Starting up Desktop environment ("+xcmd+") as user ("+xuser+")");

  //Check for PAM username/password validity
  if( !pam_checkPW() ){ emit InvalidLogin(); pam_shutdown(); return true; }

  //Make sure the user is added to any required groups
  QStringList cgroups = Backend::runShellCommand("id -nG "+xuser).join("").split(" "); //current groups
  if(!cgroups.contains("video")){ Backend::runShellCommand("pw group mod video -m "+xuser); } //add user to video group (required for GPU access)

  //If this has a special device password, mount the personacrypt device
  if( !xanonlogin && !xdevpass.isEmpty() ){ //&& Backend::getAvailablePersonaCryptUsers().contains(xuser) ){
    Backend::log(" - PersonaCrypt Login Detected");
    if( !Backend::MountPersonaCryptUser(xuser, xdevpass) ){
      //Could not mount the personacrypt device (invalid password?)
      xdevpass.clear(); //clear the invalid password
      emit InvalidLogin(); pam_shutdown(); return true;
    }else{
      //overwrite the password in memory, but leave it flagged (not empty)
      if(DEBUG){ qDebug() << "Mounted PersonaCrypt Device"; }
      xdevpass.clear();
      xdevpass = "******";
    }
  }

  //Save the current user/desktop as the last login
  Backend::saveLoginInfo(xuser, xhome, xde);

  // Get the users uid/gid information
  struct passwd *pw;
  int uid;
  char *ok;

  if (!(pw = getpwnam(xuser.toLatin1()))) {
      uid = strtol(xuser.toLatin1(), &ok, 10);
      if (!(pw = getpwuid(uid))) {
          return false;
      }
  }

  //Emit the last couple logs before dropping privileges
  Backend::log("Starting session:");
  Backend::log(" - Session Log: ~/.pcdm-startup.log");
  QProcess::execute("killall compton");
  //For sanity's sake, ensure that the ZFS mountpoint are all available first
  if(QFile::exists("/sbin/zfs")){
    QProcess::execute("zfs mount -a"); //just to ensure the user's home dir is actually mounted
  }
  //Check/create the user's home-dir before dropping privs
  if(!QFile::exists(xhome)){
    qDebug() << "No Home dir found - populating...";
    QString hmcmd = "pw usermod "+xuser+" -m";
    QProcess::execute(hmcmd);
  }
  //If this is an anonymous login, create the blank home-dir on top
  if(xanonlogin){
    if(DEBUG){ qDebug() << " - Stealth Session selected"; }
    QProcess::execute("personacrypt tempinit "+xuser+" 10G"); //always use 10GB blank dir
  }

  // Get the environment before we drop priv
  this->setProcessEnvironment( QProcessEnvironment::systemEnvironment() ); //current environment

  //Now allow this user access to the Xserver
  QString xhostcmd = "xhost si:localuser:"******"/tmp/pcdm-session."+VT+".XXXXXX");
  if ( ! tFile->open() )
     return false;

  QTextStream tOut(tFile);

  // Configure the DE startup command
  if(QFile::exists("/usr/local/bin/dbus-launch") && !xcmd.contains("lumina-desktop") ){
    cmd.append("dbus-launch --exit-with-session "+xcmd);
  }else{
    cmd.append(xcmd);
  }

  QString tUid, tGid, logFile;
  tUid.setNum(pw->pw_uid);
  tGid.setNum(pw->pw_gid);
  logFile=xhome + "/.pcdm-startup.log";

  // Locate the auth file
  QString authfile = qgetenv("XAUTHORITY");
  if ( authfile.isEmpty() )
    authfile = xhome + "/.Xauthority";

  //Need to run a couple commands in sequence: so put them in a script file
  tOut << "#!/bin/sh\n\n";

  QString PICOCLIENT = qgetenv("PICO_CLIENT_LOGIN");
  QString PICOHOME = qgetenv("PICO_CLIENT_HOME");
  if ( ! PICOCLIENT.isEmpty() && ! PICOHOME.isEmpty() ) {
    // Change ownership on the Xauthority file for PICO usage
    tOut << "rm "+authfile+"\n";
    tOut << "ln -fs "+PICOHOME+"/.Xauthority "+authfile+"\n";
    QString PICOPULSE = qgetenv("PICO_PULSE_COOKIE");
    // Check if PULSE is enabled
    if ( ! PICOPULSE.isEmpty() ) {
      tOut << "mkdir -p "+xhome+"/.config/pulse 2>/dev/null\n";
      tOut << "cp "+PICOPULSE+" "+xhome+"/.config/pulse/cookie\n";
      tOut << "chown "+tUid+":"+tGid+" " +xhome+"/.config/pulse/cookie\n";
    }
    QProcess::execute("chown "+tUid+" "+PICOHOME+"/.Xauthority"); // Change ownership on the pico login
  } else {
    // Change ownership on the Xauthority file
    QProcess::execute("chown "+tUid+":"+tGid+" "+authfile);
  }

  tOut << Backend::resetKbdCmd() + "\n"; //do this before sourcing .xprofile - in case there is a user-override set there
  tOut << "if [ -e '"+xhome+"/.xprofile' ] ; then\n";
  tOut << "  chmod 755 "+xhome+"/.xprofile\n";
  tOut << "  . "+xhome+"/.xprofile\n";
  tOut << "fi\n";
  tOut << cmd + "\n"; //+ " >" + xhome+ "/.pcdm-startup.log" + " 2>" + xhome + "/.pcdm-startup.log\n";
  tOut << "exit $?"; //Make sure we return the DE return value

  cmd = "/usr/local/share/PCDM/pcdm-session"; //+xuser+" "+tUid+" "+tGid+" "+tFile->fileName()+" "+logFile;
  QStringList cmdArgs; cmdArgs << xuser << tUid << tGid << tFile->fileName() << logFile;
  connect( this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotCleanup()) );
  tFile->setPermissions(QFile::ReadOwner | QFile::WriteOwner |QFile::ReadGroup | QFile::ReadUser | QFile::ReadOther);
  tFile->close();

  if(DEBUG){ Backend::log("Starting session with:\n" + cmd ); }
  this->start(cmd, cmdArgs);
  return true;
}
Beispiel #2
0
bool XProcess::startXSession(){
  //Returns true if the session can continue, or false if it needs to be closed down

  //Check that the necessary info to start the session is available
  if( xuser.isEmpty() || xcmd.isEmpty() || xhome.isEmpty() || xde.isEmpty() ){
    emit InvalidLogin();  //Make sure the GUI knows that it was a failure
    return true;
  }
  //Backend::log("Starting up Desktop environment ("+xcmd+") as user ("+xuser+")");
  
  //Check for PAM username/password validity
  if( !pam_checkPW() ){ emit InvalidLogin(); pam_shutdown(); return true; }

  //If this has a special device password, mount the personacrypt device
  if( !xanonlogin && !xdevpass.isEmpty() && Backend::getAvailablePersonaCryptUsers().contains(xuser) ){
    if( !Backend::MountPersonaCryptUser(xuser, xdevpass) ){ 
      //Could not mount the personacrypt device (invalid password?)
      xdevpass.clear(); //clear the invalid password
      emit InvalidLogin(); pam_shutdown(); return true; 
    }else{
      //overwrite the password in memory, but leave it flagged (not empty)
      if(DEBUG){ qDebug() << "Mounted PersonaCrypt Device"; }
      xdevpass.clear();
      xdevpass = "******"; 
    }
  }

  //Save the current user/desktop as the last login
  Backend::saveLoginInfo(xuser,xde);

  // Get the users uid/gid information
  struct passwd *pw;
  int uid;
  char *ok;

  if (!(pw = getpwnam(xuser.toLatin1()))) {
      uid = strtol(xuser.toLatin1(), &ok, 10);
      if (!(pw = getpwuid(uid))) {
          return false;
      }
  }

  //Emit the last couple logs before dropping privileges
  Backend::log("Starting session:");
  Backend::log(" - Session Log: ~/.pcdm-startup.log");
  //For sanity's sake, ensure that the ZFS mountpoint are all available first
  if(QFile::exists("/sbin/zfs")){
    QProcess::execute("zfs mount -a"); //just to ensure the user's home dir is actually mounted
  }
  //Check/create the user's home-dir before dropping privs
  if(!QFile::exists(xhome)){
    qDebug() << "No Home dir found - populating...";
    QString hmcmd = "pw usermod "+xuser+" -m";
    QProcess::execute(hmcmd);
  }
  //If this is an anonymous login, create the blank home-dir on top
  if(xanonlogin){
    if(DEBUG){ qDebug() << " - Stealth Session selected"; }
    QProcess::execute("personacrypt tempinit "+xuser+" 10G"); //always use 10GB blank dir
  }
  
  // Get the environment before we drop priv
  this->setProcessEnvironment( QProcessEnvironment::systemEnvironment() ); //current environment

  //Now allow this user access to the Xserver
  QString xhostcmd = "xhost si:localuser:"******"/usr/local/bin/dbus-launch")){
    cmd.append("dbus-launch --exit-with-session "+xcmd);
  }
  //Need to run a couple commands in sequence: so put them in a script file
  tOut << "#!/bin/sh\n\n";
  tOut << "if [ -e '"+xhome+"/.xprofile' ] ; then\n";
  tOut << "  chmod 755 "+xhome+"/.xprofile\n";
  tOut << "  . "+xhome+"/.xprofile\n";
  tOut << "fi\n";
  tOut << cmd + "\n"; //+ " >" + xhome+ "/.pcdm-startup.log" + " 2>" + xhome + "/.pcdm-startup.log\n";
  tOut << "exit $?"; //Make sure we return the DE return value

  QString tUid, tGid, logFile;
  tUid.setNum(pw->pw_uid);
  tGid.setNum(pw->pw_gid);
  logFile=xhome + "/.pcdm-startup.log";
  cmd = "/usr/local/share/PCDM/pcdm-session "+xuser+" "+tUid+" "+tGid+" "+tFile->fileName()+" "+logFile;
  connect( this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotCleanup()) );
  tFile->setPermissions(QFile::ReadOwner | QFile::WriteOwner |QFile::ReadGroup | QFile::ReadUser | QFile::ReadOther);
  tFile->close();

  if(DEBUG){ Backend::log("Starting session with:\n" + cmd ); }
  this->start(cmd);
  return true;
}