aboutsummaryrefslogtreecommitdiff
path: root/src/login.c
blob: 82142340b099f361023f8f6de94e264fd501a741 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#define _GNU_SOURCE
#include "login.h"
#include "data.h"
#include "server.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <argon2.h>

void handle_player(int conn_fd) {
  printf("Let's make a new player object\n");
  playerc_t plrc = {0};
  plrc.state = LoggedOut;
  plrc.conn = conn_fd;
  player_t plr = {0};
  plrc.plr = plr;

  printf("No sense in having a player if they can't log in!\n");

  int err = step_login(&plrc, conn_fd);
  if (err) {
    err = send_to_fd(conn_fd, "Error in login process, exiting");
    if (err) {
      printf("Could not send error message");
    }
    close(conn_fd);
    return;
  }

  close(conn_fd);
}

int step_login(playerc_t *player, int conn_fd) {
  int err = 0;

  for (;;) {
    switch (player->state) {
    case LoggedOut: ; /* the player has yet to log in, this is a fresh connection!
                     */
      printf("The player is logged out\n");
      send_to_fd(player->conn,
                 "Welcome! Please enter your **username** below\n");
      char *buf = (char *)malloc(1 << 10);
      printf("Waiting to receive...\n");
      recv(player->conn, buf, 1024, 0);
      printf("Received!\n");
      char* playername = trimwhitespace(buf);
      err = try_load_plr(playername, player);
      printf("Finished trying to load the player\n");
      if (err) {
        // File doesn't exist, let's create a player!
	player->plr.name = (char *)malloc(32);
        strcpy(player->plr.name, playername);
        send_to_fd(player->conn, "Howdy! Want to introduce yourself? [y|n]\n");
        recv(player->conn, buf, sizeof(buf), 0);
        if (buf[0] == 'y') {
          player->state = WantMakeAccount;
          break;
        } else if (buf[0] == 'n') {
          send_to_fd(player->conn,
                     "Awww :(. Oh well, hope to see you again soon!\n");
          return 4;
        }
        break;
      } else {
        player->state = EnterPassword;
        break;
      }
    case EnterPassword: ;
      asprintf(&buf, "Welcome back %s! Please enter your password, so we can confirm it.\n", player->plr.name);
      send_to_fd(player->conn, buf);
      memset(buf, '\0', 1 << 9);
      recv(player->conn, buf, sizeof(buf), 0); 
      char* pw = trimwhitespace(buf);
      int res = argon2i_verify(player->plr.pw_hash, pw, strlen(pw)); 
      printf("%d\n", res);
      if (res == ARGON2_OK) {
        // The password is good!
        send_to_fd(player->conn, "That looks good to me! Let's get you loaded in\n");
        player->state = Complete;
      } else {
          // Password is incorrect
          send_to_fd(player->conn, "Password incorrect, please try again\n");
          break;
      }
      break;
    case WantMakeAccount:
      asprintf(&buf, "Welcome aboard %s! Why don't you start us off by giving me a password.\n", player->plr.name);
      send_to_fd(player->conn, buf);
      memset(buf, '\0', 1 << 9);
      recv(player->conn, buf, sizeof(buf), 0);
        if (strlen(buf) <= 5) {
            send_to_fd(player->conn, "We're sorry, but passwords need to be at least 5 characters");
        } else {
            player->plr.pw_hash = (char *)malloc(512);
            char* hashbuf = (char *)malloc (1 << 5);
            char* pw = trimwhitespace(buf);
            err = argon2i_hash_encoded(32, 512, 1, pw, strlen(pw), "adSAaVWIueBwP2jHfAl7diRJ9ijC1Ysb9e920d6d9+I=", strlen("adSAaVWIueBwP2jHfAl7diRJ9ijC1Ysb9e920d6d9+I="), 32, player->plr.pw_hash, 512);
            
            if (err != ARGON2_OK) {
                send_to_fd(player->conn, "Uhhh, something happened. Try again.");
                printf("%d\n", err);
                player->state = LoggedOut;
                break;
            } else {
                send_to_fd(player->conn, "Sounds good! let's drop you into a world!");
                player->state = Complete;
                player->plr.hp = player->plr.max_hp = 20;
                player->plr.level = 1;
                player->plr.xp = 0;
                player->plr.location_id = 0;
                printf("Trying to write player\n");
                try_write_plr(&player->plr);
                printf("Done\n");
                player->state = Complete; 
            }
        }
    case Complete: ;
        return 0;
    }
  }

  return err;
}