zoukankan      html  css  js  c++  java
  • nginx第三方模块(ngx_http_auth_pam_module)加注释

      1 /*
      2  * Copyright (C) 2008-2010 Sergio Talens-Oliag <sto@iti.upv.es>
      3  *
      4  * Based on nginx's 'ngx_http_auth_basic_module.c' by Igor Sysoev and apache's
      5  * 'mod_auth_pam.c' by Ingo Luetkebolhe.
      6  *
      7  * SVN Id: $Id: ngx_http_auth_pam_module.c 4487 2010-11-15 09:57:03Z sto $
      8  */
      9 #include <ngx_config.h>
     10 #include <ngx_core.h>
     11 #include <ngx_http.h>
     12 #include <security/pam_appl.h>
     13 #define NGX_PAM_SERVICE_NAME    "nginx"
     14 /*conf文件中需要配置的,/etc/pam.d/下对应文件的名字
     15 auth_pam_service_name "nginx-mysql";
     16 (在/etc/pam.d/ 下建一个文件nginx-mysql
     17 /etc/pam.d/nginx-mysql)
     18 内容:
     19 auth required /lib/security/pam_mysql.so user=pamuser passwd=123456 host=localhost db=pam table=user usercolumn=userid passwdcolumn=passwd crypt=2
     20 account required /lib/security/pam_mysql.so user=pamuser passwd=123456 host=localhost db=pam table=user usercolumn=userid passwdcolumn=passwd crypt=2
     21 */
     22 /* Module context data 数据内容*/
     23 typedef struct {
     24     ngx_str_t  passwd;
     25 } ngx_http_auth_pam_ctx_t;
     26 /* PAM userinfo 用户信息*/
     27 typedef struct {
     28     ngx_str_t  username;
     29     ngx_str_t  password;
     30 } ngx_pam_userinfo;
     31 /* Module configuration struct 该模块配置数据*/
     32 typedef struct {
     33     ngx_str_t realm;  /* http basic auth realm 配置文件中的auth_pam "mysql pam";*/
     34     ngx_str_t service_name; /* pam service name 配置文件中的auth_pam_service_name "nginx-mysql";*/
     35 } ngx_http_auth_pam_loc_conf_t;
     36 /* Module handler */
     37 static ngx_int_t ngx_http_auth_pam_handler(ngx_http_request_t *r);
     38 /* Function that authenticates the user -- is the only function that uses PAM */
     39 static ngx_int_t ngx_http_auth_pam_authenticate(ngx_http_request_t *r,
     40     ngx_http_auth_pam_ctx_t *ctx, ngx_str_t *passwd, void *conf);
     41 static ngx_int_t ngx_http_auth_pam_set_realm(ngx_http_request_t *r,
     42     ngx_str_t *realm);
     43 static void *ngx_http_auth_pam_create_loc_conf(ngx_conf_t *cf);
     44 static char *ngx_http_auth_pam_merge_loc_conf(ngx_conf_t *cf,
     45     void *parent, void *child);
     46 static ngx_int_t ngx_http_auth_pam_init(ngx_conf_t *cf);
     47 static char *ngx_http_auth_pam(ngx_conf_t *cf, void *post, void *data);
     48 static ngx_conf_post_handler_pt  ngx_http_auth_pam_p = ngx_http_auth_pam;
     49 static int ngx_auth_pam_talker(int num_msg, const struct pam_message ** msg,
     50     struct pam_response ** resp, void *appdata_ptr);
     51 static ngx_command_t  ngx_http_auth_pam_commands[] = {
     52     { ngx_string("auth_pam"),
     53       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
     54                         |NGX_CONF_TAKE1,
     55       ngx_conf_set_str_slot,
     56       NGX_HTTP_LOC_CONF_OFFSET,
     57       offsetof(ngx_http_auth_pam_loc_conf_t, realm),
     58       &ngx_http_auth_pam_p },
     59     { ngx_string("auth_pam_service_name"),
     60       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
     61                         |NGX_CONF_TAKE1,
     62       ngx_conf_set_str_slot,
     63       NGX_HTTP_LOC_CONF_OFFSET,
     64       offsetof(ngx_http_auth_pam_loc_conf_t, service_name),
     65       NULL },
     66 };
     67 
     68 static ngx_http_module_t  ngx_http_auth_pam_module_ctx = {
     69     NULL,                                  /* preconfiguration */
     70     ngx_http_auth_pam_init,                /* postconfiguration */
     71     NULL,                                  /* create main configuration */
     72     NULL,                                  /* init main configuration */
     73     NULL,                                  /* create server configuration */
     74     NULL,                                  /* merge server configuration */
     75     ngx_http_auth_pam_create_loc_conf,     /* create location configuration */
     76     ngx_http_auth_pam_merge_loc_conf       /* merge location configuration */
     77 };
     78 
     79 ngx_module_t  ngx_http_auth_pam_module = {
     80     NGX_MODULE_V1,
     81     &ngx_http_auth_pam_module_ctx,         /* module context */
     82     ngx_http_auth_pam_commands,            /* module directives */
     83     NGX_HTTP_MODULE,                       /* module type */
     84     NULL,                                  /* init master */
     85     NULL,                                  /* init module */
     86     NULL,                                  /* init process */
     87     NULL,                                  /* init thread */
     88     NULL,                                  /* exit thread */
     89     NULL,                                  /* exit process */
     90     NULL,                                  /* exit master */
     91     NGX_MODULE_V1_PADDING
     92 };
     93 /*
     94  * ngx_auth_pam_talker: supply authentication information to PAM when asked
     95  *
     96  * Assumptions:
     97  *   A password is asked for by requesting input without echoing
     98  *   A username is asked for by requesting input _with_ echoing
     99  */
    100 static int
    101 ngx_auth_pam_talker(int num_msg, const struct pam_message ** msg,
    102       struct pam_response ** resp, void *appdata_ptr)
    103 {
    104     int  i;
    105     ngx_pam_userinfo  *uinfo;
    106     struct pam_response  *response;
    107     uinfo = (ngx_pam_userinfo *) appdata_ptr;
    108     response = NULL;
    109     /* parameter sanity checking */
    110     if (!resp || !msg || !uinfo)
    111  return PAM_CONV_ERR;
    112     /* allocate memory to store response */
    113     response = malloc(num_msg * sizeof(struct pam_response));
    114     if (!response)
    115  return PAM_CONV_ERR;
    116     /* copy values */
    117     for (i = 0; i < num_msg; i++) {
    118  /* initialize to safe values */
    119  response[i].resp_retcode = 0;
    120  response[i].resp = 0;
    121  /* select response based on requested output style */
    122  switch (msg[i]->msg_style) {
    123  case PAM_PROMPT_ECHO_ON:
    124      /* on memory allocation failure, auth fails */
    125      response[i].resp = strdup((const char *)uinfo->username.data);
    126      break;
    127  case PAM_PROMPT_ECHO_OFF:
    128      response[i].resp = strdup((const char *)uinfo->password.data);
    129      break;
    130  default:
    131      if (response) {
    132   free(response);
    133      }
    134      return PAM_CONV_ERR;
    135  }
    136     }
    137     /* everything okay, set PAM response values */
    138     *resp = response;
    139     return PAM_SUCCESS;
    140 }
    141 static ngx_int_t
    142 ngx_http_auth_pam_handler(ngx_http_request_t *r)
    143 {
    144     ngx_int_t  rc;
    145     ngx_http_auth_pam_ctx_t  *ctx;
    146     ngx_http_auth_pam_loc_conf_t  *alcf;
    147     alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_pam_module);
    148     if (alcf->realm.len == 0) {
    149         return NGX_DECLINED;
    150     }
    151     ctx = ngx_http_get_module_ctx(r, ngx_http_auth_pam_module);
    152     if (ctx) {
    153         return ngx_http_auth_pam_authenticate(r, ctx, &ctx->passwd, alcf);
    154     }
    155     /* Decode http auth user and passwd, leaving values on the request */
    156     rc = ngx_http_auth_basic_user(r);
    157     if (rc == NGX_DECLINED) {
    158         return ngx_http_auth_pam_set_realm(r, &alcf->realm);
    159     }
    160     if (rc == NGX_ERROR) {
    161         return NGX_HTTP_INTERNAL_SERVER_ERROR;
    162     }
    163     /* Check user & password using PAM */
    164     return ngx_http_auth_pam_authenticate(r, ctx, &ctx->passwd, alcf);
    165 }
    166 static ngx_int_t
    167 ngx_http_auth_pam_authenticate(ngx_http_request_t *r,
    168     ngx_http_auth_pam_ctx_t *ctx, ngx_str_t *passwd, void *conf)
    169 {
    170     ngx_int_t   rc;
    171     ngx_http_auth_pam_loc_conf_t  *alcf;
    172     ngx_pam_userinfo  uinfo;
    173     struct pam_conv   conv_info; /* PAM struct */
    174     pam_handle_t      *pamh;
    175     u_char            *service_name;
    176     alcf = conf;
    177     size_t   len;
    178     u_char  *uname_buf, *p;
    179     /**
    180      * Get username and password, note that r->headers_in.user contains the
    181      * string 'user:pass', so we need to copy the username
    182      **/
    183     for (len = 0; len < r->headers_in.user.len; len++) {
    184  if (r->headers_in.user.data[len] == ':') {
    185             break;
    186  }
    187     }
    188     uname_buf = ngx_palloc(r->pool, len+1);
    189     if (uname_buf == NULL) {
    190         return NGX_HTTP_INTERNAL_SERVER_ERROR;
    191     }
    192     p = ngx_cpymem(uname_buf, r->headers_in.user.data , len);
    193     *='\0';
    194     uinfo.username.data = uname_buf;
    195     uinfo.username.len  = len;
    196     
    197     uinfo.password.data = r->headers_in.passwd.data;
    198     uinfo.password.len  = r->headers_in.passwd.len;
    199     conv_info.conv = &ngx_auth_pam_talker;
    200     conv_info.appdata_ptr = (void *&uinfo;
    201     
    202     pamh = NULL;
    203     /* Initialize PAM */
    204     if (alcf->service_name.data == NULL) {
    205  service_name = (u_char *) NGX_PAM_SERVICE_NAME;
    206     } else {
    207  service_name = alcf->service_name.data;
    208     }
    209     if ((rc = pam_start((const char *) service_name,
    210    (const char *) uinfo.username.data,
    211    &conv_info,
    212    &pamh)) != PAM_SUCCESS) {
    213         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
    214         "PAM: Could not start pam service: %s",
    215         pam_strerror(pamh, rc));
    216         return NGX_HTTP_INTERNAL_SERVER_ERROR;
    217     }
    218     /* try to authenticate user, log error on failure */
    219     if ((rc = pam_authenticate(pamh,
    220           PAM_DISALLOW_NULL_AUTHTOK)) != PAM_SUCCESS) {
    221         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
    222         "PAM: user '%s' - not authenticated: %s",
    223         uinfo.username.data, pam_strerror(pamh, rc));
    224  pam_end(pamh, PAM_SUCCESS);
    225      return ngx_http_auth_pam_set_realm(r, &alcf->realm);
    226     } /* endif authenticate */
    227     /* check that the account is healthy */
    228     if ((rc = pam_acct_mgmt(pamh, PAM_DISALLOW_NULL_AUTHTOK)) != PAM_SUCCESS) {
    229         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
    230         "PAM: user '%s'  - invalid account: %s",
    231         uinfo.username.data, pam_strerror(pamh, rc));
    232  pam_end(pamh, PAM_SUCCESS);
    233      return ngx_http_auth_pam_set_realm(r, &alcf->realm);
    234     }
    235     pam_end(pamh, PAM_SUCCESS);
    236     return NGX_OK;
    237 }
    238 static ngx_int_t
    239 ngx_http_auth_pam_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
    240 {
    241     r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers);
    242     if (r->headers_out.www_authenticate == NULL) {
    243         return NGX_HTTP_INTERNAL_SERVER_ERROR;
    244     }
    245     r->headers_out.www_authenticate->hash = 1;
    246     r->headers_out.www_authenticate->key.len = sizeof("WWW-Authenticate"- 1;
    247     r->headers_out.www_authenticate->key.data = (u_char *"WWW-Authenticate";
    248     r->headers_out.www_authenticate->value = *realm;
    249     return NGX_HTTP_UNAUTHORIZED;
    250 }
    251 static void *
    252 ngx_http_auth_pam_create_loc_conf(ngx_conf_t *cf)
    253 {
    254     ngx_http_auth_pam_loc_conf_t *conf;
    255     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_pam_loc_conf_t));
    256     if (conf == NULL) {
    257         return NGX_CONF_ERROR;
    258     }
    259     return conf;
    260 }
    261 static char *
    262 ngx_http_auth_pam_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
    263 {
    264     ngx_http_auth_pam_loc_conf_t  *prev = parent;
    265     ngx_http_auth_pam_loc_conf_t  *conf = child;
    266     if (conf->realm.data == NULL) {
    267         conf->realm = prev->realm;
    268     }
    269     if (conf->service_name.data == NULL) {
    270         conf->service_name = prev->service_name;
    271     }
    272     return NGX_CONF_OK;
    273 }
    274 static ngx_int_t
    275 ngx_http_auth_pam_init(ngx_conf_t *cf)
    276 {
    277     ngx_http_handler_pt        *h;
    278     ngx_http_core_main_conf_t  *cmcf;
    279     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
    280     h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
    281     if (h == NULL) {
    282         return NGX_ERROR;
    283     }
    284     *= ngx_http_auth_pam_handler;
    285     return NGX_OK;
    286 }
    287 static char *
    288 ngx_http_auth_pam(ngx_conf_t *cf, void *post, void *data)
    289 {
    290     ngx_str_t  *realm = data;
    291     size_t   len;
    292     u_char  *basic, *p;
    293     if (ngx_strcmp(realm->data, "off"== 0) {
    294         realm->len = 0;
    295         realm->data = (u_char *"";
    296         return NGX_CONF_OK;
    297     }
    298     len = sizeof("Basic realm=\"") - 1 + realm->len + 1;
    299     basic = ngx_palloc(cf->pool, len);
    300     if (basic == NULL) {
    301         return NGX_CONF_ERROR;
    302     }
    303     p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\""- 1);
    304     p = ngx_cpymem(p, realm->data, realm->len);
    305     *= '"';
    306     realm->len = len;
    307     realm->data = basic;
    308     return NGX_CONF_OK;
    309 }
    310 /* SVN Id: $Id: ngx_http_auth_pam_module.c 4487 2010-11-15 09:57:03Z sto $ */

  • 相关阅读:
    20210312
    20210311
    20210310
    例5-1
    例5-2
    例4-12-2
    例4-12
    例4-11
    例4-10
    例4-9
  • 原文地址:https://www.cnblogs.com/xewnwsl2001/p/1897120.html
Copyright © 2011-2022 走看看