toaruos/userspace/glogin.c
2012-09-13 00:29:29 -07:00

307 lines
6.1 KiB
C

/*
* glogin
*
* Graphical Login screen
*/
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <math.h>
#include "lib/sha2.h"
#include "lib/window.h"
#include "lib/graphics.h"
#include "lib/shmemfonts.h"
sprite_t * sprites[128];
sprite_t alpha_tmp;
gfx_context_t * ctx;
uint16_t win_width;
uint16_t win_height;
int uid = 0;
int checkUserPass(char * user, char * pass) {
/* Generate SHA512 */
char hash[SHA512_DIGEST_STRING_LENGTH];
SHA512_Data(pass, strlen(pass), hash);
/* Open up /etc/master.passwd */
FILE * passwd = fopen("/etc/master.passwd", "r");
char line[2048];
while (fgets(line, 2048, passwd) != NULL) {
line[strlen(line)-1] = '\0';
char *p, *tokens[4], *last;
int i = 0;
for ((p = strtok_r(line, ":", &last)); p;
(p = strtok_r(NULL, ":", &last)), i++) {
if (i < 511) tokens[i] = p;
}
tokens[i] = NULL;
if (strcmp(tokens[0],user) != 0) {
continue;
}
if (!strcmp(tokens[1],hash)) {
fclose(passwd);
return atoi(tokens[2]);
}
}
fclose(passwd);
return -1;
}
int center_x(int x) {
return (win_width - x) / 2;
}
int center_y(int y) {
return (win_height - y) / 2;
}
void init_sprite(int i, char * filename, char * alpha) {
sprites[i] = malloc(sizeof(sprite_t));
load_sprite(sprites[i], filename);
if (alpha) {
sprites[i]->alpha = 1;
load_sprite(&alpha_tmp, alpha);
sprites[i]->masks = alpha_tmp.bitmap;
} else {
sprites[i]->alpha = 0;
}
sprites[i]->blank = 0x0;
}
#define INPUT_SIZE 1024
char input_buffer[1024];
uint32_t input_collected = 0;
int buffer_put(char c) {
if (c == 8) {
/* Backspace */
if (input_collected > 0) {
input_collected--;
input_buffer[input_collected] = '\0';
}
return 0;
}
if (c < 10 || (c > 10 && c < 32) || c > 126) {
return 0;
}
input_buffer[input_collected] = c;
input_collected++;
input_buffer[input_collected] = '\0';
if (input_collected == INPUT_SIZE - 1) {
return 1;
}
return 0;
}
void * process_input(void * arg) {
while (1) {
}
}
uint32_t gradient_at(uint16_t j) {
float x = j * 80;
x = x / ctx->height;
return rgb(0, 1 * x, 2 * x);
}
void draw_gradient() {
for (uint16_t j = 0; j < ctx->height; ++j) {
draw_line(ctx, 0, ctx->width, j, j, gradient_at(j));
}
}
int main (int argc, char ** argv) {
while (1) {
setup_windowing();
int width = wins_globals->server_width;
int height = wins_globals->server_height;
win_width = width;
win_height = height;
init_shmemfonts();
/* Do something with a window */
window_t * wina = window_create(0,0, width, height);
assert(wina);
window_reorder (wina, 0); /* Disables movement */
ctx = init_graphics_window_double_buffer(wina);
draw_gradient();
flip(ctx);
/* Fade in */
size_t buf_size = wina->width * wina->height * sizeof(uint32_t);
char * buf = malloc(buf_size);
uint16_t fade = 0;
gfx_context_t fade_ctx;
fade_ctx.backbuffer = buf;
fade_ctx.width = wina->width;
fade_ctx.height = wina->height;
fade_ctx.depth = 32;
gfx_context_t * fc = &fade_ctx;
sprites[0] = malloc(sizeof(sprite_t));
load_sprite_png(sprites[0], "/usr/share/wallpaper.png");
draw_sprite_scaled(fc,sprites[0], 0, 0, width, height);
while (fade < 256) {
for (uint32_t y = 0; y < wina->height; y++) {
for (uint32_t x = 0; x < wina->width; x++) {
GFX(ctx, x, y) = alpha_blend(GFX(ctx, x, y), GFX(fc, x, y), rgb(fade,0,0));
}
}
flip(ctx);
fade += 10;
}
init_sprite(1, "/usr/share/bs.bmp", "/usr/share/bs-alpha.bmp");
draw_sprite_scaled(fc, sprites[1], center_x(sprites[1]->width), center_y(sprites[1]->height), sprites[1]->width, sprites[1]->height);
uint32_t i = 0;
uint32_t black = rgb(0,0,0);
uint32_t white = rgb(255,255,255);
int x_offset = 65;
int y_offset = 64;
int fuzz = 3;
set_font_size(22);
char * m_username = "Username: ";
char * m_password = "Password: ";
char msg[1024];
char username[1024] = {0};
char password[1024] = {0};
input_buffer[0] = '\0';
input_collected = 0;
uid = 0;
while (1) {
while (1) {
snprintf(msg, 1024, "%s%s", m_username, input_buffer);
/* Redraw the background by memcpy (super speedy) */
memcpy(ctx->backbuffer, buf, buf_size);
set_text_opacity(0.2);
for (int y = -fuzz; y <= fuzz; ++y) {
for (int x = -fuzz; x <= fuzz; ++x) {
draw_string(ctx, wina->width / 2 - x_offset + x, wina->height / 2 + y_offset + y, black, msg);
}
}
set_text_opacity(1.0);
draw_string(ctx, wina->width / 2 - x_offset, wina->height / 2 + y_offset, white, msg);
flip(ctx);
w_keyboard_t * kbd = NULL;
do {
kbd = poll_keyboard();
} while (!kbd);
if (kbd->key == '\n') {
free(kbd);
goto _have_username;
}
buffer_put(kbd->key);
free(kbd);
}
_have_username:
input_buffer[input_collected] = '\0';
sprintf(username, "%s", input_buffer);
input_collected = 0;
input_buffer[0] = '\0';
while (1) {
snprintf(msg, 1024, "%s", m_password);
/* Redraw the background by memcpy (super speedy) */
memcpy(ctx->backbuffer, buf, buf_size);
set_text_opacity(0.2);
for (int y = -fuzz; y <= fuzz; ++y) {
for (int x = -fuzz; x <= fuzz; ++x) {
draw_string(ctx, wina->width / 2 - x_offset + x, wina->height / 2 + y_offset + y, black, msg);
}
}
set_text_opacity(1.0);
draw_string(ctx, wina->width / 2 - x_offset, wina->height / 2 + y_offset, white, msg);
flip(ctx);
w_keyboard_t * kbd = NULL;
do {
kbd = poll_keyboard();
} while (!kbd);
if (kbd->key == '\n') {
free(kbd);
goto _have_password;
}
buffer_put(kbd->key);
free(kbd);
}
_have_password:
input_buffer[input_collected] = '\0';
sprintf(password, "%s", input_buffer);
input_collected = 0;
input_buffer[0] = '\0';
uid = checkUserPass(username, password);
if (uid >= 0) {
break;
}
}
memcpy(ctx->backbuffer, buf, buf_size);
flip(ctx);
teardown_windowing();
int _session_pid = fork();
if (!_session_pid) {
syscall_setuid(uid);
char * args[] = {"/bin/gsession", NULL};
execve(args[0], args, NULL);
}
syscall_wait(_session_pid);
free(buf);
free(sprites[0]);
free(sprites[1]);
}
return 0;
}