/*
 * Copyright (c) 2008 Hunter Morris <huntermorris@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <erl_interface.h>
#include <ei.h>
#include <unistd.h>

#define dec_int16(s) ((((unsigned char*)(s))[0] << 8) | \
                      (((unsigned char*)(s))[1]))

#define enc_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff;  \
    ((unsigned char*)(s))[1] = (i) & 0xff;}

#define BUFSIZE (1 << 16)
#define CMD_SALT 0
#define CMD_HASHPW 1

typedef unsigned char byte;

char *bcrypt(const char *, const char *);
void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);

/* These methods came from the Erlang port command tutorial:
 * http://www.erlang.org/doc/tutorial/c_port.html#4.2
 */
static int
read_buf(int fd, byte *buf, int len)
{
  int i, got = 0;
  do {
    if ((i = read(fd, buf+got, len-got)) <= 0) {
      if (i == 0) return got;
      if (errno != EINTR)
        return got;
      i = 0;
    }
    got += i;
  } while (got < len);
  return (len);
}

static int
read_cmd(byte *buf)
{
  int len;
  if (read_buf(0, buf, 2) != 2)
    return 0;
  len = dec_int16(buf);
  if (read_buf(0, buf, len) != len)
    return 0;
  return 1;
}

static int
write_buf(int fd, byte *buf, int len)
{
  int i, done = 0; 
  do {
    if ((i = write(fd, buf+done, len-done)) < 0) {
      if (errno != EINTR)
        return (i);
      i = 0;
    }
    done += i;
  } while (done < len);
  return (len);
}

static int
write_cmd(byte *buf, int len)
{
  byte hd[2];
  enc_int16(len, hd);
  if (write_buf(1, hd, 2) != 2)
    return 0;
  if (write_buf(1, buf, len) != len)
    return 0;
  return 1;
}

static int
process_reply(ETERM *pid, int cmd, const char *res)
{
  ETERM *result;
  int len, retval;
  byte *buf;
  result = erl_format("{~i, ~w, ~s}", cmd, pid, res);
  len = erl_term_len(result);
  buf = erl_malloc(len);
  erl_encode(result, buf);
  retval = write_cmd(buf, len);
  erl_free_term(result);
  erl_free(buf);
  return retval;
}

static int
process_encode_salt(ETERM *pid, ETERM *data)
{
  int retval = 0;
  ETERM *pattern, *cslt, *lr;
  char *csalt = NULL;
  long log_rounds = -1;
  int csaltlen = -1;
  char ret[64];
  pattern = erl_format("{Csalt, LogRounds}");
  if (erl_match(pattern, data)) {
    cslt = erl_var_content(pattern, "Csalt");
    csalt = erl_iolist_to_string(cslt);
    csaltlen = erl_iolist_length(cslt);
    lr = erl_var_content(pattern, "LogRounds");
    log_rounds = ERL_INT_UVALUE(lr);
    if (16 != csaltlen) {
      retval = process_reply(pid, CMD_SALT, "Invalid salt length");
    } else if (log_rounds < 4 || log_rounds > 31) {
      retval = process_reply(pid, CMD_SALT, "Invalid number of rounds");
    } else {
      encode_salt(ret, csalt, csaltlen, log_rounds);
      retval = process_reply(pid, CMD_SALT, ret);
    }
    erl_free_term(cslt);
    erl_free_term(lr);
    erl_free(csalt);
  };
  erl_free_term(pattern);
  return retval;
}

static int
process_hashpw(ETERM *pid, ETERM *data)
{
  int retval = 0;
  ETERM *pattern, *pwd, *slt;
  char *password, *salt;
  char *ret = NULL;
  char hashed[200];
  pattern = erl_format("{Pass, Salt}");
  if (erl_match(pattern, data)) {
    pwd = erl_var_content(pattern, "Pass");
    password = erl_iolist_to_string(pwd);
    slt = erl_var_content(pattern, "Salt");
    salt = erl_iolist_to_string(slt);
    if (NULL == (ret = bcrypt(password, salt)) ||
        0 == strncmp(ret, ":", 1)) {
      retval = process_reply(pid, CMD_HASHPW, "Invalid salt");
    } else {
      int retlen = strlen(ret);
      strncpy(hashed, ret, retlen);
      hashed[retlen] = 0;
      retval = process_reply(pid, CMD_HASHPW, hashed);
    }
    erl_free_term(pwd);
    erl_free_term(slt);
    erl_free(password);
    erl_free(salt);
  };
  erl_free_term(pattern);
  return retval;
}

static int
process_command(unsigned char *buf)
{
  int retval = 0;
  ETERM *pattern, *tuple, *cmd, *port, *data;
  pattern = erl_format("{Cmd, Port, Data}");
  tuple = erl_decode(buf);
  if (erl_match(pattern, tuple)) {
    cmd = erl_var_content(pattern, "Cmd");
    port = erl_var_content(pattern, "Port");
    data = erl_var_content(pattern, "Data");
    switch (ERL_INT_VALUE(cmd)) {
    case CMD_SALT:
      retval = process_encode_salt(port, data);
      break;
    case CMD_HASHPW:
      retval = process_hashpw(port, data);
      break;
    };
    erl_free_term(cmd);
    erl_free_term(port);
    erl_free_term(data);
  }
  erl_free_term(pattern);
  erl_free_term(tuple);
  return retval;
}

static void
loop(void)
{
  byte buf[BUFSIZE];
  int retval = 0;
  do {
    if (read_cmd(buf) > 0)
      retval = process_command(buf);
    else
      retval = 0;
  } while (retval);
}

int
main(int argc, char *argv[])
{
  erl_init(NULL, 0);
  loop();
  return 0;
}
