-/* $OpenBSD: agentx.c,v 1.13 2021/10/23 17:13:50 martijn Exp $ */
+/* $OpenBSD: agentx.c,v 1.14 2021/10/24 18:03:27 martijn Exp $ */
/*
* Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org>
*
static int agentx_request_cmp(struct agentx_request *,
struct agentx_request *);
static int agentx_strcat(char **, const char *);
+static int agentx_oidfill(struct ax_oid *, const uint32_t[], size_t,
+ const char **);
RB_PROTOTYPE_STATIC(ax_requests, agentx_request, axr_ax_requests,
agentx_request_cmp)
size_t oidlen, const char *descr, uint8_t timeout)
{
struct agentx_session *axs;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
-#ifdef AX_DEBUG
- agentx_log_ax_fatalx(ax, "%s: oidlen > %d", __func__,
- AGENTX_OID_MAX_LEN);
-#else
- errno = EINVAL;
- return NULL;
-#endif
- }
if ((axs = calloc(1, sizeof(*axs))) == NULL)
return NULL;
axs->axs_ax = ax;
axs->axs_timeout = timeout;
- for (i = 0; i < oidlen; i++)
- axs->axs_oid.aoi_id[i] = oid[i];
- axs->axs_oid.aoi_idlen = oidlen;
+ /* RFC 2741 section 6.2.1: may send a null Object Identifier */
+ if (oidlen == 0)
+ axs->axs_oid.aoi_idlen = oidlen;
+ else {
+ if (agentx_oidfill((&axs->axs_oid), oid, oidlen,
+ &errstr) == -1) {
+#ifdef AX_DEBUG
+ agentx_log_ax_fatalx(ax, "%s: %s", __func__, errstr);
+#else
+ return NULL;
+#endif
+ }
+ }
axs->axs_descr.aos_string = (unsigned char *)strdup(descr);
if (axs->axs_descr.aos_string == NULL) {
free(axs);
const uint32_t oid[], size_t oidlen, int active, int instance)
{
struct agentx_object *axo, axo_search;
- size_t i;
+ const char *errstr;
- for (i = 0; i < oidlen; i++)
- axo_search.axo_oid.aoi_id[i] = oid[i];
- axo_search.axo_oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&(axo_search.axo_oid), oid, oidlen, &errstr) == -1) {
+ if (oidlen > AGENTX_OID_MIN_LEN) {
+#ifdef AX_DEBUG
+ agentx_log_axc_fatalx(axc, "%s: %s", __func__, errstr);
+#else
+ agentx_log_axc_warnx(axc, "%s: %s", __func__, errstr);
+ return NULL;
+ }
+#endif
+ if (oidlen == 1)
+ axo_search.axo_oid.aoi_id[0] = oid[0];
+ axo_search.axo_oid.aoi_idlen = oidlen;
+ }
axo = RB_FIND(axc_objects, &(axc->axc_objects), &axo_search);
while (axo == NULL && !instance && axo_search.axo_oid.aoi_idlen > 0) {
const uint32_t oid[], size_t oidlen, int active, int inclusive)
{
struct agentx_object *axo, axo_search;
- size_t i;
+ const char *errstr;
- for (i = 0; i < oidlen; i++)
- axo_search.axo_oid.aoi_id[i] = oid[i];
- axo_search.axo_oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&(axo_search.axo_oid), oid, oidlen, &errstr) == -1) {
+ if (oidlen > AGENTX_OID_MIN_LEN) {
+#ifdef AX_DEBUG
+ agentx_log_axc_fatalx(axc, "%s: %s", __func__, errstr);
+#else
+ agentx_log_axc_warnx(axc, "%s: %s", __func__, errstr);
+ return NULL;
+#endif
+ }
+ if (oidlen == 1)
+ axo_search.axo_oid.aoi_id[0] = oid[0];
+ axo_search.axo_oid.aoi_idlen = oidlen;
+ }
axo = RB_NFIND(axc_objects, &(axc->axc_objects), &axo_search);
if (!inclusive && axo != NULL &&
size_t oidlen, const char *descr)
{
struct agentx_agentcaps *axa;
- size_t i;
+ const char *errstr;
if (axc->axc_dstate == AX_DSTATE_CLOSE)
agentx_log_axc_fatalx(axc, "%s: use after free", __func__);
return NULL;
axa->axa_axc = axc;
- for (i = 0; i < oidlen; i++)
- axa->axa_oid.aoi_id[i] = oid[i];
- axa->axa_oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&(axa->axa_oid), oid, oidlen, &errstr) == -1) {
+#ifdef AX_DEBUG
+ agentx_log_axc_fatalx(axc, "%s: %s", __func__, errstr);
+#else
+ agentx_log_axc_warnx(axc, "%s: %s", __func__, errstr);
+ return NULL;
+#endif
+ }
axa->axa_descr.aos_string = (unsigned char *)strdup(descr);
if (axa->axa_descr.aos_string == NULL) {
free(axa);
{
struct agentx_region *axr;
struct ax_oid tmpoid;
- size_t i;
+ const char *errstr;
if (axc->axc_dstate == AX_DSTATE_CLOSE)
agentx_log_axc_fatalx(axc, "%s: use after free", __func__);
- if (oidlen < 1) {
-#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axc, "%s: oidlen == 0", __func__);
-#else
- errno = EINVAL;
- return NULL;
-#endif
- }
- if (oidlen > AGENTX_OID_MAX_LEN) {
+
+ if (agentx_oidfill(&tmpoid, oid, oidlen, &errstr) == -1) {
#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axc, "%s: oidlen > %d", __func__,
- AGENTX_OID_MAX_LEN);
+ agentx_log_axc_fatalx(axc, "%s: %s", __func__, errstr);
#else
- errno = EINVAL;
return NULL;
#endif
+
}
-
- for (i = 0; i < oidlen; i++)
- tmpoid.aoi_id[i] = oid[i];
- tmpoid.aoi_idlen = oidlen;
TAILQ_FOREACH(axr, &(axc->axc_regions), axr_axc_regions) {
if (ax_oid_cmp(&(axr->axr_oid), &tmpoid) == 0) {
#ifdef AX_DEBUG
size_t oidlen)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
+ vb.avb_type = AX_DATA_TYPE_INTEGER;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
return NULL;
#endif
}
-
- vb.avb_type = AX_DATA_TYPE_INTEGER;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
- vb.avb_oid.aoi_idlen = oidlen;
vb.avb_data.avb_int32 = 0;
return agentx_index(axr, &vb, AXI_TYPE_NEW);
size_t oidlen)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
+ vb.avb_type = AX_DATA_TYPE_INTEGER;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
return NULL;
#endif
}
-
- vb.avb_type = AX_DATA_TYPE_INTEGER;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
- vb.avb_oid.aoi_idlen = oidlen;
vb.avb_data.avb_int32 = 0;
return agentx_index(axr, &vb, AXI_TYPE_ANY);
size_t oidlen, int32_t value)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
-#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
-#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
- return NULL;
-#endif
- }
if (value < 0) {
#ifdef AX_DEBUG
agentx_log_axc_fatalx(axr->axr_axc, "%s: value < 0", __func__);
}
vb.avb_type = AX_DATA_TYPE_INTEGER;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
- vb.avb_oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
+#ifdef AX_DEBUG
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
+#else
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
+ return NULL;
+#endif
+ }
vb.avb_data.avb_int32 = value;
return agentx_index(axr, &vb, AXI_TYPE_VALUE);
size_t oidlen)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
+ vb.avb_type = AX_DATA_TYPE_INTEGER;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
return NULL;
#endif
}
- vb.avb_type = AX_DATA_TYPE_INTEGER;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
- vb.avb_oid.aoi_idlen = oidlen;
-
return agentx_index(axr, &vb, AXI_TYPE_DYNAMIC);
}
size_t oidlen)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
+ vb.avb_type = AX_DATA_TYPE_OCTETSTRING;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
return NULL;
#endif
}
-
- vb.avb_type = AX_DATA_TYPE_OCTETSTRING;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
- vb.avb_oid.aoi_idlen = oidlen;
vb.avb_data.avb_ostring.aos_slen = 0;
vb.avb_data.avb_ostring.aos_string = NULL;
size_t oidlen, size_t vlen)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
-#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
-#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
- return NULL;
-#endif
- }
if (vlen == 0 || vlen > AGENTX_OID_MAX_LEN) {
#ifdef AX_DEBUG
agentx_log_axc_fatalx(axr->axr_axc, "%s: invalid string "
}
vb.avb_type = AX_DATA_TYPE_OCTETSTRING;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
- vb.avb_oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
+#ifdef AX_DEBUG
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
+#else
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
+ return NULL;
+#endif
+ }
vb.avb_data.avb_ostring.aos_slen = vlen;
vb.avb_data.avb_ostring.aos_string = NULL;
size_t oidlen)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
+ vb.avb_type = AX_DATA_TYPE_OID;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
return NULL;
#endif
}
-
- vb.avb_type = AX_DATA_TYPE_OID;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
- vb.avb_oid.aoi_idlen = oidlen;
vb.avb_data.avb_oid.aoi_idlen = 0;
return agentx_index(axr, &vb, AXI_TYPE_DYNAMIC);
size_t oidlen, size_t vlen)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
-#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
-#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
- return NULL;
-#endif
- }
- if (vlen == 0 || vlen > AGENTX_OID_MAX_LEN) {
+ if (vlen < AGENTX_OID_MIN_LEN || vlen > AGENTX_OID_MAX_LEN) {
#ifdef AX_DEBUG
agentx_log_axc_fatalx(axr->axr_axc, "%s: invalid string "
"length: %zu\n", __func__, vlen);
}
vb.avb_type = AX_DATA_TYPE_OID;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
- vb.avb_oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
+#ifdef AX_DEBUG
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
+#else
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
+ return NULL;
+#endif
+ }
vb.avb_data.avb_oid.aoi_idlen = vlen;
return agentx_index(axr, &vb, AXI_TYPE_DYNAMIC);
size_t oidlen)
{
struct ax_varbind vb;
- size_t i;
+ const char *errstr;
- if (oidlen > AGENTX_OID_MAX_LEN) {
+ vb.avb_type = AX_DATA_TYPE_IPADDRESS;
+ if (agentx_oidfill(&(vb.avb_oid), oid, oidlen, &errstr) == -1) {
#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
return NULL;
#endif
}
-
- vb.avb_type = AX_DATA_TYPE_IPADDRESS;
- for (i = 0; i < oidlen; i++)
- vb.avb_oid.aoi_id[i] = oid[i];
vb.avb_data.avb_ostring.aos_string = NULL;
- vb.avb_oid.aoi_idlen = oidlen;
return agentx_index(axr, &vb, AXI_TYPE_DYNAMIC);
}
{
struct agentx_object *axo, **taxo, axo_search;
struct agentx_index *laxi;
+ const char *errstr;
int ready = 1;
size_t i, j;
if (axr->axr_dstate == AX_DSTATE_CLOSE)
agentx_log_axc_fatalx(axr->axr_axc, "%s: use after free",
__func__);
- if (oidlen < 1) {
-#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen == 0",
- __func__);
-#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen == 0",
- __func__);
- errno = EINVAL;
- return NULL;
-#endif
- }
- if (oidlen > AGENTX_OID_MAX_LEN) {
-#ifdef AX_DEBUG
- agentx_log_axc_fatalx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
-#else
- agentx_log_axc_warnx(axr->axr_axc, "%s: oidlen > %d",
- __func__, AGENTX_OID_MAX_LEN);
- errno = EINVAL;
- return NULL;
-#endif
- }
if (axilen > AGENTX_OID_INDEX_MAX_LEN) {
#ifdef AX_DEBUG
agentx_log_axc_fatalx(axr->axr_axc, "%s: indexlen > %d",
#endif
}
- for (i = 0; i < oidlen; i++)
- axo_search.axo_oid.aoi_id[i] = oid[i];
- axo_search.axo_oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&(axo_search.axo_oid), oid, oidlen, &errstr) == -1) {
+#ifdef AX_DEBUG
+ agentx_log_axc_fatalx(axr->axr_axc, "%s: %s", __func__, errstr);
+#else
+ agentx_log_axc_warnx(axr->axr_axc, "%s: %s", __func__, errstr);
+ return NULL;
+#endif
+ }
do {
if (RB_FIND(axc_objects, &(axr->axr_axc->axc_objects),
if (r == -1) {
axv->axv_vb.avb_data.avb_ostring.aos_string = NULL;
agentx_log_axg_warn(axv->axv_axg, "Couldn't bind string");
- agentx_varbind_error_type(axv,
- AX_PDU_ERROR_PROCESSINGERROR, 1);
+ agentx_varbind_error_type(axv, AX_PDU_ERROR_PROCESSINGERROR, 1);
return;
}
axv->axv_vb.avb_data.avb_ostring.aos_slen = r;
agentx_varbind_oid(struct agentx_varbind *axv, const uint32_t oid[],
size_t oidlen)
{
- size_t i;
+ const char *errstr;
axv->axv_vb.avb_type = AX_DATA_TYPE_OID;
- for (i = 0; i < oidlen; i++)
- axv->axv_vb.avb_data.avb_oid.aoi_id[i] = oid[i];
- axv->axv_vb.avb_data.avb_oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&(axv->axv_vb.avb_data.avb_oid),
+ oid, oidlen, &errstr) == -1) {
+#ifdef AX_DEBUG
+ agentx_log_axg_fatalx(axv->axv_axg, "%s: %s", __func__, errstr);
+#else
+ agentx_log_axg_warnx(axv->axv_axg, "%s: %s", __func__, errstr);
+ agentx_varbind_error_type(axv, AX_PDU_ERROR_PROCESSINGERROR, 1);
+ return;
+#endif
+ }
agentx_varbind_finalize(axv);
}
struct agentx_index *axi, const uint32_t *value, size_t oidlen)
{
struct ax_oid *curvalue, oid;
+ const char *errstr;
size_t i;
if (axi->axi_vb.avb_type != AX_DATA_TYPE_OID) {
#endif
}
curvalue = &(axv->axv_index[i].axv_idata.avb_oid);
- for (i = 0; i < oidlen; i++)
- oid.aoi_id[i] = value[i];
- oid.aoi_idlen = oidlen;
+ if (agentx_oidfill(&oid, value,
+ oidlen, &errstr) == -1) {
+#ifdef AX_DEBUG
+ agentx_log_axg_fatalx(axv->axv_axg, "%s: %s",
+ __func__, errstr);
+#else
+ agentx_log_axg_warnx(axv->axv_axg, "%s: %s",
+ __func__, errstr);
+ agentx_varbind_error_type(axv,
+ AX_PDU_ERROR_PROCESSINGERROR, 1);
+ return;
+#endif
+ }
+
if (axv->axv_axg->axg_type == AX_PDU_TYPE_GET &&
ax_oid_cmp(&oid, curvalue) != 0) {
#ifdef AX_DEBUG
return;
#endif
}
- for (i = 0; i < oidlen; i++)
- curvalue->aoi_id[i] = value[i];
- curvalue->aoi_idlen = oidlen;
+
+ *curvalue = oid;
return;
}
}
return 0;
}
+static int
+agentx_oidfill(struct ax_oid *oid, const uint32_t oidval[], size_t oidlen,
+ const char **errstr)
+{
+ size_t i;
+
+ if (oidlen < AGENTX_OID_MIN_LEN) {
+ *errstr = "oidlen < 2";
+ errno = EINVAL;
+ return -1;
+ }
+ if (oidlen > AGENTX_OID_MAX_LEN) {
+ *errstr = "oidlen > 128";
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (i = 0; i < oidlen; i++)
+ oid->aoi_id[i] = oidval[i];
+ oid->aoi_idlen = oidlen;
+ return 0;
+}
+
void
agentx_read(struct agentx *ax)
{