LCOV - code coverage report
Current view: top level - libcli/http/gensec - basic.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 51 82 62.2 %
Date: 2024-04-21 15:09:00 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    HTTP library - Basic authentication mechanism gensec module
       5             : 
       6             :    Copyright (C) 2014 Samuel Cabrero <samuelcabrero@kernevil.me>
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include <tevent.h>
      24             : #include "lib/util/tevent_ntstatus.h"
      25             : #include "auth/auth.h"
      26             : #include "auth/gensec/gensec.h"
      27             : #include "auth/gensec/gensec_internal.h"
      28             : #include "auth/credentials/credentials.h"
      29             : #include "lib/util/base64.h"
      30             : 
      31             : _PUBLIC_ NTSTATUS gensec_http_basic_init(TALLOC_CTX *);
      32             : 
      33             : struct gensec_http_basic_state {
      34             :         enum {
      35             :                 GENSEC_HTTP_BASIC_START,
      36             :                 GENSEC_HTTP_BASIC_DONE,
      37             :                 GENSEC_HTTP_BASIC_ERROR,
      38             :         } step;
      39             : };
      40             : 
      41          14 : static NTSTATUS gensec_http_basic_client_start(struct gensec_security *gensec)
      42             : {
      43           0 :         struct gensec_http_basic_state *state;
      44             : 
      45          14 :         state = talloc_zero(gensec, struct gensec_http_basic_state);
      46          14 :         if (state == NULL) {
      47           0 :                 return NT_STATUS_NO_MEMORY;
      48             :         }
      49          14 :         gensec->private_data = state;
      50             : 
      51          14 :         state->step = GENSEC_HTTP_BASIC_START;
      52             : 
      53          14 :         return NT_STATUS_OK;
      54             : }
      55             : 
      56             : struct gensec_http_basic_update_state {
      57             :         NTSTATUS status;
      58             :         DATA_BLOB out;
      59             : };
      60             : 
      61             : static NTSTATUS gensec_http_basic_update_internal(struct gensec_security *gensec_ctx,
      62             :                                                   TALLOC_CTX *mem_ctx,
      63             :                                                   const DATA_BLOB in,
      64             :                                                   DATA_BLOB *out);
      65             : 
      66          14 : static struct tevent_req *gensec_http_basic_update_send(TALLOC_CTX *mem_ctx,
      67             :                                                     struct tevent_context *ev,
      68             :                                                     struct gensec_security *gensec_security,
      69             :                                                     const DATA_BLOB in)
      70             : {
      71          14 :         struct tevent_req *req = NULL;
      72          14 :         struct gensec_http_basic_update_state *state = NULL;
      73           0 :         NTSTATUS status;
      74             : 
      75          14 :         req = tevent_req_create(mem_ctx, &state,
      76             :                                 struct gensec_http_basic_update_state);
      77          14 :         if (req == NULL) {
      78           0 :                 return NULL;
      79             :         }
      80             : 
      81          14 :         status = gensec_http_basic_update_internal(gensec_security,
      82             :                                                    state, in,
      83          14 :                                                    &state->out);
      84          14 :         state->status = status;
      85          14 :         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
      86           0 :                 tevent_req_done(req);
      87           0 :                 return tevent_req_post(req, ev);
      88             :         }
      89          14 :         if (tevent_req_nterror(req, status)) {
      90           0 :                 return tevent_req_post(req, ev);
      91             :         }
      92             : 
      93          14 :         tevent_req_done(req);
      94          14 :         return tevent_req_post(req, ev);
      95             : }
      96             : 
      97          14 : static NTSTATUS gensec_http_basic_update_internal(struct gensec_security *gensec_ctx,
      98             :                                                   TALLOC_CTX *mem_ctx,
      99             :                                                   const DATA_BLOB in,
     100             :                                                   DATA_BLOB *out)
     101             : {
     102           0 :         struct gensec_http_basic_state *state;
     103           0 :         struct cli_credentials *creds;
     104           0 :         char *tmp, *b64;
     105             : 
     106          14 :         state = talloc_get_type_abort(gensec_ctx->private_data,
     107             :                                       struct gensec_http_basic_state);
     108          14 :         creds = gensec_get_credentials(gensec_ctx);
     109             : 
     110          14 :         switch (gensec_ctx->gensec_role) {
     111          14 :         case GENSEC_CLIENT:
     112          14 :                 switch (state->step) {
     113          14 :                 case GENSEC_HTTP_BASIC_START:
     114          14 :                         tmp = talloc_asprintf(mem_ctx, "%s\\%s:%s",
     115             :                                         cli_credentials_get_domain(creds),
     116             :                                         cli_credentials_get_username(creds),
     117             :                                         cli_credentials_get_password(creds));
     118          14 :                         if (tmp == NULL) {
     119           0 :                                 state->step = GENSEC_HTTP_BASIC_ERROR;
     120           0 :                                 return NT_STATUS_NO_MEMORY;
     121             :                         }
     122          14 :                         *out = data_blob_string_const(tmp);
     123             : 
     124          14 :                         b64 = base64_encode_data_blob(mem_ctx, *out);
     125          14 :                         if (b64 == NULL) {
     126           0 :                                 state->step = GENSEC_HTTP_BASIC_ERROR;
     127           0 :                                 return NT_STATUS_NO_MEMORY;
     128             :                         }
     129          14 :                         TALLOC_FREE(tmp);
     130             : 
     131          14 :                         tmp = talloc_asprintf(mem_ctx, "Basic %s", b64);
     132          14 :                         if (tmp == NULL) {
     133           0 :                                 state->step = GENSEC_HTTP_BASIC_ERROR;
     134           0 :                                 return NT_STATUS_NO_MEMORY;
     135             :                         }
     136          14 :                         TALLOC_FREE(b64);
     137             : 
     138          14 :                         *out = data_blob_string_const(tmp);
     139          14 :                         state->step = GENSEC_HTTP_BASIC_DONE;
     140          14 :                         return NT_STATUS_OK;
     141             : 
     142           0 :                 case GENSEC_HTTP_BASIC_DONE:
     143             :                 case GENSEC_HTTP_BASIC_ERROR:
     144             :                 default:
     145           0 :                         break;
     146             :                 }
     147           0 :                 state->step = GENSEC_HTTP_BASIC_ERROR;
     148           0 :                 return NT_STATUS_INTERNAL_ERROR;
     149             : 
     150           0 :         case GENSEC_SERVER:
     151           0 :                 state->step = GENSEC_HTTP_BASIC_ERROR;
     152           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     153             :         }
     154             : 
     155           0 :         state->step = GENSEC_HTTP_BASIC_ERROR;
     156           0 :         return NT_STATUS_INTERNAL_ERROR;
     157             : }
     158             : 
     159          14 : static NTSTATUS gensec_http_basic_update_recv(struct tevent_req *req,
     160             :                                               TALLOC_CTX *out_mem_ctx,
     161             :                                               DATA_BLOB *out)
     162             : {
     163           0 :         struct gensec_http_basic_update_state *state =
     164          14 :                 tevent_req_data(req,
     165             :                 struct gensec_http_basic_update_state);
     166           0 :         NTSTATUS status;
     167             : 
     168          14 :         *out = data_blob_null;
     169             : 
     170          14 :         if (tevent_req_is_nterror(req, &status)) {
     171           0 :                 tevent_req_received(req);
     172           0 :                 return status;
     173             :         }
     174             : 
     175          14 :         *out = state->out;
     176          14 :         talloc_steal(out_mem_ctx, state->out.data);
     177          14 :         status = state->status;
     178          14 :         tevent_req_received(req);
     179          14 :         return status;
     180             : }
     181             : 
     182             : static const struct gensec_security_ops gensec_http_basic_security_ops = {
     183             :         .name           = "http_basic",
     184             :         .auth_type      = 0,
     185             :         .client_start   = gensec_http_basic_client_start,
     186             :         .update_send    = gensec_http_basic_update_send,
     187             :         .update_recv    = gensec_http_basic_update_recv,
     188             :         .enabled        = true,
     189             :         .priority       = GENSEC_EXTERNAL,
     190             : };
     191             : 
     192       52291 : _PUBLIC_ NTSTATUS gensec_http_basic_init(TALLOC_CTX *ctx)
     193             : {
     194        1208 :         NTSTATUS status;
     195             : 
     196       52291 :         status = gensec_register(ctx, &gensec_http_basic_security_ops);
     197       52291 :         if (!NT_STATUS_IS_OK(status)) {
     198           0 :                 DEBUG(0, ("Failed to register '%s' gensec backend!\n",
     199             :                                 gensec_http_basic_security_ops.name));
     200           0 :                 return status;
     201             :         }
     202             : 
     203       52291 :         return status;
     204             : }

Generated by: LCOV version 1.14