
/*
 * 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>

#if (NGX_HAVE_OPENSSL_SHA1_H)
#include <openssl/sha.h>
#else
#include <sha.h>
#endif


#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;
    SHA_CTX                     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_palloc(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;

        SHA1_Init(&sha);
        SHA1_Update(&sha, m->passwd->data, m->passwd->len);
        SHA1_Final(hash1, &sha);

        SHA1_Init(&sha);
        SHA1_Update(&sha, hash1, 20);
        SHA1_Final(hash2, &sha);

        SHA1_Init(&sha);
        SHA1_Update(&sha, gr2->salt1, 8);
        SHA1_Update(&sha, gr2->salt2, 12);
        SHA1_Update(&sha, hash2, 20);
        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);
}
