
/*
 * Copyright (C) Igor Sysoev
 */


/* the library supports the subset of the MySQL 4.1+ protocol (version 10) */


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_event_connect.h>
#include <ngx_mysql.h>
#include <ngx_sha1.h>


#define NGX_MYSQL_LONG_PASSWORD       0x0001
#define NGX_MYSQL_CONNECT_WITH_DB     0x0008
#define NGX_MYSQL_PROTOCOL_41         0x0200
#define NGX_MYSQL_SECURE_CONNECTION   0x8000


#define NGX_MYSQL_CMD_QUERY           3


typedef struct {
    u_char      pktlen[3];
    u_char      pktn;

    u_char      protocol;
    u_char      version[1];       /* NULL-terminated string */
} ngx_mysql_greeting1_pkt_t;


typedef struct {
    u_char      thread[4];
    u_char      salt1[9];
    u_char      capacity[2];
    u_char      charset;
    u_char      status[2];
    u_char      zero[13];
    u_char      salt2[13];
} ngx_mysql_greeting2_pkt_t;


typedef struct {
    u_char      pktlen[3];
    u_char      pktn;

    u_char      capacity[4];
    u_char      max_packet[4];
    u_char      charset;
    u_char      zero[23];
    u_char      login[1];        /* NULL-terminated string */

 /*
  * u_char      passwd_len;         0 if no password
  * u_char      passwd[20];
  *
  * u_char      database[1];        NULL-terminated string
  */

} ngx_mysql_auth_pkt_t;


typedef struct {
    u_char      pktlen[3];
    u_char      pktn;
    u_char      fields;
} ngx_mysql_response_pkt_t;


typedef struct {
    u_char      pktlen[3];
    u_char      pktn;
    u_char      err;
    u_char      code[2];
    u_char      message[1];        /* string */
} ngx_mysql_error_pkt_t;


typedef struct {
    u_char      pktlen[3];
    u_char      pktn;
    u_char      command;
    u_char      arg[1];            /* string */
} ngx_mysql_command_pkt_t;


static void ngx_mysql_read_server_greeting(ngx_event_t *rev);
static void ngx_mysql_empty_handler(ngx_event_t *wev);
static void ngx_mysql_read_auth_result(ngx_event_t *rev);
static void ngx_mysql_read_query_result(ngx_event_t *rev);
static void ngx_mysql_close(ngx_mysql_t *m, ngx_int_t rc);


ngx_int_t
ngx_mysql_connect(ngx_mysql_t *m)
{
    ngx_int_t  rc;

#if 0
    if (cached) {
        return NGX_OK;
    }
#endif

    m->peer.log->action = "connecting to mysql server";

    rc = ngx_event_connect_peer(&m->peer);

    if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
        return rc;
    }

    m->peer.connection->data = m;

    m->peer.connection->read->handler = ngx_mysql_read_server_greeting;
    m->peer.connection->write->handler = ngx_mysql_empty_handler;

    ngx_add_timer(m->peer.connection->read, /* STUB */ 5000);

    return NGX_OK;
}


