~muirrum/cmud

b6a5143693d85ca26d3e42f9999348b53290b34d — Cara Salter 7 months ago a932e1e
start implementing XML in login.c
5 files changed, 102 insertions(+), 21 deletions(-)

M Makefile.am
M include/xml.h
M src/login.c
M src/util/data.c
M src/util/xml.c
M Makefile.am => Makefile.am +2 -2
@@ 1,3 1,3 @@
bin_PROGRAMS = cmud
cmud_SOURCES = src/main.c src/login.c src/util/data.c src/game.c src/util/hash.c src/server.c src/util/util.c src/log.c src/config.c
cmud_CFLAGS = -fsanitize=address -I ./include
cmud_SOURCES = src/main.c src/login.c src/util/data.c src/game.c src/util/hash.c src/server.c src/util/util.c src/log.c src/config.c src/util/xml.c
cmud_CFLAGS = -I ./include

M include/xml.h => include/xml.h +3 -1
@@ 3,4 3,6 @@

int load_player_from_xml(const char* player_name, playerc_t* plr);

int write_player_to_xml(const player* plr);
\ No newline at end of file
int write_player_to_xml(const player_t* plr);

int does_player_exist(const char* player_name);
\ No newline at end of file

M src/login.c => src/login.c +20 -11
@@ 1,8 1,9 @@
#define _GNU_SOURCE
#include "login.h"
#include "data.h"
#include "xml.h"
#include "server.h"
#include "util.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


