Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_builder.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2014 Martin Willi
! 3: * Copyright (C) 2014 revosec AG
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "vici_builder.h"
! 17:
! 18: #include <bio/bio_writer.h>
! 19:
! 20: typedef struct private_vici_builder_t private_vici_builder_t;
! 21:
! 22: /**
! 23: * Private data of an vici_builder_t object.
! 24: */
! 25: struct private_vici_builder_t {
! 26:
! 27: /**
! 28: * Public vici_builder_t interface.
! 29: */
! 30: vici_builder_t public;
! 31:
! 32: /**
! 33: * Writer for elements
! 34: */
! 35: bio_writer_t *writer;
! 36:
! 37: /**
! 38: * Errors encountered
! 39: */
! 40: u_int error;
! 41:
! 42: /**
! 43: * Section nesting level
! 44: */
! 45: u_int section;
! 46:
! 47: /**
! 48: * In list element?
! 49: */
! 50: bool list;
! 51: };
! 52:
! 53: METHOD(vici_builder_t, add, void,
! 54: private_vici_builder_t *this, vici_type_t type, ...)
! 55: {
! 56: va_list args;
! 57: char *name = NULL;
! 58: chunk_t value = chunk_empty;
! 59:
! 60: va_start(args, type);
! 61: switch (type)
! 62: {
! 63: case VICI_SECTION_END:
! 64: case VICI_LIST_END:
! 65: case VICI_END:
! 66: break;
! 67: case VICI_LIST_START:
! 68: case VICI_SECTION_START:
! 69: name = va_arg(args, char*);
! 70: break;
! 71: case VICI_KEY_VALUE:
! 72: name = va_arg(args, char*);
! 73: value = va_arg(args, chunk_t);
! 74: break;
! 75: case VICI_LIST_ITEM:
! 76: value = va_arg(args, chunk_t);
! 77: break;
! 78: default:
! 79: va_end(args);
! 80: this->error++;
! 81: return;
! 82: }
! 83: va_end(args);
! 84:
! 85: if (value.len > 0xffff)
! 86: {
! 87: DBG1(DBG_ENC, "vici value exceeds size limit (%zu > %u)",
! 88: value.len, 0xffff);
! 89: this->error++;
! 90: return;
! 91: }
! 92: if (!vici_verify_type(type, this->section, this->list))
! 93: {
! 94: this->error++;
! 95: return;
! 96: }
! 97: if (type != VICI_END)
! 98: {
! 99: this->writer->write_uint8(this->writer, type);
! 100: }
! 101: switch (type)
! 102: {
! 103: case VICI_SECTION_START:
! 104: this->writer->write_data8(this->writer, chunk_from_str(name));
! 105: this->section++;
! 106: break;
! 107: case VICI_SECTION_END:
! 108: this->section--;
! 109: break;
! 110: case VICI_KEY_VALUE:
! 111: this->writer->write_data8(this->writer, chunk_from_str(name));
! 112: this->writer->write_data16(this->writer, value);
! 113: break;
! 114: case VICI_LIST_START:
! 115: this->writer->write_data8(this->writer, chunk_from_str(name));
! 116: this->list = TRUE;
! 117: break;
! 118: case VICI_LIST_ITEM:
! 119: this->writer->write_data16(this->writer, value);
! 120: break;
! 121: case VICI_LIST_END:
! 122: this->list = FALSE;
! 123: break;
! 124: default:
! 125: this->error++;
! 126: break;
! 127: }
! 128: }
! 129:
! 130: /**
! 131: * Add a list item or a key/value, if key given
! 132: */
! 133: static void vadd_kv_or_li(private_vici_builder_t *this, char *key,
! 134: char *fmt, va_list args)
! 135: {
! 136: u_char buf[512];
! 137: chunk_t value;
! 138: ssize_t len;
! 139: va_list copy;
! 140:
! 141: va_copy(copy, args);
! 142: len = vsnprintf(buf, sizeof(buf), fmt, copy);
! 143: va_end(copy);
! 144: if (len >= sizeof(buf))
! 145: {
! 146: value = chunk_alloc(len + 1);
! 147: len = vsnprintf(value.ptr, value.len, fmt, args);
! 148: }
! 149: else
! 150: {
! 151: value = chunk_create(buf, len);
! 152: }
! 153:
! 154: if (len < 0)
! 155: {
! 156: DBG1(DBG_ENC, "vici builder format print failed");
! 157: this->error++;
! 158: }
! 159: else
! 160: {
! 161: if (key)
! 162: {
! 163: add(this, VICI_KEY_VALUE, key, value);
! 164: }
! 165: else
! 166: {
! 167: add(this, VICI_LIST_ITEM, value);
! 168: }
! 169: }
! 170: if (value.ptr != buf)
! 171: {
! 172: free(value.ptr);
! 173: }
! 174: }
! 175:
! 176: METHOD(vici_builder_t, vadd_kv, void,
! 177: private_vici_builder_t *this, char *key, char *fmt, va_list args)
! 178: {
! 179: vadd_kv_or_li(this, key, fmt, args);
! 180: }
! 181:
! 182: METHOD(vici_builder_t, add_kv, void,
! 183: private_vici_builder_t *this, char *key, char *fmt, ...)
! 184: {
! 185: va_list args;
! 186:
! 187: va_start(args, fmt);
! 188: vadd_kv(this, key, fmt, args);
! 189: va_end(args);
! 190: }
! 191:
! 192: METHOD(vici_builder_t, vadd_li, void,
! 193: private_vici_builder_t *this, char *fmt, va_list args)
! 194: {
! 195: vadd_kv_or_li(this, NULL, fmt, args);
! 196: }
! 197:
! 198: METHOD(vici_builder_t, add_li, void,
! 199: private_vici_builder_t *this, char *fmt, ...)
! 200: {
! 201: va_list args;
! 202:
! 203: va_start(args, fmt);
! 204: vadd_li(this, fmt, args);
! 205: va_end(args);
! 206: }
! 207:
! 208: METHOD(vici_builder_t, begin_section, void,
! 209: private_vici_builder_t *this, char *name)
! 210: {
! 211: add(this, VICI_SECTION_START, name);
! 212: }
! 213:
! 214: METHOD(vici_builder_t, end_section, void,
! 215: private_vici_builder_t *this)
! 216: {
! 217: add(this, VICI_SECTION_END);
! 218: }
! 219:
! 220: METHOD(vici_builder_t, begin_list, void,
! 221: private_vici_builder_t *this, char *name)
! 222: {
! 223: add(this, VICI_LIST_START, name);
! 224: }
! 225:
! 226: METHOD(vici_builder_t, end_list, void,
! 227: private_vici_builder_t *this)
! 228: {
! 229: add(this, VICI_LIST_END);
! 230: }
! 231:
! 232: METHOD(vici_builder_t, destroy, void,
! 233: private_vici_builder_t *this)
! 234: {
! 235: this->writer->destroy(this->writer);
! 236: free(this);
! 237: }
! 238:
! 239: METHOD(vici_builder_t, finalize, vici_message_t*,
! 240: private_vici_builder_t *this)
! 241: {
! 242: vici_message_t *product;
! 243:
! 244: if (this->error || this->section || this->list)
! 245: {
! 246: DBG1(DBG_ENC, "vici builder error: %u errors (section: %u, list %u)",
! 247: this->error, this->section, this->list);
! 248: destroy(this);
! 249: return NULL;
! 250: }
! 251: product = vici_message_create_from_data(
! 252: this->writer->extract_buf(this->writer), TRUE);
! 253: destroy(this);
! 254: return product;
! 255: }
! 256:
! 257: /**
! 258: * See header
! 259: */
! 260: vici_builder_t *vici_builder_create()
! 261: {
! 262: private_vici_builder_t *this;
! 263:
! 264: INIT(this,
! 265: .public = {
! 266: .add = _add,
! 267: .add_kv = _add_kv,
! 268: .vadd_kv = _vadd_kv,
! 269: .add_li = _add_li,
! 270: .vadd_li = _vadd_li,
! 271: .begin_section = _begin_section,
! 272: .end_section = _end_section,
! 273: .begin_list = _begin_list,
! 274: .end_list = _end_list,
! 275: .finalize = _finalize,
! 276: .destroy = _destroy,
! 277: },
! 278: .writer = bio_writer_create(0),
! 279: );
! 280:
! 281: return &this->public;
! 282: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>