#include #include #include #include #include #include #include #include #include "LoginApp.h" #include "LoginWindow.h" #include "DesktopWindow.h" #ifdef __HAIKU__ #include #include #include "multiuser_utils.h" #endif const char *kLoginAppSig = "application/x-vnd.Haiku-Login"; LoginApp::LoginApp() : BApplication(kLoginAppSig), fEditShelfMode(false) { } LoginApp::~LoginApp() { } void LoginApp::ReadyToRun() { BScreen screen; if (fEditShelfMode) { (new BAlert("Info", "You can customize the desktop shown " "behind the Login app by dropping replicants onto it.\n" "\n" "When you are finished just quit the application (Alt-Q).", "Ok"))->Go(NULL); } else { BRect frame(0, 0, 400, 150); frame.OffsetBySelf(screen.Frame().Width()/2 - frame.Width()/2, screen.Frame().Height()/2 - frame.Height()/2); fLoginWindow = new LoginWindow(frame); fLoginWindow->Show(); } fDesktopWindow = new DesktopWindow(screen.Frame(), fEditShelfMode); fDesktopWindow->Show(); // TODO: add a shelf with Activity Monitor replicant :) } void LoginApp::MessageReceived(BMessage *message) { bool reboot = false; switch (message->what) { case kAttemptLogin: message->PrintToStream(); TryLogin(message); // TODO break; #ifdef __HAIKU__ case kHaltAction: reboot = false; // FALLTHROUGH case kRebootAction: { BRoster roster; BRoster::Private rosterPrivate(roster); status_t error = rosterPrivate.ShutDown(reboot, false, false); if (error < B_OK) { BString msg("Error: "); msg << strerror(error); (new BAlert("Error", msg.String(), "Ok"))->Go(); } break; } case kSuspendAction: (new BAlert("Error", "Unimplemented", "Ok"))->Go(); break; #endif default: BApplication::MessageReceived(message); } } void LoginApp::ArgvReceived(int32 argc, char **argv) { int i; for (i = 1; i < argc; i++) { printf("[%d]: %s\n", i, argv[i]); if (argv[i] == BString("--edit")) fEditShelfMode = true; } } void LoginApp::TryLogin(BMessage *message) { status_t err; const char *login; const char *password; BMessage reply(kLoginBad); if (message->FindString("login", &login) == B_OK) { if (message->FindString("password", &password) < B_OK) password = NULL; err = ValidateLogin(login, password); printf("ValidateLogin: %s\n", strerror(err)); if (err == B_OK) { reply.what = kLoginOk; message->SendReply(&reply); if (password == NULL) return; // start a session //kSetProgress StartUserSession(login); } else { reply.AddInt32("error", err); message->SendReply(&reply); return; } } else { reply.AddInt32("error", EINVAL); message->SendReply(&reply); return; } } status_t LoginApp::ValidateLogin(const char *login, const char *password) { struct passwd *pwd; pwd = getpwnam(login); if (!pwd) return ENOENT; if (strcmp(pwd->pw_name, login)) return ENOENT; if (password == NULL) { // we only want to check is login exists. return B_OK; } #ifdef __HAIKU__ if (verify_password(pwd, getspnam(login), password)) return B_OK; #else // for testing if (strcmp(crypt(password, pwd->pw_passwd), pwd->pw_passwd) == 0) return B_OK; #endif return B_PERMISSION_DENIED; } status_t LoginApp::StartUserSession(const char *login) { return B_ERROR; } int LoginApp::getpty(char *pty, char *tty) { static const char major[] = "pqrs"; static const char minor[] = "0123456789abcdef"; uint32 i, j; int32 fd = -1; for (i = 0; i < sizeof(major); i++) { for (j = 0; j < sizeof(minor); j++) { sprintf(pty, "/dev/pt/%c%c", major[i], minor[j]); sprintf(tty, "/dev/tt/%c%c", major[i], minor[j]); fd = open(pty, O_RDWR|O_NOCTTY); if (fd >= 0) { return fd; } } } return fd; }