Annotation of embedaddon/strongswan/src/libimcv/swid_gen/swid_gen.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2017 Andreas Steffen
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      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: #define _GNU_SOURCE
                     17: #include <stdio.h>
                     18: 
                     19: #include "swid_gen.h"
                     20: 
                     21: #include <bio/bio_writer.h>
                     22: 
                     23: #define SWID_GENERATOR "/usr/local/bin/swid_generator"
                     24: 
                     25: typedef struct private_swid_gen_t private_swid_gen_t;
                     26: 
                     27: /**
                     28:  * Private data of a swid_gen_t object.
                     29:  *
                     30:  */
                     31: struct private_swid_gen_t {
                     32: 
                     33:        /**
                     34:         * Public swid_gen_t interface.
                     35:         */
                     36:        swid_gen_t public;
                     37: 
                     38:        /**
                     39:         * Path of the SWID generator command
                     40:         */
                     41:        char *generator;
                     42: 
                     43:        /**
                     44:         * Entity name of the tagCreator
                     45:         */
                     46:        char *entity;
                     47: 
                     48:        /**
                     49:         * Regid of the tagCreator
                     50:         */
                     51:        char *regid;
                     52: 
                     53: };
                     54: 
                     55: METHOD(swid_gen_t, generate_tag, char*,
                     56:        private_swid_gen_t *this, char *sw_id, char *package, char *version,
                     57:        bool full, bool pretty)
                     58: {
                     59:        char *tag = NULL;
                     60:        size_t tag_buf_len = 8192;
                     61:        char tag_buf[tag_buf_len], command[BUF_LEN];
                     62:        bio_writer_t *writer;
                     63:        chunk_t swid_tag;
                     64:        FILE *file;
                     65: 
                     66:        /* Compose the SWID generator command */
                     67:        if (full || !package || !version)
                     68:        {
                     69:                snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" "
                     70:                                 "--regid %s --software-id %s%s%s",
                     71:                                 this->generator, this->entity, this->regid, sw_id,
                     72:                                 full ? " --full" : "", pretty ? " --pretty" : "");
                     73:        }
                     74:        else
                     75:        {
                     76:                snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" "
                     77:                                 "--regid %s --name %s --version-string %s%s",
                     78:                                 this->generator, this->entity, this->regid, package,
                     79:                                 version, pretty ? " --pretty" : "");
                     80:        }
                     81: 
                     82:        /* Open a pipe stream for reading the SWID generator output */
                     83:        file = popen(command, "r");
                     84:        if (file)
                     85:        {
                     86:                writer = bio_writer_create(tag_buf_len);
                     87:                while (TRUE)
                     88:                {
                     89:                        if (!fgets(tag_buf, tag_buf_len, file))
                     90:                        {
                     91:                                break;
                     92:                        }
                     93:                        writer->write_data(writer, chunk_create(tag_buf, strlen(tag_buf)));
                     94:                }
                     95:                pclose(file);
                     96:                swid_tag = writer->extract_buf(writer);
                     97:                writer->destroy(writer);
                     98: 
                     99:                if (swid_tag.len > 0)
                    100:                {
                    101:                        tag = swid_tag.ptr;
                    102:                        tag[swid_tag.len - 1] = '\0';
                    103:                }
                    104:                else
                    105:                {
                    106:                        chunk_free(&swid_tag);
                    107:                }
                    108:        }
                    109:        else
                    110:        {
                    111:                DBG1(DBG_IMC, "failed to run swid_generator command");
                    112:        }
                    113: 
                    114:        return tag;
                    115: }
                    116: 
                    117: typedef struct {
                    118:        /** public enumerator interface */
                    119:        enumerator_t public;
                    120:        /** swid_generator output stream */
                    121:        FILE *file;
                    122:        /** generate software identifier only */
                    123:        bool sw_id_only;
                    124: } swid_gen_enumerator_t;
                    125: 
                    126: METHOD(enumerator_t, enumerate, bool,
                    127:        swid_gen_enumerator_t *this, va_list args)
                    128: {
                    129:        chunk_t *out;
                    130: 
                    131:        VA_ARGS_VGET(args, out);
                    132: 
                    133:        if (this->sw_id_only)
                    134:        {
                    135:                char line[BUF_LEN];
                    136:                size_t len;
                    137: 
                    138:                if (!fgets(line, sizeof(line), this->file))
                    139:                {
                    140:                        return FALSE;
                    141:                }
                    142:                len = strlen(line);
                    143: 
                    144:                if (len == 0)
                    145:                {
                    146:                        return FALSE;
                    147:                }
                    148: 
                    149:                /* remove trailing newline if present */
                    150:                if (line[len - 1] == '\n')
                    151:                {
                    152:                        len--;
                    153:                }
                    154:                DBG3(DBG_IMC, "  %.*s", len, line);
                    155:                *out = chunk_clone(chunk_create(line, len));
                    156:        }
                    157:        else
                    158:        {
                    159:                bool last_newline = TRUE;
                    160:                size_t len, line_len = 8192;
                    161:                char line[line_len];
                    162:                bio_writer_t *writer;
                    163:                chunk_t swid_tag;
                    164: 
                    165:                writer = bio_writer_create(line_len);
                    166:                while (TRUE)
                    167:                {
                    168:                        if (!fgets(line, line_len, this->file))
                    169:                        {
                    170:                                break;
                    171:                        }
                    172:                        len = strlen(line);
                    173: 
                    174:                        if (last_newline && line[0] == '\n')
                    175:                        {
                    176:                                break;
                    177:                        }
                    178:                        else
                    179:                        {
                    180:                                last_newline = (line[len-1] == '\n');
                    181:                                writer->write_data(writer, chunk_create(line, len));
                    182:                        }
                    183:                }
                    184:                swid_tag = writer->extract_buf(writer);
                    185:                writer->destroy(writer);
                    186: 
                    187:                if (swid_tag.len <= 1)
                    188:                {
                    189:                        chunk_free(&swid_tag);
                    190:                        return FALSE;
                    191:                }
                    192: 
                    193:                /* remove trailing newline if present */
                    194:                if (swid_tag.ptr[swid_tag.len - 1] == '\n')
                    195:                {
                    196:                        swid_tag.len--;
                    197:                }
                    198:                DBG3(DBG_IMC, "  %.*s", swid_tag.len, swid_tag.ptr);
                    199:                *out = swid_tag;
                    200:        }
                    201: 
                    202:        return TRUE;
                    203: }
                    204: 
                    205: METHOD(enumerator_t, enumerator_destroy, void,
                    206:        swid_gen_enumerator_t *this)
                    207: {
                    208:        pclose(this->file);
                    209:        free(this);
                    210: }
                    211: 
                    212: METHOD(swid_gen_t, create_tag_enumerator, enumerator_t*,
                    213:        private_swid_gen_t *this, bool sw_id_only, bool full, bool pretty)
                    214: {
                    215:        swid_gen_enumerator_t *enumerator;
                    216:        char command[BUF_LEN];
                    217:        char doc_separator[] = "'\n\n'";
                    218:        FILE *file;
                    219: 
                    220:        /* Assemble the SWID generator command */
                    221:        if (sw_id_only)
                    222:        {
                    223:                snprintf(command, BUF_LEN, "%s software-id --regid %s ",
                    224:                                 this->generator, this->regid);
                    225:        }
                    226:        else
                    227:        {
                    228:                snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" --regid %s "
                    229:                                 "--doc-separator %s%s%s", this->generator, this->entity,
                    230:                                 this->regid, doc_separator, pretty ? " --pretty" : "",
                    231:                                                                                         full   ? " --full"   : "");
                    232:        }
                    233: 
                    234:        /* Open a pipe stream for reading the SWID generator output */
                    235:        file = popen(command, "r");
                    236:        if (!file)
                    237:        {
                    238:                DBG1(DBG_IMC, "failed to run swid_generator command");
                    239:                return NULL;
                    240:        }
                    241: 
                    242:        INIT(enumerator,
                    243:                .public = {
                    244:                        .enumerate = enumerator_enumerate_default,
                    245:                        .venumerate = _enumerate,
                    246:                        .destroy = _enumerator_destroy,
                    247:                },
                    248:                .sw_id_only = sw_id_only,
                    249:                .file = file,
                    250:        );
                    251: 
                    252:        return &enumerator->public;
                    253: }
                    254: 
                    255: METHOD(swid_gen_t, destroy, void,
                    256:        private_swid_gen_t *this)
                    257: {
                    258:        free(this->generator);
                    259:        free(this->entity);
                    260:        free(this->regid);
                    261:        free(this);
                    262: }
                    263: 
                    264: /**
                    265:  * See header
                    266:  */
                    267: swid_gen_t *swid_gen_create(void)
                    268: {
                    269:        private_swid_gen_t *this;
                    270:        char *entity, *regid, *generator;
                    271: 
                    272:        entity = lib->settings->get_str(lib->settings,
                    273:                                "libimcv.swid_gen.tag_creator.name", "strongSwan Project");
                    274:        regid  = lib->settings->get_str(lib->settings,
                    275:                                "libimcv.swid_gen.tag_creator.regid", "strongswan.org");
                    276:        generator = lib->settings->get_str(lib->settings,
                    277:                                "libimcv.swid_gen.command", SWID_GENERATOR);
                    278: 
                    279:        INIT(this,
                    280:                .public = {
                    281:                        .generate_tag = _generate_tag,
                    282:                        .create_tag_enumerator = _create_tag_enumerator,
                    283:                        .destroy = _destroy,
                    284:                },
                    285:                .generator = strdup(generator),
                    286:                .entity = strdup(entity),
                    287:                .regid = strdup(regid),
                    288:        );
                    289: 
                    290:        return &this->public;
                    291: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>