1 #include <Alert.h> 2 #include <Screen.h> 3 #include <String.h> 4 #include <View.h> 5 6 #include <stdio.h> 7 #include <string.h> 8 #include <unistd.h> 9 #include <pwd.h> 10 11 #include "LoginApp.h" 12 #include "LoginWindow.h" 13 #include "DesktopWindow.h" 14 15 #ifdef __HAIKU__ 16 #include <RosterPrivate.h> 17 #include <shadow.h> 18 #include "multiuser_utils.h" 19 #endif 20 21 22 const char *kLoginAppSig = "application/x-vnd.Haiku-Login"; 23 24 25 LoginApp::LoginApp() 26 : BApplication(kLoginAppSig), 27 fEditShelfMode(false) 28 { 29 } 30 31 32 LoginApp::~LoginApp() 33 { 34 } 35 36 37 void 38 LoginApp::ReadyToRun() 39 { 40 BScreen screen; 41 42 if (fEditShelfMode) { 43 (new BAlert("Info", "You can customize the desktop shown " 44 "behind the Login app by dropping replicants onto it.\n" 45 "\n" 46 "When you are finished just quit the application (Alt-Q).", 47 "Ok"))->Go(NULL); 48 } else { 49 BRect frame(0, 0, 400, 150); 50 frame.OffsetBySelf(screen.Frame().Width()/2 - frame.Width()/2, 51 screen.Frame().Height()/2 - frame.Height()/2); 52 fLoginWindow = new LoginWindow(frame); 53 fLoginWindow->Show(); 54 } 55 56 fDesktopWindow = new DesktopWindow(screen.Frame(), fEditShelfMode); 57 fDesktopWindow->Show(); 58 // TODO: add a shelf with Activity Monitor replicant :) 59 } 60 61 62 void 63 LoginApp::MessageReceived(BMessage *message) 64 { 65 bool reboot = false; 66 67 switch (message->what) { 68 case kAttemptLogin: 69 message->PrintToStream(); 70 TryLogin(message); 71 // TODO 72 break; 73 #ifdef __HAIKU__ 74 case kHaltAction: 75 reboot = false; 76 // FALLTHROUGH 77 case kRebootAction: 78 { 79 BRoster roster; 80 BRoster::Private rosterPrivate(roster); 81 status_t error = rosterPrivate.ShutDown(reboot, false, false); 82 if (error < B_OK) { 83 BString msg("Error: "); 84 msg << strerror(error); 85 (new BAlert("Error", msg.String(), "Ok"))->Go(); 86 } 87 break; 88 } 89 case kSuspendAction: 90 (new BAlert("Error", "Unimplemented", "Ok"))->Go(); 91 break; 92 #endif 93 default: 94 BApplication::MessageReceived(message); 95 } 96 } 97 98 99 void 100 LoginApp::ArgvReceived(int32 argc, char **argv) 101 { 102 int i; 103 for (i = 1; i < argc; i++) { 104 printf("[%d]: %s\n", i, argv[i]); 105 if (argv[i] == BString("--edit")) 106 fEditShelfMode = true; 107 } 108 } 109 110 111 void 112 LoginApp::TryLogin(BMessage *message) 113 { 114 status_t err; 115 const char *login; 116 const char *password; 117 BMessage reply(kLoginBad); 118 if (message->FindString("login", &login) == B_OK) { 119 if (message->FindString("password", &password) < B_OK) 120 password = NULL; 121 err = ValidateLogin(login, password); 122 printf("ValidateLogin: %s\n", strerror(err)); 123 if (err == B_OK) { 124 reply.what = kLoginOk; 125 message->SendReply(&reply); 126 127 if (password == NULL) 128 return; 129 130 // start a session 131 //kSetProgress 132 StartUserSession(login); 133 } else { 134 reply.AddInt32("error", err); 135 message->SendReply(&reply); 136 return; 137 } 138 139 } else { 140 reply.AddInt32("error", EINVAL); 141 message->SendReply(&reply); 142 return; 143 } 144 } 145 146 147 status_t 148 LoginApp::ValidateLogin(const char *login, const char *password) 149 { 150 struct passwd *pwd; 151 152 pwd = getpwnam(login); 153 if (!pwd) 154 return ENOENT; 155 if (strcmp(pwd->pw_name, login)) 156 return ENOENT; 157 158 if (password == NULL) { 159 // we only want to check is login exists. 160 return B_OK; 161 } 162 163 #ifdef __HAIKU__ 164 if (verify_password(pwd, getspnam(login), password)) 165 return B_OK; 166 #else 167 // for testing 168 if (strcmp(crypt(password, pwd->pw_passwd), pwd->pw_passwd) == 0) 169 return B_OK; 170 #endif 171 172 return B_PERMISSION_DENIED; 173 } 174 175 176 status_t 177 LoginApp::StartUserSession(const char *login) 178 { 179 return B_ERROR; 180 } 181 182 183 int 184 LoginApp::getpty(char *pty, char *tty) 185 { 186 static const char major[] = "pqrs"; 187 static const char minor[] = "0123456789abcdef"; 188 uint32 i, j; 189 int32 fd = -1; 190 191 for (i = 0; i < sizeof(major); i++) 192 { 193 for (j = 0; j < sizeof(minor); j++) 194 { 195 sprintf(pty, "/dev/pt/%c%c", major[i], minor[j]); 196 sprintf(tty, "/dev/tt/%c%c", major[i], minor[j]); 197 fd = open(pty, O_RDWR|O_NOCTTY); 198 if (fd >= 0) 199 { 200 return fd; 201 } 202 } 203 } 204 205 return fd; 206 } 207 208 209 210