ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Нужен пример моду ля.



maxhl@xxxxxxxxxxxxxx wrote:
Кому нежалко скиньте какой нибудь пример.

В аттаче -- пример модуля для валидации одноразовых ссылок.

Дисклеймер: написано было давно, поэтому помидорами не кидаться.

Кроме того, есть страница

http://wiki.codemongers.com/NginxModules

В разделе Third-Party HTTP modules там исключительно одни примеры.

--
Regards,
Valery Kholodkov
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

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

#if (NGX_OPENSSL_SHA1)
#define  SHA1Init    SHA1_Init
#define  SHA1Update  SHA1_Update
#define  SHA1Final   SHA1_Final
#endif

typedef struct {
        ngx_str_t       secret_key;
        ngx_regex_t     *regex;
        ngx_int_t       ncaptures;

        ngx_int_t       authenticator_pos;
        ngx_int_t       fragment_pos;
        ngx_int_t       digest_pos;
        ngx_int_t       id_pos;
        ngx_int_t       filename_pos;
} ngx_http_securelinks_loc_conf_t;


static void *ngx_http_securelinks_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_securelinks_merge_loc_conf(ngx_conf_t *cf,
    void *parent, void *child);
static ngx_int_t ngx_http_securelinks_init(ngx_cycle_t *cycle);
static char *ngx_http_securelinks_regex(ngx_conf_t *cf, ngx_command_t *cmd, 
void *conf);


static ngx_command_t  ngx_http_securelinks_commands[] = {

    { ngx_string("securelinks_regex"),
      NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                       |NGX_CONF_TAKE1,
      ngx_http_securelinks_regex,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },

    { ngx_string("securelinks_secret_key"),
      NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                       |NGX_CONF_TAKE1,
      ngx_conf_set_str_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_securelinks_loc_conf_t, secret_key),
      NULL },

    { ngx_string("securelinks_authenticator_pos"),
      NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                       |NGX_CONF_TAKE1,
      ngx_conf_set_num_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_securelinks_loc_conf_t, authenticator_pos),
      NULL },

    { ngx_string("securelinks_fragment_pos"),
      NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                       |NGX_CONF_TAKE1,
      ngx_conf_set_num_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_securelinks_loc_conf_t, fragment_pos),
      NULL },

    { ngx_string("securelinks_digest_pos"),
      NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                       |NGX_CONF_TAKE1,
      ngx_conf_set_num_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_securelinks_loc_conf_t, digest_pos),
      NULL },

    { ngx_string("securelinks_id_pos"),
      NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                       |NGX_CONF_TAKE1,
      ngx_conf_set_num_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_securelinks_loc_conf_t, id_pos),
      NULL },

    { ngx_string("securelinks_filename_pos"),
      NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                       |NGX_CONF_TAKE1,
      ngx_conf_set_num_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_securelinks_loc_conf_t, filename_pos),
      NULL },

      ngx_null_command
};


ngx_http_module_t  ngx_http_securelinks_module_ctx = {
    NULL,                                  /* preconfiguration */
    NULL,                                  /* postconfiguration */

    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */

    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */

    ngx_http_securelinks_create_loc_conf,  /* create location configration */
    ngx_http_securelinks_merge_loc_conf    /* merge location configration */
};


ngx_module_t  ngx_http_securelinks_module = {
    NGX_MODULE_V1,
    &ngx_http_securelinks_module_ctx,      /* module context */
    ngx_http_securelinks_commands,         /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    NULL,                                  /* init master */
    ngx_http_securelinks_init,             /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};

static ngx_int_t
ngx_http_securelinks_get_remote_addr_str(ngx_http_request_t *r, ngx_str_t *dest)
{
    struct sockaddr_in          *sin;
    
    dest->data = ngx_palloc(r->pool, INET_ADDRSTRLEN);

    if(dest->data == NULL)
        return NGX_ERROR;

    sin = (struct sockaddr_in *) r->connection->sockaddr;   

    dest->len = ngx_inet_ntop(sin->sin_family,
                &sin->sin_addr, dest->data, INET_ADDRSTRLEN);

    return NGX_OK;
}

