Skip to content

Commit

Permalink
Merge branch 'main' into coverity
Browse files Browse the repository at this point in the history
  • Loading branch information
sreimers committed Aug 30, 2023
2 parents 8abe15d + 36b80da commit fa5eb3e
Show file tree
Hide file tree
Showing 11 changed files with 459 additions and 19 deletions.
29 changes: 29 additions & 0 deletions include/re_httpauth.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@
*/


/** HTTP digest request challenge */
struct httpauth_digest_chall_req {
char *realm;
char *domain;
char *nonce;
char *opaque;
bool stale;
char *algorithm;
char *qop;

/* optional */
char *charset;
bool userhash;
};

/** HTTP Digest Challenge */
struct httpauth_digest_chall {
struct pl realm;
Expand All @@ -15,6 +30,9 @@ struct httpauth_digest_chall {
struct pl stale;
struct pl algorithm;
struct pl qop;
struct pl domain;
struct pl charset;
struct pl userhash;
};

/** HTTP Digest response */
Expand Down Expand Up @@ -62,6 +80,17 @@ int httpauth_digest_make_response(struct httpauth_digest_resp **resp,
int httpauth_digest_response_encode(const struct httpauth_digest_resp *resp,
struct mbuf *mb);


int httpauth_digest_chall_req_print(struct re_printf *pf,
const struct httpauth_digest_chall_req *req);
int httpauth_digest_chall_request(struct httpauth_digest_chall_req **preq,
const char *realm, const char *etag, const char *qop);
int httpauth_digest_chall_request_full(struct httpauth_digest_chall_req **preq,
const char *real, const char *domain, const char *etag,
const char *opaque, const bool stale, const char *algo,
const char *qop, const char *charset, const bool userhash);


struct httpauth_basic *httpauth_basic_alloc(void);
int httpauth_basic_decode(struct httpauth_basic *basic,
const struct pl *hval);
Expand Down
2 changes: 2 additions & 0 deletions include/re_sip.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg);
bool sip_dialog_rseq_valid(struct sip_dialog *dlg, const struct sip_msg *msg);
const char *sip_dialog_callid(const struct sip_dialog *dlg);
int sip_dialog_set_callid(struct sip_dialog *dlg, const char *callid);
void sip_dialog_set_srcport(struct sip_dialog *dlg, uint16_t srcport);
uint16_t sip_dialog_srcport(struct sip_dialog *dlg);
const char *sip_dialog_uri(const struct sip_dialog *dlg);
uint32_t sip_dialog_lseq(const struct sip_dialog *dlg);
enum sip_transp sip_dialog_tp(const struct sip_dialog *dlg);
Expand Down
14 changes: 7 additions & 7 deletions include/re_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,18 +317,18 @@ typedef int re_sock_t;

#define RE_ARG_SIZE(type) \
_Generic((type), \
bool: sizeof(bool), \
char: sizeof(char), \
unsigned char: sizeof(unsigned char), \
short: sizeof(short), \
unsigned short: sizeof(unsigned short), \
bool: sizeof(int), \
char: sizeof(int), \
unsigned char: sizeof(unsigned int), \
short: sizeof(int), \
unsigned short: sizeof(unsigned int), \
int: sizeof(int), \
unsigned int: sizeof(unsigned int), \
long: sizeof(long), \
unsigned long: sizeof(unsigned long), \
long long: sizeof(long long), \
unsigned long long: sizeof(unsigned long long), \
float: sizeof(float), \
float: sizeof(double), \
double: sizeof(double), \
char const*: sizeof(char const *), \
char*: sizeof(char *), \
Expand Down Expand Up @@ -375,7 +375,7 @@ typedef int re_sock_t;
err = EOVERFLOW; \
goto out; \
} \
if (unlikely(sz > sizeof(type))) { \
if (unlikely(sz != sizeof(type))) { \
re_assert(0 && "RE_VA_ARG: arg is not compatible"); \
err = EOVERFLOW; \
goto out; \
Expand Down
15 changes: 15 additions & 0 deletions src/fmt/print.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum length_modifier {
LENMOD_NONE = 0,
LENMOD_LONG = 1,
LENMOD_LONG_LONG = 2,
LENMOD_INT64 = 3,
LENMOD_SIZE = 42,
};

Expand Down Expand Up @@ -219,6 +220,10 @@ static int vhprintf(const char *fmt, va_list ap, re_vprintf_h *vph, void *arg,
case 'i':
switch (lenmod) {

case LENMOD_INT64:
RE_VA_ARG(ap, sn, int64_t, safe);
break;

case LENMOD_SIZE:
RE_VA_ARG(ap, sn, ssize_t, safe);
break;
Expand Down Expand Up @@ -335,6 +340,10 @@ static int vhprintf(const char *fmt, va_list ap, re_vprintf_h *vph, void *arg,
case 'u':
switch (lenmod) {

case LENMOD_INT64:
RE_VA_ARG(ap, n, uint64_t, safe);
break;

case LENMOD_SIZE:
RE_VA_ARG(ap, n, size_t, safe);
break;
Expand Down Expand Up @@ -400,6 +409,11 @@ static int vhprintf(const char *fmt, va_list ap, re_vprintf_h *vph, void *arg,
fm = true;
break;

case 'L':
lenmod = LENMOD_INT64;
fm = true;
break;

case 'j':
RE_VA_ARG(ap, sa, struct sa *, safe);
if (!sa)
Expand Down Expand Up @@ -500,6 +514,7 @@ static int vhprintf(const char *fmt, va_list ap, re_vprintf_h *vph, void *arg,
* %H (re_printf_h *, void *) Print handler with argument
* %v (char *fmt, va_list *) Variable argument list
* %m (int) Describe an error code
* %L (uint64_t/int64_t) 64-bit length modifier for %i, %d, %x and %u
* </pre>
*
* Reserved for the future:
Expand Down
185 changes: 184 additions & 1 deletion src/httpauth/digest.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
/**
* @file digest.c HTTP Digest authentication (RFC 2617)
* @file digest.c HTTP Digest authentication (RFC 2617) - obsolete
* HTTP Digest authentication (RFC 7616) - wip
*
* Copyright (C) 2010 Creytiv.com
*/
#include <string.h>
#include <time.h>
#include <re_types.h>
#include <re_fmt.h>
#include <re_mbuf.h>
#include <re_mem.h>
#include <re_md5.h>
#include <re_sha.h>
#include <re_sys.h>
#include <re_httpauth.h>

Expand Down Expand Up @@ -410,3 +413,183 @@ int httpauth_digest_response_encode(const struct httpauth_digest_resp *resp,
mbuf_set_pos(mb, 0);
return err;
}


static void httpauth_digest_chall_req_destructor(void *arg)
{
struct httpauth_digest_chall_req *req = arg;

mem_deref(req->realm);
mem_deref(req->domain);
mem_deref(req->nonce);
mem_deref(req->opaque);
mem_deref(req->algorithm);
mem_deref(req->qop);
mem_deref(req->charset);
}


static int generate_nonce(char **pnonce, const time_t ts,
const char *etag, const char *secret)
{
struct mbuf *mb = NULL;
char *nonce = NULL;
uint8_t hash [SHA256_DIGEST_LENGTH];
int err = 0;

mb = mbuf_alloc(32);
if (!mb)
return ENOMEM;

if (str_isset(secret))
err = mbuf_printf(mb, "%"PRIu64":%s:%s",
(uint64_t)ts, etag, secret);
else
err = mbuf_printf(mb, "%"PRIu64":%s", (uint64_t)ts, etag);

if (err)
goto out;

sha256(mb->buf, mb->end, hash);
mbuf_rewind(mb);

err = mbuf_printf(mb, "%w%016"PRIx64"", hash, sizeof(hash),
(uint64_t)ts);
if (err)
goto out;

mbuf_set_pos(mb, 0);
err = mbuf_strdup(mb, &nonce, mbuf_get_left(mb));

out:
if (err)
mem_deref(nonce);
else
*pnonce = nonce;

mem_deref(mb);

return err;
}


/**
* Prints / encodes an HTTP digest request challenge
*
* @param pf Re_printf object
* @param req Request to print
*
* @return 0 if success, otherwise errorcode
*/
int httpauth_digest_chall_req_print(struct re_printf *pf,
const struct httpauth_digest_chall_req *req)
{
int err = 0;

if (!req)
return EINVAL;

/* historical reason quoted strings: */
/* realm, domain, nonce, opaque, qop */
/* historical reason unquoted strings: */
/* stale, algorithm */
err = re_hprintf(pf, "Digest realm=\"%s\", "
"qop=\"%s\", nonce=\"%s\", algorithm=%s",
req->realm, req->qop, req->nonce, req->algorithm);

if (str_isset(req->opaque))
err |= re_hprintf(pf, ", opaque=\"%s\"", req->opaque);
if (str_isset(req->domain))
err |= re_hprintf(pf, ", domain=\"%s\"", req->domain);
if (req->stale)
err |= re_hprintf(pf, ", stale=true");
if (str_isset(req->charset))
err |= re_hprintf(pf, ", charset=\"%s\"", req->charset);
if (req->userhash)
err |= re_hprintf(pf, ", userhash=true");

return err;
}


/**
* Create a digest authentication request
*
* @param preq Httpauth_digest_chall_req object ptr
* @param realm Realm
* @param etag Changing data for nonce creation
* (HTTP ETag header / SIP msg src address)
* @param qop Quality of protection
*
* @return 0 if success, otherwise errorcode
*/
int httpauth_digest_chall_request(struct httpauth_digest_chall_req **preq,
const char *realm, const char *etag, const char *qop)
{
return httpauth_digest_chall_request_full(preq, realm, NULL, etag,
NULL, false, NULL, qop, NULL, false);
}


/**
* Create a full configurable digest authentication request
*
* @param preq Httpauth_digest_chall_req object ptr
* @param realm Realm
* @param domain Domain (not used in SIP)
* @param etag Changing data for nonce creation
* (HTTP ETag header / SIP msg src address)
* @param opaque Opaque
* @param stale Stale
* @param algo Supported algorithm (MD5, SHA1, SHA256 and sess versions)
* @param qop Quality of protection
* @param charset Character set used (not used in SIP)
* @param userhash Userhash support (not used in SIP)
*
* @return 0 if success, otherwise errorcode
*/
int httpauth_digest_chall_request_full(struct httpauth_digest_chall_req **preq,
const char *realm, const char *domain, const char *etag,
const char *opaque, const bool stale, const char *algo,
const char *qop, const char *charset, const bool userhash)
{
struct httpauth_digest_chall_req *req = NULL;
int err = 0;

if (!preq || !realm || !etag || !qop)
return EINVAL;

req = mem_zalloc(sizeof(*req), httpauth_digest_chall_req_destructor);
if (!req)
return ENOMEM;

req->stale = stale;
req->userhash = userhash;
err = str_dup(&req->realm, realm);
err |= str_dup(&req->qop, qop);

if (str_isset(algo))
err |= str_dup(&req->algorithm, algo);
else
err |= str_dup(&req->algorithm, "MD5");

if (str_isset(domain))
err |= str_dup(&req->domain, domain);
if (str_isset(opaque))
err |= str_dup(&req->opaque, opaque);
if (str_isset(charset) && str_casecmp(charset, "UTF-8") == 0)
err |= str_dup(&req->charset, charset);

if (err)
goto out;

err = generate_nonce(&req->nonce, time(NULL), etag, NULL);

out:
if (err)
mem_deref(req);
else
*preq = req;

return err;
}
32 changes: 32 additions & 0 deletions src/sip/dialog.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct sip_dialog {
uint32_t rseq;
size_t cpos;
enum sip_transp tp;
uint32_t srcport;
};


Expand Down Expand Up @@ -578,6 +579,37 @@ int sip_dialog_set_callid(struct sip_dialog *dlg, const char *callid)
}


/**
* Set TCP source port for a SIP Dialog
*
* @param dlg SIP Dialog
* @param srcport The TCP source port to be used
*/
void sip_dialog_set_srcport(struct sip_dialog *dlg, uint16_t srcport)
{
if (!dlg)
return;

dlg->srcport = srcport;
}


/**
* Get TCP source port for a SIP Dialog
*
* @param dlg SIP Dialog
*
* @return TCP source port
*/
uint16_t sip_dialog_srcport(struct sip_dialog *dlg)
{
if (!dlg)
return 0;

return dlg->srcport;
}


/**
* Get the local sequence number from a SIP Dialog
*
Expand Down
Loading

0 comments on commit fa5eb3e

Please sign in to comment.