xref: /haiku/src/apps/login/LoginApp.cpp (revision 0efb25854aaf4a3a2da429d3d1c43cf15837970b)
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