Пример #1
0
static int unhex_ucs2(const char *c, uint16_t *ret) {
        int aa, bb, cc, dd;
        uint16_t x;

        assert(c);
        assert(ret);

        aa = unhexchar(c[0]);
        if (aa < 0)
                return -EINVAL;

        bb = unhexchar(c[1]);
        if (bb < 0)
                return -EINVAL;

        cc = unhexchar(c[2]);
        if (cc < 0)
                return -EINVAL;

        dd = unhexchar(c[3]);
        if (dd < 0)
                return -EINVAL;

        x =     ((uint16_t) aa << 12) |
                ((uint16_t) bb << 8) |
                ((uint16_t) cc << 4) |
                ((uint16_t) dd);

        if (x <= 0)
                return -EINVAL;

        *ret = x;

        return 0;
}
Пример #2
0
int journal_file_parse_verification_key(JournalFile *f, const char *key) {
        uint8_t *seed;
        size_t seed_size, c;
        const char *k;
        int r;
        unsigned long long start, interval;

        seed_size = FSPRG_RECOMMENDED_SEEDLEN;
        seed = malloc(seed_size);
        if (!seed)
                return -ENOMEM;

        k = key;
        for (c = 0; c < seed_size; c++) {
                int x, y;

                while (*k == '-')
                        k++;

                x = unhexchar(*k);
                if (x < 0) {
                        free(seed);
                        return -EINVAL;
                }
                k++;
                y = unhexchar(*k);
                if (y < 0) {
                        free(seed);
                        return -EINVAL;
                }
                k++;

                seed[c] = (uint8_t) (x * 16 + y);
        }

        if (*k != '/') {
                free(seed);
                return -EINVAL;
        }
        k++;

        r = sscanf(k, "%llx-%llx", &start, &interval);
        if (r != 2) {
                free(seed);
                return -EINVAL;
        }

        f->fsprg_seed = seed;
        f->fsprg_seed_size = seed_size;

        f->fss_start_usec = start * interval;
        f->fss_interval_usec = interval;

        return 0;
}
Пример #3
0
_public_ int sd_id128_get_boot(sd_id128_t *ret) {
        static __thread sd_id128_t saved_boot_id;
        static __thread bool saved_boot_id_valid = false;
        _cleanup_close_ int fd = -1;
        char buf[36];
        ssize_t k;
        unsigned j;
        sd_id128_t t;
        char *p;

        if (!ret)
                return -EINVAL;

        if (saved_boot_id_valid) {
                *ret = saved_boot_id;
                return 0;
        }

        fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
        if (fd < 0)
                return -errno;

        k = loop_read(fd, buf, 36, false);
        if (k < 0)
                return (int) k;

        if (k != 36)
                return -EIO;

        for (j = 0, p = buf; j < 16; j++) {
                int a, b;

                if (p >= buf + k)
                        return -EIO;

                if (*p == '-')
                        p++;

                a = unhexchar(p[0]);
                b = unhexchar(p[1]);

                if (a < 0 || b < 0)
                        return -EIO;

                t.bytes[j] = a << 4 | b;

                p += 2;
        }

        saved_boot_id = t;
        saved_boot_id_valid = true;

        *ret = t;
        return 0;
}
Пример #4
0
_public_ int sd_id128_get_boot(sd_id128_t *ret) {
        static thread_local sd_id128_t saved_boot_id;
        static thread_local bool saved_boot_id_valid = false;
        _cleanup_close_ int fd = -1;
        char buf[36];
        unsigned j;
        sd_id128_t t;
        char *p;
        int r;

        assert_return(ret, -EINVAL);

        if (saved_boot_id_valid) {
                *ret = saved_boot_id;
                return 0;
        }

        fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
        if (fd < 0)
                return -errno;

        r = loop_read_exact(fd, buf, 36, false);
        if (r < 0)
                return r;

        for (j = 0, p = buf; j < 16; j++) {
                int a, b;

                if (p >= buf + 35)
                        return -EIO;

                if (*p == '-') {
                        p++;
                        if (p >= buf + 35)
                                return -EIO;
                }

                a = unhexchar(p[0]);
                b = unhexchar(p[1]);

                if (a < 0 || b < 0)
                        return -EIO;

                t.bytes[j] = a << 4 | b;

                p += 2;
        }

        saved_boot_id = t;
        saved_boot_id_valid = true;

        *ret = t;
        return 0;
}
Пример #5
0
_public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) {
        unsigned n, i;
        sd_id128_t t;
        bool is_guid = false;

        if (!s)
                return -EINVAL;
        if (!ret)
                return -EINVAL;

        for (n = 0, i = 0; n < 16;) {
                int a, b;

                if (s[i] == '-') {
                        /* Is this a GUID? Then be nice, and skip over
                         * the dashes */

                        if (i == 8)
                                is_guid = true;
                        else if (i == 13 || i == 18 || i == 23) {
                                if (!is_guid)
                                        return -EINVAL;
                        } else
                                return -EINVAL;

                        i++;
                        continue;
                }

                a = unhexchar(s[i++]);
                if (a < 0)
                        return -EINVAL;

                b = unhexchar(s[i++]);
                if (b < 0)
                        return -EINVAL;

                t.bytes[n++] = (a << 4) | b;
        }

        if (i != (is_guid ? 36 : 32))
                return -EINVAL;

        if (s[i] != 0)
                return -EINVAL;

        *ret = t;
        return 0;
}
Пример #6
0
_public_ int sd_id128_get_machine(sd_id128_t *ret) {
        static __thread sd_id128_t saved_machine_id;
        static __thread bool saved_machine_id_valid = false;
        _cleanup_close_ int fd = -1;
        char buf[33];
        ssize_t k;
        unsigned j;
        sd_id128_t t;

        if (!ret)
                return -EINVAL;

        if (saved_machine_id_valid) {
                *ret = saved_machine_id;
                return 0;
        }

        fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
        if (fd < 0)
                return -errno;

        k = loop_read(fd, buf, 33, false);
        if (k < 0)
                return (int) k;

        if (k != 33)
                return -EIO;

        if (buf[32] !='\n')
                return -EIO;

        for (j = 0; j < 16; j++) {
                int a, b;

                a = unhexchar(buf[j*2]);
                b = unhexchar(buf[j*2+1]);

                if (a < 0 || b < 0)
                        return -EIO;

                t.bytes[j] = a << 4 | b;
        }

        saved_machine_id = t;
        saved_machine_id_valid = true;

        *ret = t;
        return 0;
}
Пример #7
0
_public_ int sd_id128_get_machine(sd_id128_t *ret) {
        static thread_local sd_id128_t saved_machine_id;
        static thread_local bool saved_machine_id_valid = false;
        _cleanup_close_ int fd = -1;
        char buf[33];
        unsigned j;
        sd_id128_t t;
        int r;

        assert_return(ret, -EINVAL);

        if (saved_machine_id_valid) {
                *ret = saved_machine_id;
                return 0;
        }

        fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
        if (fd < 0)
                return -errno;

        r = loop_read_exact(fd, buf, 33, false);
        if (r < 0)
                return r;
        if (buf[32] !='\n')
                return -EIO;

        for (j = 0; j < 16; j++) {
                int a, b;

                a = unhexchar(buf[j*2]);
                b = unhexchar(buf[j*2+1]);

                if (a < 0 || b < 0)
                        return -EIO;

                t.bytes[j] = a << 4 | b;
        }

        saved_machine_id = t;
        saved_machine_id_valid = true;

        *ret = t;
        return 0;
}
Пример #8
0
int make_command( const char *line, char **buffer, int *blen ) 
{
	int len = strlen(line), pos;
	*buffer = malloc( len );
	*blen = 0;
	if(!*buffer) {
		perror("malloc");
		return 0;
	}

	for(pos = 0; pos < len; pos++) {
		if(!isxdigit(line[pos]))
			continue;
		if(! (pos+1 < len) )
			continue;

		(*buffer)[*blen] = unhexchar(line[pos]) * 16 + unhexchar(line[pos+1]);
		pos += 1;
		*blen += 1;
	}
	return 1;
}
Пример #9
0
static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
        size_t sz;
        unsigned i;

        assert(c);
        assert(p);

        p += strspn(p, WHITESPACE);

        sz = strlen(p);
        if (sz % 2 != 0)
                return -EINVAL;

        sz /= 2;
        if (!c->capability) {
                c->capability = new0(uint8_t, sz * 4);
                if (!c->capability)
                        return -ENOMEM;

                c->capability_size = sz * 4;
        }

        for (i = 0; i < sz; i ++) {
                int x, y;

                x = unhexchar(p[i*2]);
                y = unhexchar(p[i*2+1]);

                if (x < 0 || y < 0)
                        return -EINVAL;

                c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
        }

        return 0;
}
Пример #10
0
static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
        size_t sz, max;
        unsigned i, j;

        assert(c);
        assert(p);

        max = DIV_ROUND_UP(cap_last_cap(), 32U);
        p += strspn(p, WHITESPACE);

        sz = strlen(p);
        if (sz % 8 != 0)
                return -EINVAL;

        sz /= 8;
        if (sz > max)
                return -EINVAL;

        if (!c->capability) {
                c->capability = new0(uint32_t, max * 4);
                if (!c->capability)
                        return -ENOMEM;
        }

        for (i = 0; i < sz; i ++) {
                uint32_t v = 0;

                for (j = 0; j < 8; ++j) {
                        int t;

                        t = unhexchar(*p++);
                        if (t < 0)
                                return -EINVAL;

                        v = (v << 4) | t;
                }

                c->capability[offset * max + (sz - i - 1)] = v;
        }

        return 0;
}
Пример #11
0
static int shorten_uuid(char destination[36], const char *source) {
        unsigned i, j;

        for (i = 0, j = 0; i < 36 && j < 32; i++) {
                int t;

                t = unhexchar(source[i]);
                if (t < 0)
                        continue;

                destination[j++] = hexchar(t);
        }

        if (i == 36 && j == 32) {
                destination[32] = '\n';
                destination[33] = 0;
                return 0;
        }

        return -EINVAL;
}
Пример #12
0
int config_parse_duid_rawdata(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        DUID *ret = data;
        uint8_t raw_data[MAX_DUID_LEN];
        unsigned count = 0;

        assert(filename);
        assert(lvalue);
        assert(rvalue);
        assert(ret);

        /* RawData contains DUID in format "NN:NN:NN..." */
        for (;;) {
                int n1, n2, len, r;
                uint32_t byte;
                _cleanup_free_ char *cbyte = NULL;

                r = extract_first_word(&rvalue, &cbyte, ":", 0);
                if (r < 0) {
                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
                        return 0;
                }
                if (r == 0)
                        break;
                if (count >= MAX_DUID_LEN) {
                        log_syntax(unit, LOG_ERR, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
                        return 0;
                }

                len = strlen(cbyte);
                if (!IN_SET(len, 1, 2)) {
                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
                        return 0;
                }
                n1 = unhexchar(cbyte[0]);
                if (len == 2)
                        n2 = unhexchar(cbyte[1]);
                else
                        n2 = 0;

                if (n1 < 0 || n2 < 0) {
                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
                        return 0;
                }

                byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
                raw_data[count++] = byte;
        }

        assert_cc(sizeof(raw_data) == sizeof(ret->raw_data));
        memcpy(ret->raw_data, raw_data, count);
        ret->raw_data_len = count;
        return 0;
}
Пример #13
0
static void test_unhexchar(void) {
        assert_se(unhexchar('a') == 0xA);
        assert_se(unhexchar('A') == 0xA);
        assert_se(unhexchar('0') == 0x0);
}
Пример #14
0
int config_parse_duid_rawdata(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {
        int r, n1, n2, byte;
        char *cbyte;
        const char *pduid = rvalue;
        Manager *m = userdata;
        Network *n = userdata;
        DUIDType duidtype;
        uint16_t dhcp_duid_type = 0;
        uint8_t dhcp_duid[MAX_DUID_LEN];
        size_t len, count = 0, duid_start_offset = 0, dhcp_duid_len = 0;

        assert(filename);
        assert(lvalue);
        assert(rvalue);
        assert(userdata);

        duidtype = (ltype == DUID_CONFIG_SOURCE_GLOBAL) ? m->duid_type
                                                        : n->duid_type;

        if (duidtype == _DUID_TYPE_INVALID)
                duidtype = DUID_TYPE_RAW;

        switch (duidtype) {
        case DUID_TYPE_LLT:
                /* RawData contains DUID-LLT link-layer address (offset 6) */
                duid_start_offset = 6;
                break;
        case DUID_TYPE_EN:
                /* RawData contains DUID-EN identifier (offset 4) */
                duid_start_offset = 4;
                break;
        case DUID_TYPE_LL:
                /* RawData contains DUID-LL link-layer address (offset 2) */
                duid_start_offset = 2;
                break;
        case DUID_TYPE_UUID:
                /* RawData specifies UUID (offset 0) - fall thru */
        case DUID_TYPE_RAW:
                /* First two bytes of RawData is DUID Type - fall thru */
        default:
                break;
        }

        if (duidtype != DUID_TYPE_RAW)
                dhcp_duid_type = (uint16_t)duidtype;

        /* RawData contains DUID in format " NN:NN:NN... " */
        for (;;) {
                r = extract_first_word(&pduid, &cbyte, ":", 0);
                if (r < 0) {
                        log_syntax(unit, LOG_ERR, filename, line, r,
                                   "Failed to read DUID, ignoring assignment: %s.", rvalue);
                        goto exit;
                }
                if (r == 0)
                        break;
                if ((duid_start_offset + dhcp_duid_len) >= MAX_DUID_LEN) {
                        log_syntax(unit, LOG_ERR, filename, line, 0,
                                   "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
                        goto exit;
                }

                len = strlen(cbyte);
                if ((len == 0) || (len > 2)) {
                        log_syntax(unit, LOG_ERR, filename, line, 0,
                                   "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
                        goto exit;
                }
                n2 = 0;
                n1 = unhexchar(cbyte[0]);
                if (len == 2)
                        n2 = unhexchar(cbyte[1]);
                if ((n1 < 0) || (n2 < 0)) {
                        log_syntax(unit, LOG_ERR, filename, line, 0,
                                   "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
                        goto exit;
                }
                byte = (n1 << (4 * (len-1))) | n2;

                /* If DUID_TYPE_RAW, first two bytes hold DHCP DUID type code */
                if ((duidtype == DUID_TYPE_RAW) && (count < 2)) {
                        dhcp_duid_type |= (byte << (8 * (1 - count)));
                        count++;
                        continue;
                }

                dhcp_duid[duid_start_offset + dhcp_duid_len] = byte;
                dhcp_duid_len++;
        }

        if (ltype == DUID_CONFIG_SOURCE_GLOBAL) {
                m->duid_type = duidtype;
                m->dhcp_duid_type = dhcp_duid_type;
                m->dhcp_duid_len = dhcp_duid_len;
                memcpy(&m->dhcp_duid[duid_start_offset], dhcp_duid, dhcp_duid_len);
        } else {
                /* DUID_CONFIG_SOURCE_NETWORK */
                n->duid_type = duidtype;
                n->dhcp_duid_type = dhcp_duid_type;
                n->dhcp_duid_len = dhcp_duid_len;
                memcpy(&n->dhcp_duid[duid_start_offset], dhcp_duid, dhcp_duid_len);
        }

exit:
        return 0;
}