@@ 43,16 44,16 @@ int step_login(playerc_t *player, int conn_fd) {
      debug("The player is logged out\n");
      send_to_fd(player->conn,
                 "Welcome! Please enter your **username** below\n");
      char *buf = (char *)malloc(1 << 10);
      debug("Waiting to receive...\n");
      recv(player->conn, buf, 1024, 0);
      debug("Received!\n");
      char *buf = (char *)malloc(1 << 8);
      debug("Waiting to receive...");
      recv(player->conn, buf, 256, 0);
      debug("Received!");
      char* playername = trimwhitespace(buf);
      err = try_load_plr(playername, player);
      debug("Finished trying to load the player\n");
      err = does_player_exist(playername);
      debug("Finished trying to load the player");
      if (err) {
        // File doesn't exist, let's create a player!
	player->plr.name = (char *)malloc(32);
      	player->plr.name = (char *)malloc(sizeof(char)*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);


@@ 66,6 67,7 @@ int step_login(playerc_t *player, int conn_fd) {
        }
        break;
      } else {
        load_player_from_xml(playername, player);
        player->state = EnterPassword;
        break;
      }


@@ 94,9 96,16 @@ int step_login(playerc_t *player, int conn_fd) {
        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);
            player->plr.pw_hash = (char *)malloc(sizeof(char)*32);
            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);
            char* salt = (char*) malloc(sizeof(char)*64);
            err = config_read_string("salt", salt, "config");
            if (err) {
              error("Could not find salt value, using 'bad-salt', THIS IS INSECURE!");
              salt = "bad-salt";
            }
            err = argon2i_hash_encoded(32, 512, 1, pw, strlen(pw), salt,strlen(salt), 32, player->plr.pw_hash, 32);
            free(salt);
            
            if (err != ARGON2_OK) {
                send_to_fd(player->conn, "Uhhh, something happened. Try again."); 


@@ 110,7 119,7 @@ int step_login(playerc_t *player, int conn_fd) {
                player->plr.xp = 0;
                player->plr.location_id = 0;
                debug("Trying to write player\n");
                try_write_plr(&player->plr);
                write_player_to_xml(&(player->plr));
                debug("Done\n");
                player->state = Complete; 
            }

M src/util/data.c => src/util/data.c +0 -6
@@ 12,13 12,7 @@

int deserialize_player(FILE* fp, player_t *plr);
int serialize_player(player_t* plr, FILE* fp);
int try_make_data_dirs() {
  int err = 0;
  err = mkdir("data", S_IRWXU);
  err = mkdir("data/players", S_IRWXU);

  return err;
}

int try_load_plr(char *player_name, playerc_t *plr) {
  int err = 0;

M src/util/xml.c => src/util/xml.c +77 -1
@@ 15,6 15,27 @@ int try_make_data_dirs() {
  return err;
}

int does_player_exist(const char* player_name) {
  int err = try_make_data_dirs();
  if (err) {
    error("Couldn't make data directories!");
    return err;
  }

  char* fname;
  make_plrfname(player_name, fname);

  if (stat(fname, NULL)) {
    return 0;
  } else {
    return 1;
  }
}

void make_plrfname(const char* player_name, char* buf) {
    asprintf(buf, "data/players/%s.xml", player_name);
}

int load_player_from_xml(const char* player_name, playerc_t* plr){
    int err = 0;
    if ((err = try_make_data_dirs())) {


@@ 22,9 43,64 @@ int load_player_from_xml(const char* player_name, playerc_t* plr){
        return err;
    }
    char* fname;
    asprintf(fname, "data/players/%s.plr", player_name);
    make_plrfname(player_name, fname);
    FILE* fp = fopen(fname, "r");
    mxml_node_t* plr_tree;

    plr_tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);
    fclose(fp);

    mxml_node_t* name_n = mxmlFindElement(plr_tree, plr_tree, "name", NULL, NULL, MXML_DESCEND);
    plr->plr.name = mxmlGetText(name_n, 0);

    mxml_node_t* pwhash_n = mxmlFindElement(plr_tree, plr_tree, "pw_hash", NULL, NULL, MXML_DESCEND);
    plr->plr.pw_hash = mxmlGetText(pwhash_n, 0);

    mxml_node_t* xp_n = mxmlFindElement(plr_tree, plr_tree, "xp", NULL, NULL, MXML_DESCEND);
    plr->plr.xp = mxmlGetInteger(xp_n);

    mxml_node_t* hp_n = mxmlFindElement(plr_tree, plr_tree, "hp", NULL, NULL, MXML_DESCEND);
    plr->plr.hp = mxmlGetInteger(hp_n);

    mxml_node_t* maxhp_n = mxmlFindElement(plr_tree, plr_tree, "max_hp", NULL, NULL, MXML_DESCEND);
    plr->plr.max_hp = mxmlGetInteger(maxhp_n);

    mxml_node_t* level_n = mxmlFindElement(plr_tree, plr_tree, "level", NULL, NULL, MXML_DESCEND);
    plr->plr.level = mxmlGetInteger(level_n);

    mxml_node_t* location_n = mxmlFindElement(plr_tree, plr_tree, "location_id", NULL, NULL, MXML_DESCEND);
    plr->plr.location_id = mxmlGetInteger(location_n);

    return 0;
}

int write_player_to_xml(const player_t* plr) {
  mxml_node_t *xml;
  mxml_node_t* player;

  xml = mxmlNewXML("1.0");

  player = mxmlNewElement(xml, "player");
  mxml_node_t* node = mxmlNewElement(player, "name");
  mxmlNewText(node, 0, plr->name);
  node = mxmlNewElement(player, "pw_hash");
  mxmlNewText(node, 0, plr->pw_hash);
  node = mxmlNewElement(player, "xp");
  mxmlNewInteger(node, plr->xp);
  node = mxmlNewElement(player, "hp");
  mxmlNewInteger(node, plr->hp);
  node = mxmlNewElement(player, "max_hp");
  mxmlNewInteger(node, plr->max_hp);
  node = mxmlNewElement(player, "level");
  mxmlNewInteger(node, plr->level);
  node = mxmlNewElement(player, "location_id");
  mxmlNewInteger(node, plr->location_id);

  char* fname;
  make_plrfname(plr->name, fname);
  FILE* fp = fopen(fname, "w");
  mxmlSaveFile(xml, fp, MXML_NO_CALLBACK);
  fclose(fp);

  return 0;
}
\ No newline at end of file