static ngx_int_t
ngx_http_securelinks_handler(ngx_http_request_t *r)
{
    ngx_http_securelinks_loc_conf_t  *rlcf;
    ngx_int_t                        *captures;
    ngx_int_t                        rc;
    ngx_str_t                     authenticator;
    ngx_str_t                     fragment;
    ngx_str_t                     digest;
    ngx_str_t                     id;
    ngx_str_t                     filename;

    SHA_CTX                      sha1;
    u_char                       sha1_digest[SHA_DIGEST_LENGTH];
    ngx_str_t                    remote_addr;
    ngx_str_t                    hex_digest;
    ngx_str_t                    rewritten_uri;
    char                         *p;

    rlcf = ngx_http_get_module_loc_conf(r, ngx_http_securelinks_module);

    if (rlcf->regex == NULL) {
        return NGX_DECLINED;
    }

    if(ngx_http_securelinks_get_remote_addr_str(r, &remote_addr) != NGX_OK)
        return NGX_HTTP_INTERNAL_SERVER_ERROR;

    captures = ngx_palloc(r->pool, (rlcf->ncaptures + 1) * sizeof(int) * 3);
    if (captures == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    rc = ngx_regex_exec(rlcf->regex, &r->uri, captures, (rlcf->ncaptures + 1) * 
3);

    if(rc == NGX_REGEX_NO_MATCHED) {
        return NGX_HTTP_NOT_FOUND;    
    }

    if (rc < 0) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
            ngx_regex_exec_n " failed: %d on \"%V\"", rc, &r->uri);
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    authenticator.data = r->uri.data + captures[2 * rlcf->authenticator_pos]; 
    authenticator.len = captures[2 * rlcf->authenticator_pos + 1] - captures[2 
* rlcf->authenticator_pos]; 

    fragment.data = r->uri.data + captures[2 * rlcf->fragment_pos]; 
    fragment.len = captures[2 * rlcf->fragment_pos + 1] - captures[2 * 
rlcf->fragment_pos]; 
    
    digest.data = r->uri.data + captures[2 * rlcf->digest_pos]; 
    digest.len = captures[2 * rlcf->digest_pos + 1] - captures[2 * 
rlcf->digest_pos]; 
    
    id.data = r->uri.data + captures[2 * rlcf->id_pos]; 
    id.len = captures[2 * rlcf->id_pos + 1] - captures[2 * rlcf->id_pos]; 

    filename.data = r->uri.data + captures[2 * rlcf->filename_pos]; 
    filename.len = captures[2 * rlcf->filename_pos + 1] - captures[2 * 
rlcf->filename_pos]; 

    SHA1_Init(&sha1);

    SHA1_Update(&sha1, remote_addr.data, remote_addr.len);
    SHA1_Update(&sha1, ":", sizeof(char));
    SHA1_Update(&sha1, authenticator.data, authenticator.len);
    SHA1_Update(&sha1, ":", sizeof(char));
    SHA1_Update(&sha1, fragment.data, fragment.len);
    SHA1_Update(&sha1, ":", sizeof(char));
    SHA1_Update(&sha1, filename.data, filename.len);
    SHA1_Update(&sha1, ":", sizeof(char));
    SHA1_Update(&sha1, rlcf->secret_key.data, rlcf->secret_key.len);

    SHA1_Final(sha1_digest, &sha1);

#ifdef SECURELINKS_DEBUG
    ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
            "verified sequence \"%V:%V:%V:%V:%V\"", &remote_addr, 
&authenticator, &fragment, &filename, &rlcf->secret_key);
#endif

    hex_digest.data = ngx_palloc(r->pool, (2 * SHA_DIGEST_LENGTH + 1 ) * 
sizeof(char));
    if (hex_digest.data == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    ngx_digest_text(hex_digest.data, sha1_digest, SHA_DIGEST_LENGTH);
    hex_digest.len = 2 * SHA_DIGEST_LENGTH;

    // Verify digest
    if(ngx_strncasecmp(digest.data, hex_digest.data, (digest.len < 
hex_digest.len) ? digest.len : hex_digest.len)) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
            "digest mismatch: \"%V\" vs \"%V\" for \"%V\"", &digest, 
&hex_digest, &r->uri);
        return NGX_HTTP_NOT_FOUND;
    }

    rewritten_uri.len = 1 + fragment.len + 1 + filename.len;
    rewritten_uri.data = ngx_palloc(r->pool, rewritten_uri.len);
    if (rewritten_uri.data == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    p = rewritten_uri.data;

    *p++ = '/';

    ngx_memcpy(p, fragment.data, fragment.len);
    p += fragment.len;

    *p++ = '/';

    ngx_memcpy(p, filename.data, filename.len);
    p += filename.len;

    r->uri.data = rewritten_uri.data;
    r->uri.len = rewritten_uri.len;

    return NGX_DECLINED; 
}

static void *
ngx_http_securelinks_create_loc_conf(ngx_conf_t *cf)
{
    ngx_http_securelinks_loc_conf_t  *conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_securelinks_loc_conf_t));
    if (conf == NULL) {
        return NGX_CONF_ERROR;
    }

    conf->secret_key.len = 0;
    conf->secret_key.data = NULL;

    conf->regex = NULL;

    conf->authenticator_pos = NGX_CONF_UNSET;
    conf->fragment_pos = NGX_CONF_UNSET;
    conf->digest_pos = NGX_CONF_UNSET;
    conf->id_pos = NGX_CONF_UNSET;
    conf->filename_pos = NGX_CONF_UNSET;

    return conf;
}

static char *
ngx_http_securelinks_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
    ngx_http_securelinks_loc_conf_t *prev = parent;
    ngx_http_securelinks_loc_conf_t *conf = child;

    ngx_conf_merge_str_value(conf->secret_key, prev->secret_key, "");

    ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);

    return NGX_CONF_OK;
}

static ngx_int_t
ngx_http_securelinks_init(ngx_cycle_t *cycle)
{
    ngx_http_handler_pt        *h;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);

    h = ngx_array_push(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    *h = ngx_http_securelinks_handler;

    h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    *h = ngx_http_securelinks_handler;

    return NGX_OK;
}

static char *
ngx_http_securelinks_regex(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_securelinks_loc_conf_t  *lcf = conf;
    ngx_str_t                         *value, err;
    ngx_int_t                        n;

    value = cf->args->elts;

    lcf->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err);

    if (lcf->regex == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
        return NGX_CONF_ERROR;
    }

    n = ngx_regex_capture_count(lcf->regex);

    if (n < 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           ngx_regex_capture_count_n " failed for "
                           "pattern \"%V\"", &value[1]);
        return NGX_CONF_ERROR;                   
    }

    lcf->ncaptures = n;

    return NGX_CONF_OK;    
}



 




Copyright © Lexa Software, 1996-2009.