static void
ngx_mysql_read_server_greeting(ngx_event_t *rev)
{
    size_t                      len;
    u_char                     *p;
    ssize_t                     n;
    ngx_uint_t                  i, capacity;
    ngx_mysql_t                *m;
    ngx_connection_t           *c;
    ngx_mysql_greeting1_pkt_t  *gr1;
    ngx_mysql_greeting2_pkt_t  *gr2;
    ngx_mysql_auth_pkt_t       *auth;
    ngx_sha1_t                  sha;
    u_char                      hash1[20], hash2[20];

    c = rev->data;
    m = c->data;

    if (rev->timedout) {
        ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
                      "mysql server %V timed out", m->peer.name);

        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    if (m->buf == NULL) {
        m->peer.log->action = "reading mysql server greeting";

        m->buf = ngx_create_temp_buf(m->pool, /* STUB */ 1024);
        if (m->buf == NULL) {
            ngx_mysql_close(m, NGX_ERROR);
            return;
        }
    }

    n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024);

    if (n == NGX_AGAIN) {
        return;
    }

    if (n < 5) {
        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    gr1 = (ngx_mysql_greeting1_pkt_t *) m->buf->pos;

    if (ngx_m24toh(gr1->pktlen) > n - 4) {
        ngx_log_error(NGX_LOG_ERR, rev->log, 0,
                      "mysql server %V sent incomplete greeting packet",
                      m->peer.name);

        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    if (gr1->protocol < 10) {
        ngx_log_error(NGX_LOG_ERR, rev->log, 0,
                      "mysql server %V sent unsupported protocol version %ud",
                      m->peer.name, gr1->protocol);

        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    gr2 = (ngx_mysql_greeting2_pkt_t *)
                                 (gr1->version + ngx_strlen(gr1->version) + 1);

    capacity = ngx_m16toh(gr2->capacity);

    ngx_log_debug8(NGX_LOG_DEBUG_MYSQL, rev->log, 0,
                   "mysql version: %ud, \"%s\", thread: %ud, salt: \"%s\", "
                   "capacity: %Xd, charset: %ud, status: %ud, salt rest \"%s\"",
                   gr1->protocol, gr1->version, ngx_m32toh(gr2->thread),
                   gr2->salt1, capacity, gr2->charset,
                   ngx_m16toh(gr2->status), &gr2->salt2);

    capacity = NGX_MYSQL_LONG_PASSWORD
               | NGX_MYSQL_CONNECT_WITH_DB
               | NGX_MYSQL_PROTOCOL_41
               | NGX_MYSQL_SECURE_CONNECTION;

    len = 4 + 4 + 4 + 1 + 23 + m->login->len + 1 + 1 + m->database->len + 1;

    if (m->passwd->len) {
        len += 20;
    }

    auth = ngx_pnalloc(m->pool, len);
    if (auth == NULL) {
        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    ngx_htom24(auth->pktlen, len - 4);
    auth->pktn = (u_char) (gr1->pktn + 1);

    ngx_htom32(auth->capacity, capacity);
    ngx_htom32(auth->max_packet, 0x01000000);  /* max packet size 2^24 */
    ngx_memzero(auth->zero, 24);
    auth->charset = gr2->charset;

    p = ngx_copy(auth->login, m->login->data, m->login->len);
    *p++ = '\0';

    if (m->passwd->len) {

        *p++ = (u_char) 20;

        ngx_sha1_init(&sha);
        ngx_sha1_update(&sha, m->passwd->data, m->passwd->len);
        ngx_sha1_final(hash1, &sha);

        ngx_sha1_init(&sha);
        ngx_sha1_update(&sha, hash1, 20);
        ngx_sha1_final(hash2, &sha);

        ngx_sha1_init(&sha);
        ngx_sha1_update(&sha, gr2->salt1, 8);
        ngx_sha1_update(&sha, gr2->salt2, 12);
        ngx_sha1_update(&sha, hash2, 20);
        ngx_sha1_final(hash2, &sha);

        for (i = 0; i < 20; i++) {
            *p++ = (u_char) (hash1[i] ^ hash2[i]);
        }

    } else {
        *p++ = '\0';
    }

    p = ngx_copy(p, m->database->data, m->database->len);
    *p = '\0';


    n = ngx_send(m->peer.connection, (void *) auth, len);

    if (n < (ssize_t) len) {
        ngx_log_error(NGX_LOG_ERR, rev->log, 0,
                      "the incomplete packet was sent to mysql server %V",
                      m->peer.name);

        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    m->peer.connection->read->handler = ngx_mysql_read_auth_result;

    ngx_add_timer(m->peer.connection->read, /* STUB */ 5000);
}


static void
ngx_mysql_empty_handler(ngx_event_t *wev)
{
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "mysql empty handler");

    return;
}


static void
ngx_mysql_read_auth_result(ngx_event_t *rev)
{
    ssize_t                    n, len;
    ngx_str_t                  msg;
    ngx_mysql_t               *m;
    ngx_connection_t          *c;
    ngx_mysql_error_pkt_t     *epkt;
    ngx_mysql_response_pkt_t  *pkt;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql read auth");

    c = rev->data;
    m = c->data;

    m->peer.log->action = "reading mysql auth result";

    n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024);

    if (n == NGX_AGAIN) {
        return;
    }

    if (n < 5) {
        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    pkt = (ngx_mysql_response_pkt_t *) m->buf->pos;

    len = ngx_m24toh(pkt->pktlen);

    if (len > n - 4) {
        ngx_log_error(NGX_LOG_ERR, rev->log, 0,
                      "mysql server %V sent incomplete response packet",
                      m->peer.name);

        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    if (pkt->fields == 0) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql auth OK");

        m->state = NGX_OK;
        m->pktn = 0;

        m->handler(m);

        return;
    }

    epkt = (ngx_mysql_error_pkt_t *) pkt;

    msg.len = (u_char *) epkt + 4 + len - epkt->message;
    msg.data = epkt->message;

    ngx_log_error(NGX_LOG_ERR, rev->log, 0,
                  "mysql server %V sent error (%ud): \"%V\"",
                  m->peer.name, ngx_m16toh(epkt->code), &msg);

    ngx_mysql_close(m, NGX_ERROR);
}


ngx_int_t
ngx_mysql_query(ngx_mysql_t *m)
{
    ssize_t                   n;
    ngx_mysql_command_pkt_t  *pkt;

    pkt = (ngx_mysql_command_pkt_t *) m->query.data;

    ngx_htom24(pkt->pktlen, m->query.len - 4);
    pkt->pktn = (u_char) m->pktn++;
    pkt->command = NGX_MYSQL_CMD_QUERY;

    n = ngx_send(m->peer.connection, m->query.data, m->query.len);

    if (n < (ssize_t) m->query.len) {
        ngx_log_error(NGX_LOG_ERR, m->peer.log, 0,
                      "the incomplete packet was sent to mysql server %V",
                      m->peer.name);

        ngx_mysql_close(m, NGX_ERROR);
        return NGX_OK;
    }

    m->peer.connection->read->handler = ngx_mysql_read_query_result;

    ngx_add_timer(m->peer.connection->read, /* STUB */ 5000);

    /* STUB handle event */

    return NGX_OK;
}


static void
ngx_mysql_read_query_result(ngx_event_t *rev)
{
    ssize_t                    n, len;
    ngx_str_t                  msg;
    ngx_mysql_t               *m;
    ngx_connection_t          *c;
    ngx_mysql_error_pkt_t     *epkt;
    ngx_mysql_response_pkt_t  *pkt;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql read query result");

    c = rev->data;
    m = c->data;

    m->peer.log->action = "reading mysql read query result";

    n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024);

    if (n == NGX_AGAIN) {
        return;
    }

    if (n < 5) {
        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    pkt = (ngx_mysql_response_pkt_t *) m->buf->pos;

    len = ngx_m24toh(pkt->pktlen);

    if (len > n - 4) {
        ngx_log_error(NGX_LOG_ERR, rev->log, 0,
                      "mysql server %V sent incomplete response packet",
                      m->peer.name);

        ngx_mysql_close(m, NGX_ERROR);
        return;
    }

    if (pkt->fields != 0xff) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql query OK");

        m->state = NGX_OK;
        m->pktn = pkt->pktn;

        m->handler(m);

        return;
    }

    epkt = (ngx_mysql_error_pkt_t *) pkt;

    msg.len = (u_char *) epkt + 4 + len - epkt->message;
    msg.data = epkt->message;

    ngx_log_error(NGX_LOG_ERR, rev->log, 0,
                  "mysql server %V sent error (%ud): \"%V\"",
                  m->peer.name, ngx_m16toh(epkt->code), &msg);

    ngx_mysql_close(m, NGX_ERROR);
}


static void
ngx_mysql_close(ngx_mysql_t *m, ngx_int_t rc)
{
    if (rc == NGX_ERROR) {
        ngx_close_connection(m->peer.connection);
    }

    m->state = rc;

    m->handler(m);
}
