mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
140 lines
4.4 KiB
C
140 lines
4.4 KiB
C
/*
|
|
This file is part of GNU libmicrohttpd
|
|
Copyright (C) 2024 Evgeny Grin (Karlson2k)
|
|
|
|
GNU libmicrohttpd is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
GNU libmicrohttpd is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
/**
|
|
* @file src/mhd2/auth_basic.c
|
|
* @brief The implementation of the Basic Authorization header parser
|
|
* @author Karlson2k (Evgeny Grin)
|
|
*/
|
|
|
|
#include "mhd_sys_options.h"
|
|
|
|
#include "sys_bool_type.h"
|
|
#include "sys_base_types.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "mhd_cntnr_ptr.h"
|
|
|
|
#include "mhd_assert.h"
|
|
|
|
#include "mhd_str_types.h"
|
|
#include "mhd_connection.h"
|
|
|
|
#include "mhd_str.h"
|
|
#include "stream_funcs.h"
|
|
#include "request_auth_get.h"
|
|
|
|
#include "auth_basic.h"
|
|
|
|
static MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_
|
|
enum MHD_StatusCode
|
|
find_and_parse_auth_basic (struct MHD_Request *restrict req)
|
|
{
|
|
struct MHD_String token68;
|
|
size_t alloc_size;
|
|
size_t dec_size;
|
|
char *dec_buf;
|
|
char *colon_ptr;
|
|
|
|
mhd_assert (NULL == req->auth.basic.intr.username.cstr);
|
|
|
|
if (! mhd_request_get_auth_header_value (req,
|
|
mhd_AUTH_HDR_BASIC,
|
|
&token68))
|
|
return MHD_SC_AUTH_ABSENT;
|
|
|
|
mhd_assert (NULL != token68.cstr);
|
|
|
|
if (0 == token68.len)
|
|
{
|
|
/* Zero-length token68 */
|
|
req->auth.basic.intr.username.cstr = token68.cstr;
|
|
mhd_assert (0 == req->auth.basic.intr.username.len);
|
|
mhd_assert (NULL == req->auth.basic.intr.password.cstr);
|
|
mhd_assert (0 == req->auth.basic.intr.password.len);
|
|
return MHD_SC_OK;
|
|
}
|
|
|
|
alloc_size = mhd_base64_max_dec_size (token68.len) + 1;
|
|
dec_buf = (char *)
|
|
mhd_stream_alloc_memory (mhd_CNTNR_PTR (req, \
|
|
struct MHD_Connection, \
|
|
rq),
|
|
alloc_size);
|
|
if (NULL == dec_buf)
|
|
return MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA;
|
|
|
|
/* The 'dec_buf' remains allocated until start of sending reply or until
|
|
end of the request processing. */
|
|
|
|
dec_size = mhd_base64_to_bin_n (token68.cstr,
|
|
token68.len,
|
|
dec_buf,
|
|
alloc_size);
|
|
if (0 == dec_size)
|
|
return MHD_SC_REQ_AUTH_DATA_BROKEN;
|
|
|
|
dec_buf[dec_size] = 0; /* Zero-terminate the result */
|
|
req->auth.basic.intr.username.cstr = dec_buf;
|
|
colon_ptr = memchr (dec_buf, ':', dec_size);
|
|
if (NULL == colon_ptr)
|
|
{
|
|
/* No password provided. Only username. */
|
|
req->auth.basic.intr.username.len = dec_size;
|
|
mhd_assert (NULL == req->auth.basic.intr.password.cstr);
|
|
mhd_assert (0 == req->auth.basic.intr.password.len);
|
|
return MHD_SC_OK;
|
|
}
|
|
*colon_ptr = 0; /* Zero-terminate the username */
|
|
req->auth.basic.intr.username.len = (size_t) (colon_ptr - dec_buf);
|
|
req->auth.basic.intr.password.cstr = colon_ptr + 1;
|
|
mhd_assert ((req->auth.basic.intr.username.len + 1) <= dec_size);
|
|
req->auth.basic.intr.password.len =
|
|
dec_size - (req->auth.basic.intr.username.len + 1);
|
|
return MHD_SC_OK;
|
|
}
|
|
|
|
|
|
MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_
|
|
MHD_FN_PAR_OUT_ (2) enum MHD_StatusCode
|
|
mhd_request_get_auth_basic_creds (
|
|
struct MHD_Request *restrict req,
|
|
const struct MHD_AuthBasicCreds **restrict v_auth_basic_creds)
|
|
{
|
|
enum MHD_StatusCode res;
|
|
mhd_assert (mhd_HTTP_STAGE_HEADERS_PROCESSED <=
|
|
mhd_CNTNR_CPTR (req, struct MHD_Connection, rq)->stage);
|
|
mhd_assert (mhd_HTTP_STAGE_REQ_RECV_FINISHED >=
|
|
mhd_CNTNR_CPTR (req, struct MHD_Connection, rq)->stage);
|
|
|
|
if (NULL != req->auth.basic.intr.username.cstr)
|
|
res = MHD_SC_OK;
|
|
else
|
|
res = find_and_parse_auth_basic (req);
|
|
|
|
if (MHD_SC_OK != res)
|
|
return res; /* Failure exit point */
|
|
|
|
*v_auth_basic_creds = &(req->auth.basic.extr);
|
|
|
|
return MHD_SC_OK; /* Success exit point */
|
|
}
|