LCOV - code coverage report
Current view: top level - tests/cwrap - mock_pam_responder.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 118 150 78.7 %
Date: 2015-10-19 Functions: 13 14 92.9 %

          Line data    Source code
       1             : /*
       2             :     Copyright (C) 2015 Red Hat
       3             : 
       4             :     SSSD tests: PAM tests
       5             : 
       6             :     This program is free software; you can redistribute it and/or modify
       7             :     it under the terms of the GNU General Public License as published by
       8             :     the Free Software Foundation; either version 3 of the License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     This program is distributed in the hope that it will be useful,
      12             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :     GNU General Public License for more details.
      15             : 
      16             :     You should have received a copy of the GNU General Public License
      17             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include <stdint.h>
      21             : #include <errno.h>
      22             : #include <sys/types.h>
      23             : #include "sss_cli.h"
      24             : 
      25             : #include "responder/pam/pamsrv.h"
      26             : #include "responder/common/responder_packet.h"
      27             : #include "providers/data_provider.h"
      28             : 
      29             : /* FIXME - move the definition to a private header */
      30             : struct sss_packet {
      31             :     size_t memsize;
      32             : 
      33             :     /* Structure of the buffer:
      34             :     * Bytes    Content
      35             :     * ---------------------------------
      36             :     * 0-15     packet header
      37             :     * 0-3      packet length (uint32_t)
      38             :     * 4-7      command type (uint32_t)
      39             :     * 8-11     status (uint32_t)
      40             :     * 12-15    reserved
      41             :     * 16+      packet body */
      42             :     uint8_t *buffer;
      43             : 
      44             :     /* io pointer */
      45             :     size_t iop;
      46             : };
      47             : 
      48             : /* Make linker happy */
      49          16 : int __wrap_sss_parse_name_for_domains(TALLOC_CTX *memctx,
      50             :                                       struct sss_domain_info *domains,
      51             :                                       const char *default_domain,
      52             :                                       const char *orig,
      53             :                                       char **domain, char **name)
      54             : {
      55             :     char *atsign;
      56             : 
      57          16 :     atsign = strrchr(orig, '@');
      58          16 :     if (atsign == NULL) {
      59          16 :         *domain = NULL;
      60          16 :         *name = talloc_strdup(memctx, orig);
      61          16 :         if (*name == NULL) {
      62           0 :             return ENOMEM;
      63             :         }
      64          16 :         return EOK;
      65             :     }
      66             : 
      67           0 :     *name = talloc_strndup(memctx, orig, atsign - orig);
      68           0 :     *domain = talloc_strdup(memctx, atsign+1);
      69           0 :     if (*name == NULL || *domain == NULL) {
      70           0 :         return ENOMEM;
      71             :     }
      72             : 
      73           0 :     return EOK;
      74             : }
      75             : 
      76          32 : void __wrap_sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen)
      77             : {
      78          32 :     *body = packet->buffer;
      79          32 :     *blen = packet->memsize;
      80          32 : }
      81             : 
      82             : static struct cli_ctx *
      83          16 : mock_pam_cctx(TALLOC_CTX *mem_ctx,
      84             :               enum sss_cli_command cmd,
      85             :               int cli_protocol_version,
      86             :               struct sss_cli_req_data *rd)
      87             : {
      88          16 :     struct cli_ctx *cctx = NULL;
      89             :     int ret;
      90             : 
      91          16 :     cctx = talloc_zero(mem_ctx, struct cli_ctx);
      92          16 :     if (!cctx) goto fail;
      93             : 
      94          16 :     cctx->creq = talloc_zero(cctx, struct cli_request);
      95          16 :     if (cctx->creq == NULL) goto fail;
      96             : 
      97          16 :     cctx->cli_protocol_version = talloc_zero(cctx,
      98             :                                              struct cli_protocol_version);
      99          16 :     if (cctx->cli_protocol_version == NULL) goto fail;
     100             : 
     101          16 :     cctx->cli_protocol_version->version = cli_protocol_version;
     102             : 
     103          16 :     cctx->creq = talloc_zero(cctx, struct cli_request);
     104          16 :     if (cctx->creq == NULL) goto fail;
     105             : 
     106          16 :     ret = sss_packet_new(cctx->creq, 0, cmd, &cctx->creq->in);
     107          16 :     if (ret != EOK) goto fail;
     108             : 
     109          16 :     cctx->rctx = talloc_zero(cctx, struct resp_ctx);
     110          16 :     if (cctx->rctx == NULL) goto fail;
     111             : 
     112          16 :     cctx->creq->in->buffer = discard_const(rd->data);
     113          16 :     cctx->creq->in->memsize = rd->len;
     114             : 
     115          16 :     return cctx;
     116             : 
     117             : fail:
     118           0 :     talloc_free(cctx);
     119           0 :     return NULL;
     120             : }
     121             : 
     122             : static struct pam_data *
     123          16 : mock_pam_data(TALLOC_CTX *mem_ctx, enum sss_cli_command cmd)
     124             : {
     125          16 :     struct pam_data *pd = NULL;
     126             : 
     127          16 :     pd = talloc_zero(mem_ctx, struct pam_data);
     128          16 :     if (pd == NULL) goto fail;
     129             : 
     130          16 :     pd->cmd = cmd;
     131          16 :     pd->authtok = sss_authtok_new(pd);
     132          16 :     pd->newauthtok = sss_authtok_new(pd);
     133          16 :     if (pd->authtok == NULL || pd->newauthtok == NULL) goto fail;
     134             : 
     135          16 :     return pd;
     136             : 
     137             : fail:
     138           0 :     talloc_free(pd);
     139           0 :     return NULL;
     140             : }
     141             : 
     142          10 : static bool authtok_matches(struct sss_auth_token *authtok,
     143             :                             const char *exp_pass)
     144             : {
     145             :     int ret;
     146             :     const char *password;
     147             :     size_t pwlen;
     148             : 
     149          10 :     ret = sss_authtok_get_password(authtok, &password, &pwlen);
     150          10 :     if (ret != EOK) {
     151           0 :         return EINVAL;
     152             :     }
     153             : 
     154          10 :     if (strncmp(password, exp_pass, pwlen) == 0) {
     155           5 :         return true;
     156             :     }
     157             : 
     158           5 :     return false;
     159             : }
     160             : 
     161          10 : static int test_auth(struct pam_data *pd, const char *exp_pass)
     162             : {
     163          10 :     pd->pam_status = PAM_AUTH_ERR;
     164             : 
     165          10 :     if (authtok_matches(pd->authtok, exp_pass) == true) {
     166           5 :         pd->pam_status = PAM_SUCCESS;
     167             :     }
     168             : 
     169          10 :     return EOK;
     170             : }
     171             : 
     172           0 : static int test_chauthtok(struct pam_data *pd, const char *exp_pass)
     173             : {
     174           0 :     pd->pam_status = PAM_AUTH_ERR;
     175             : 
     176           0 :     if (authtok_matches(pd->authtok, exp_pass) == true
     177           0 :             && authtok_matches(pd->newauthtok, exp_pass) == true) {
     178           0 :         pd->pam_status = PAM_SUCCESS;
     179             :     }
     180             : 
     181           0 :     return EOK;
     182             : }
     183             : 
     184          10 : static int mock_pam_auth(struct pam_data *pd)
     185             : {
     186          10 :     errno_t ret = PAM_SYSTEM_ERR;
     187             : 
     188          10 :     if (strcmp(pd->user, "testuser") == 0) {
     189           5 :         ret = test_auth(pd, "secret");
     190           5 :     } else if (strcmp(pd->user, "domtest") == 0) {
     191           1 :         pd->pam_status = PAM_AUTH_ERR;
     192           1 :         if (pd->requested_domains[0] != NULL
     193           1 :                 && strcmp(pd->requested_domains[0], "mydomain") == 0
     194           1 :                 && pd->requested_domains[1] == NULL) {
     195           1 :             pd->pam_status = PAM_SUCCESS;
     196             :         }
     197             : 
     198           1 :         ret = EOK;
     199           4 :     } else if (strcmp(pd->user, "retrytest") == 0) {
     200           4 :         ret = test_auth(pd, "retried_secret");
     201             :     }
     202             : 
     203          10 :     return ret;
     204             : }
     205             : 
     206           1 : static int mock_pam_chauthtok(struct pam_data *pd)
     207             : {
     208           1 :     errno_t ret = PAM_SYSTEM_ERR;
     209             : 
     210           1 :     if (strcmp(pd->user, "testuser") == 0) {
     211           1 :         ret = test_auth(pd, "secret");
     212           0 :     } else if (strcmp(pd->user, "domtest") == 0) {
     213           0 :         pd->pam_status = PAM_AUTH_ERR;
     214           0 :         if (pd->requested_domains[0] != NULL
     215           0 :                 && strcmp(pd->requested_domains[0], "mydomain") == 0
     216           0 :                 && pd->requested_domains[1] == NULL) {
     217           0 :             pd->pam_status = PAM_SUCCESS;
     218             :         }
     219             : 
     220           0 :         ret = EOK;
     221           0 :     } else if (strcmp(pd->user, "retrytest") == 0) {
     222           0 :         ret = test_auth(pd, "retried_secret");
     223             :     }
     224             : 
     225           1 :     return ret;
     226             : }
     227             : 
     228           2 : static int mock_pam_acct(struct pam_data *pd)
     229             : {
     230           2 :     if (strcmp(pd->user, "allowed_user") == 0) {
     231           1 :         pd->pam_status = PAM_SUCCESS;
     232           1 :     } else if (strcmp(pd->user, "denied_user") == 0) {
     233           1 :         pd->pam_status = PAM_PERM_DENIED;
     234             :     }
     235             : 
     236           2 :     return EOK;
     237             : }
     238             : 
     239           1 : static int mock_pam_set_cred(struct pam_data *pd)
     240             : {
     241           1 :     const char *cred_msg = "CREDS=set";
     242             : 
     243           1 :     pd->pam_status = PAM_SUCCESS;
     244           1 :     return pam_add_response(pd, SSS_ALL_ENV_ITEM,
     245           1 :                             strlen(cred_msg)+1,
     246             :                             (const uint8_t *) cred_msg);
     247             : }
     248             : 
     249           1 : static int mock_pam_open_session(struct pam_data *pd)
     250             : {
     251           1 :     const char *session_msg = "SESSION=open";
     252             : 
     253           1 :     pd->pam_status = PAM_SUCCESS;
     254           1 :     return pam_add_response(pd, SSS_ALL_ENV_ITEM,
     255           1 :                             strlen(session_msg)+1,
     256             :                             (const uint8_t *) session_msg);
     257             : }
     258             : 
     259           1 : static int mock_pam_close_session(struct pam_data *pd)
     260             : {
     261           1 :     pd->pam_status = PAM_SUCCESS;
     262           1 :     return EOK;
     263             : }
     264             : 
     265             : /* Receives a packed response and returns a mock reply */
     266          16 : int __wrap_sss_pam_make_request(enum sss_cli_command cmd,
     267             :                                 struct sss_cli_req_data *rd,
     268             :                                 uint8_t **repbuf, size_t *replen,
     269             :                                 int *errnop)
     270             : {
     271             :     errno_t ret;
     272             :     TALLOC_CTX *test_ctx;
     273             :     struct cli_ctx *cctx;
     274             :     struct pam_data *pd;
     275             : 
     276          16 :     test_ctx = talloc_new(NULL);
     277          16 :     if (test_ctx == NULL) {
     278           0 :         return ENOMEM;
     279             :     }
     280             : 
     281             :     /* The PAM responder functions expect both cctx and pd to be talloc
     282             :      * contexts
     283             :      */
     284          16 :     cctx = mock_pam_cctx(test_ctx, cmd, 3, rd);
     285          16 :     pd = mock_pam_data(test_ctx, cmd);
     286          16 :     if (cctx == NULL || pd == NULL) {
     287           0 :         ret = ENOMEM;
     288           0 :         goto done;
     289             :     }
     290             : 
     291          16 :     ret = pam_forwarder_parse_data(cctx, pd);
     292          16 :     if (ret != EOK) {
     293           0 :         goto done;
     294             :     }
     295             : 
     296          16 :     pd->pam_status = PAM_SYSTEM_ERR;
     297             : 
     298          16 :     if (cmd == SSS_PAM_AUTHENTICATE) {
     299           7 :         ret = mock_pam_auth(pd);
     300           9 :     } else if (cmd == SSS_PAM_ACCT_MGMT) {
     301           2 :         ret = mock_pam_acct(pd);
     302           7 :     } else if (cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
     303           3 :         ret = mock_pam_auth(pd);
     304           4 :     } else if (cmd == SSS_PAM_CHAUTHTOK) {
     305           1 :         ret = mock_pam_chauthtok(pd);
     306           3 :     } else if (cmd == SSS_PAM_SETCRED) {
     307           1 :         ret = mock_pam_set_cred(pd);
     308           2 :     } else if (cmd == SSS_PAM_OPEN_SESSION) {
     309           1 :         ret = mock_pam_open_session(pd);
     310           1 :     } else if (cmd == SSS_PAM_CLOSE_SESSION) {
     311           1 :         ret = mock_pam_close_session(pd);
     312             :     }
     313             : 
     314          16 :     if (ret != EOK) {
     315           0 :         goto done;
     316             :     }
     317             : 
     318          16 :     ret = pamsrv_reply_packet(cctx->creq, pd, cmd, &cctx->creq->out);
     319          16 :     if (ret != EOK) {
     320           0 :         goto done;
     321             :     }
     322             : 
     323          16 :     *repbuf = malloc(cctx->creq->out->memsize);
     324          16 :     memcpy(*repbuf, cctx->creq->out->buffer, cctx->creq->out->memsize);
     325          16 :     *replen = cctx->creq->out->memsize;
     326             : 
     327          16 :     ret = EOK;
     328             : done:
     329          16 :     return ret;
     330             : }

Generated by: LCOV version 1.10