#include "vuln.h"

#include <stdio.h>
#include <string.h>

static uint16_t g_current_session_id = (VULN_INIT_SESSION_ID & 0xFF00u) - 1u;

uint16_t VULN_GETSESSIONID() {
  return g_current_session_id;
}

static const char *get_expected_username() {
  return VULN_USERNAME;
}

static const char *get_expected_password() {
  return VULN_PASSWORD;
}

int32_t authenticate(const char *req, char resp[0x100]) {
  char _stack_localvars[0x80];
#define _local_username     ((char *)    (_stack_localvars + 0 ))
#define _local_password     ((char *)    (_stack_localvars + 0x30))
#define _local_session_id (*((uint16_t *)(_stack_localvars + 0x60)))
#define _local_ret        (*(( int32_t *)(_stack_localvars + 0x70)))

  _local_session_id = ++g_current_session_id;
  _local_ret = 0;

  const char *_temp_start_username = req;
  const char *_temp_end_username= strchr(req, ' ');
  int _temp_len_username = _temp_end_username - _temp_start_username;
  memcpy(_local_username, _temp_start_username, _temp_len_username);

  const char *_temp_start_password = _temp_end_username + 1;
  int _temp_len_password = strlen(_temp_start_password);
  memcpy(_local_password, _temp_start_password, _temp_len_password);

  if (strcmp(_local_username, get_expected_username())) {
    sprintf(resp, "error 403: no such user: %s", _local_username);
    _local_ret = -1;
    return _local_ret;
  }
  
  if (strcmp(_local_password, get_expected_password())) {
    sprintf(resp, "error 403: invalid password");
    _local_ret = -1;
    return _local_ret;
  }

  sprintf(resp, "ok %" PRIu16, _local_session_id);
  _local_ret = 0;
  return _local_ret;
#undef _local_ret
#undef _local_session_id
#undef _local_password
#undef _local_username
}
