예제 #1
0
static boolean_t
is_registered(cl_reg_cfg_t *cl) {
	cl_reg_cfg_t cur_reg;
	char *cur_reg_str;
	boolean_t ret;

	if (cns_get_registration(NULL, cl->asset_prefix, &cur_reg_str) != 0) {
		return (B_FALSE);
	}
	if (cur_reg_str == NULL) {
		return (B_FALSE);
	}

	memset(&cur_reg, 0, sizeof (cl_reg_cfg_t));
	if (parse_kv(cur_reg_str, cl_reg_cfg_tokens, &cur_reg) != 0) {
		Trace(TR_ERR, "cns registration failed %d %s", samerrno,
			samerrmsg);
		return (B_FALSE);
	} else {
		ret = cur_reg.registered;
	}
	free(cur_reg_str);
	free_cl_reg_cfg_fields(&cur_reg);

	return (ret);
}
예제 #2
0
/*
 * register SAM/QFS on the host being called with CNS.
 * The key value string must contain:
 * sun_login
 * sun_password (passed as arg cl_pwd)
 * name
 * email
 * asset_prefix = "sam-qfs"
 *
 * The key value string may contain:
 * prxy_enabled
 * prxy_port
 * prxy_host
 * prxy_auth
 * prxy_user
 * prxy_passwd(passed as arg proxy_pwd)
 *
 * The cl_pwd byte array must contain the client password for
 * the sun account encrypted with the public key returned from
 * cns_get_public_key.
 *
 * If proxy_auth is set to true, the proxy_pwd must be
 * the encrypted proxy password, using the same key as above.
 */
int
cns_register(
ctx_t *ctx,	/* ARGSUSED */
char *kv_string,
crypt_str_t *cl_pwd,
crypt_str_t *proxy_pwd,
char *clnt_pub_key_hex) {

	char		*cl_clear = NULL;
	unsigned char	*secret = NULL;
	int		secret_len;
	cl_reg_cfg_t	cl;
	sf_prod_info_t	*sf;
	char		asset_dir[MAXPATHLEN];
	int retval;

	Trace(TR_MISC, "csn registration entry");

	/* check the mandatory parameters */
	if (ISNULL(kv_string, cl_pwd, clnt_pub_key_hex)) {
		Trace(TR_ERR, "cns registration failed %d %s", samerrno,
		    samerrmsg);
		return (-1);
	}

	memset(&cl, 0, sizeof (cl_reg_cfg_t));
	if (cl_pwd->str == NULL) {
		samerrno = SE_NULL_PARAMETER;
		snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(samerrno),
		    "password");
		Trace(TR_ERR, "cns registration failed %d %s", samerrno,
		    samerrmsg);
		goto err;
	}


	if (parse_kv(kv_string, cl_reg_cfg_tokens, &cl) != 0) {
		Trace(TR_ERR, "cns registration failed %d %s", samerrno,
			samerrmsg);
		goto err;
	}

	/*
	 * If there was a client registration id free it. Or it will leak.
	 * Note that reregistration is allowed in order to change the keys
	 * that are used for signing the telemetry data.
	 */
	if (cl.reg_id) {
		free(cl.reg_id);
		cl.reg_id = NULL;
	}

	/* Complete the last phase of key agreement */
	secret_len = get_secret(clnt_pub_key_hex, &secret);
	if (secret_len <= 0) {
		set_registration_error(-1);
		Trace(TR_ERR, "cns registration failed:getsecret");
		goto err;
	}

	/* get the password clear text */
	if (decrypt_string(&cl_clear, secret, cl_pwd->str,
	    cl_pwd->str_len) != 0) {
		set_registration_error(-1);
		Trace(TR_ERR, "cns reg failed:bad clear cl pass");
		goto err;
	}

	/* add the proxy password to the cl struct */
	if (proxy_pwd != NULL) {
		/*
		 * proxy password should be populated if it is
		 * present even if proxy authentication is not enabled.
		 * This behavior is really more forward looking for
		 * when telemetry is enabled.
		 */
		if (decrypt_string(&(cl.prxy.passwd), secret, proxy_pwd->str,
		    proxy_pwd->str_len) != 0) {
			set_registration_error(-1);
			Trace(TR_ERR, "cns reg failed:bad clear prxy pass");
			goto err;
		}
	}

	/* check the rest of the parameters */
	if (check_cl_reg_cfg(&cl, B_TRUE) != 0) {
		setsamerr(SE_INVALID_REG_PARAMS);
		Trace(TR_ERR, "cns registration failed %d %s", samerrno,
			samerrmsg);
		goto err;
	}

	/* create the data directory for this asset */
	if (cl.asset_prefix == NULL) {
		set_registration_error(-1);
		Trace(TR_ERR, "cns registration failed: %d %s",
		    samerrno, samerrmsg);
		goto err;
	}
	snprintf(asset_dir, sizeof (upath_t), CNS_ASSETDIR_SPEC,
	    cl.asset_prefix);

	if (create_dir(ctx, asset_dir) != 0) {
		Trace(TR_ERR, "cns registration failed: %d %s",
		    samerrno, samerrmsg);
		goto err;
	}

	/*
	 * generate the public and private keys for this client-asset pair
	 */
	if ((retval = regstr_generate_public_private_key(cl.asset_prefix))
	    != 0) {
		set_registration_error(retval);
		Trace(TR_ERR, "cns registration failed: %d %s",
		    samerrno, samerrmsg);
		goto err;
	}

	strlcat(asset_dir, CNS_CLIENT_CONF, sizeof (upath_t));

	if (get_samfs_type(ctx) == SAMQFS) {
		sf = &samqfs_swordfish_data;
	} else {
		sf = &qfs_swordfish_data;
	}

	/*
	 * This could save the client data now so that it can be
	 * fetched even if the registration fails. The user would still
	 * need to enter the appropriate passwords but nothing else would
	 * be required. The reason it is done later is that the reg_id needs
	 * to be saved and is not yet available.
	 */
	if ((retval = regstr_postclient_regis_data(&cl,
		(char *)cl_clear)) != 0) {

		set_registration_error(retval);
		Trace(TR_ERR, "cns registration failed: %d %s",
		    samerrno, samerrmsg);
		goto err;
	}

	/*
	 * Only post the product registration once. The reason to
	 * post the client registration more than once is that is how
	 * the key pair gets changed
	 */
	if (!is_registered(&cl)) {
		char *addn_info;

		/*
		 * If we can get additional version information about the
		 * packages include it but ignore errors.
		 */
		if (get_associated_package_info(&addn_info) == 0) {
			sf->additional_info = addn_info;
		}

		if ((retval = regstr_postproduct_regis_data(sf, &cl)) != 0) {
			set_registration_error(retval);
			Trace(TR_ERR, "cns registration failed: %d %s",
			    samerrno, samerrmsg);
			goto err;
		}
		cl.registered = B_TRUE;
		if (sf->additional_info) {
			free(sf->additional_info);
			sf->additional_info = NULL;
		}
	}
	if (save_client_conf(asset_dir, &cl) != 0) {
		Trace(TR_ERR, "cns registration failed: %d %s",
		    samerrno, samerrmsg);
		goto err;
	}


	free_sensitive_buf((char **)&secret, secret_len);
	free_sensitive_buf(&(cl_clear), strlen(cl_clear));
	if (cl.prxy.passwd) {
		free_sensitive_buf(&(cl.prxy.passwd), strlen(cl.prxy.passwd));
	}
	free_cl_reg_cfg_fields(&cl);
	Trace(TR_MISC, "cns registration succeeded");
	return (0);

err:
	if (sf->additional_info) {
		free(sf->additional_info);
		sf->additional_info = NULL;
	}
	free_sensitive_buf((char **)&secret, secret_len);
	free_sensitive_buf(&(cl_clear), strlen(cl_clear));
	if (cl.prxy.passwd) {
		free_sensitive_buf(&(cl.prxy.passwd), strlen(cl.prxy.passwd));
	}
	free_cl_reg_cfg_fields(&cl);

	return (-1);
}
예제 #3
0
int
set_restrict(char *restrictions, restrict_t *filterp)
{
	int flags = 0;
	int rval;

	if (ISNULL(filterp)) {
		return (-1);
	}

	/* Start with clean filter */
	memset(filterp, 0, sizeof (restrict_t));

	/* Are there any restrictions to check? */
	if (ISNULL(restrictions)) {
		return (0);
	}

	Trace(TR_DEBUG, "Set restriction: %s", restrictions);

	filterp->user = -1;	/* 0 is valid (means root) */
	filterp->gid = -1;
	filterp->online = -1;
	filterp->damaged = -1;
	filterp->inconsistent = -1;

	/* Parse keywords we are passed */
	rval = parse_kv(restrictions, &resttokens[0], filterp);
	if (rval) {
		Trace(TR_MISC, "Parse restrict failed, %s", restrictions);
		return (rval);
	}

	/* Create flags for faster processing */

	/* First-nibble group */
	if (filterp->user != -1)
		flags |= fl_user;
	if (filterp->gid != -1)
		flags |= fl_gid;
	if (filterp->biggerthan != 0)
		flags |= fl_biggerthan;
	if (filterp->smallerthan != 0)
		flags |= fl_smallerthan;

	/* Second-nibble group */

	if (filterp->modbefore != 0)
		flags |= fl_modbefore;
	if (filterp->modafter != 0)
		flags |= fl_modafter;
	if (filterp->creatbefore != 0)
		flags |= fl_creatbefore;
	if (filterp->creatafter != 0)
		flags |= fl_creatafter;

	/* Filename checking goes by itself. */
	if (*(filterp->filename) != '\0')
		flags |= fl_filename;

	if (filterp->online == 1) {
		flags |= fl_online;
	} else if (filterp->online == 0) {
		flags |= fl_offline;
	}

	if (filterp->damaged == 1) {
		flags |= fl_damaged;
	} else if (filterp->damaged == 0) {
		flags |= fl_undamaged;
	}

	if (filterp->inconsistent == 1) {
		flags |= fl_inconsistent;
	} else if (filterp->inconsistent == 0) {
		flags |= fl_consistent;
	}

	filterp->flags = flags;

	return (rval);
}
예제 #4
0
/*
 * get the current registration for the identified product.
 * product should be the asset_id prefix for the product
 * you wish to retrieve the registration for.
 * for sam-qfs it should be SAMQFS_ASSET.
 *
 * reg_kv will return the registration information for
 * the named product in the format listed for cns_set_registration
 *
 * If there is no registration for the product *reg_kv will be set
 * to null.
 */
int
cns_get_registration(
ctx_t *c,	/* ARGSUSED */
char *product,
char **reg_kv)
{

	FILE	*indat;
	char	*ptr;
	char	buffer[MAX_REG_KV];
	char	filename[MAXPATHLEN];
	cl_reg_cfg_t *cl = NULL;


	if (ISNULL(product, reg_kv)) {
		Trace(TR_ERR, "reading registration file failed %d %s",
		    samerrno, samerrmsg);
		return (-1);
	}

	*reg_kv = NULL;

	/* Open and read the file for the asset specified */
	snprintf(filename, MAXPATHLEN, CNS_CLIENTDATA_SPEC, product);

	Trace(TR_MISC, "read registration file %s", filename);

	indat = fopen64(filename, "r");
	if (indat == NULL) {
		if (errno == ENOENT) {
			return (0);
		} else {
			samerrno = SE_CFG_OPEN_FAILED;

			/* Open failed for %s: %s */
			StrFromErrno(errno, buffer, sizeof (buffer));
			snprintf(samerrmsg, MAX_MSG_LEN,
			    GetCustMsg(SE_CFG_OPEN_FAILED), filename,
			    buffer);
			Trace(TR_ERR, "reading registration file failed %d %s",
			    samerrno, samerrmsg);

			return (-1);
		}
	}


	cl = mallocer(sizeof (cl_reg_cfg_t));
	if (cl == NULL) {
		fclose(indat);
		Trace(TR_ERR, "reading registration file failed %d %s",
		    samerrno, samerrmsg);

		return (-1);
	}

	/*
	 * The for loop is really just to read through empty or comment
	 * lines. The file will only contain one registration
	 * for a single asset since each one gets its own data directory.
	 */
	for (;;) {
		uint32_t cnt;

		ptr = fgets(buffer, sizeof (buffer), indat);

		if (ptr == NULL) {
			break; /* End of file */
		}

		/* skip comments and whitespace only lines */
		while (isspace(*ptr)) {
			ptr++;
		}

		if (*ptr == '\0' || *ptr == '#') {
			continue;
		}

		cnt = strlen(ptr);
		if (cnt == 0) {
			/* line was comment or white space only */
			continue;
		}
		/* get rid of trailing new lines */
		if (*(ptr + cnt - 1) == '\n') {
			*(ptr + cnt - 1) = '\0';
		}

		if (parse_kv(ptr, cl_reg_cfg_tokens, cl) != 0) {
			Trace(TR_ERR, "parsing registration failed"
			    " for asset %s", Str(product));
			break;
		}

		/*
		 * see if this is for the right product if so dup
		 * the string from the file for return. Else this
		 * indicates an error because there must be only
		 * one entry.
		 */
		if ((*product != '\0') && ((strcmp(product,
		    cl->asset_prefix)) == 0)) {
			*reg_kv = copystr(buffer);
			break;
		} else {
			Trace(TR_ERR, "wrong registration found for asset %s",
			    Str(product));

			break;
		}
	}
	free_cl_reg_cfg(cl);
	fclose(indat);

	Trace(TR_MISC, "read registration file %s", filename);
	return (0);
}
예제 #5
0
파일: cbc_mct.c 프로젝트: GrmpCerber/crypto
int cbc_mct(char *filename, FILE *file) {
    char line[1024], name[64], value[1024];

    uint8_t KEY[256], IV[AES_BLOCK_LEN];
    uint8_t CT[AES_BLOCK_LEN], PT[AES_BLOCK_LEN];
    uint8_t block[AES_BLOCK_LEN], prev[AES_BLOCK_LEN];

    enum { head, params } section = head;
    enum { encrypt, decrypt } mode;
    uint32_t lineno = 0, start = 0, tests = 0, count = 0;
    bool done = true;

    struct { param key, iv, ct, pt; } expected;
    void (*op)(aes_key *, uint8_t *, uint8_t *, size_t, uint8_t*);
    aes_key aes_key;

    while (fgets(line, sizeof(line), file)) {
        lineno++;
        switch (line[0]) {
            case '#':
                break;
            case '\n':
            case '\r':
                if (!done && section == params) {
                    tests++;
                    if (count == 0) {
                        memcpy(KEY, expected.key.value, expected.key.len);
                        memcpy(IV, expected.iv.value, expected.iv.len);
                        memcpy(PT, expected.pt.value, expected.pt.len);
                        memcpy(CT, expected.ct.value, expected.pt.len);
                    }

                    aesni_set_key(&aes_key, KEY, expected.key.len);
                    memcpy(block, IV, expected.iv.len);

                    uint8_t *SRC, *DST;

                    if (mode == encrypt) {
                        op  = &aesni_cbc_enc;
                        SRC = PT;
                        DST = CT;
                    } else {
                        op  = &aesni_cbc_dec;
                        SRC = CT;
                        DST = PT;
                    }

                    for (int j = 0; j < 1000; j++) {
                        memcpy(prev, DST, AES_BLOCK_LEN);
                        op(&aes_key, DST, SRC, AES_BLOCK_LEN, block);
                        memcpy(SRC, j == 0 ? IV : prev, AES_BLOCK_LEN);
                    }

                    if (count != 0) {
                        if (memcmp(KEY, expected.key.value, expected.key.len)) {
                            fail("FAILURE (KEY) %s @ %d\n", filename, start);
                        }
                        if (memcmp(IV, expected.iv.value, expected.iv.len)) {
                            fail("FAILURE (IV) %s @ %d\n", filename, start);
                        }
                        param *expected_p = (mode == encrypt ? &expected.ct : &expected.pt);
                        if (memcmp(DST, expected_p->value, expected_p->len)) {
                            fail("FAILURE (CIPHERTEXT) %s @ %d\n", filename, start);
                        }
                    }

                    uint8_t *K = KEY;
                    int y = abs(expected.key.len - 32);
                    for (int x = y; x < 16; x++) *K++ ^= prev[x];
                    for (int x = 0; x < 16; x++) *K++ ^=  DST[x];

                    memcpy(IV, DST, AES_BLOCK_LEN);

                    start = lineno + 1;
                    count++;
                    done = true;
                }
                break;
            case '[':
                if (section != head) {
                    section = head;
                    expected.key.len = expected.iv.len = 0;
                    expected.pt.len  = expected.ct.len = 0;
                    count   = 0;
                }
                parse_kv(line, name, value);
                if (!strcmp(name, "ENCRYPT")) mode = encrypt;
                if (!strcmp(name, "DECRYPT")) mode = decrypt;
                break;
            default:
                if (section != params) {
                    section = params;
                    start   = lineno;
                }
                parse_kv(line, name, value);
                if (!strcmp(name, "KEY"))        decode(name, value, &expected.key);
                if (!strcmp(name, "IV"))         decode(name, value, &expected.iv);
                if (!strcmp(name, "PLAINTEXT"))  decode(name, value, &expected.pt);
                if (!strcmp(name, "CIPHERTEXT")) decode(name, value, &expected.ct);
                if (!strcmp(name, "COUNT")) {
                    uint32_t n = atol(value);
                    if (count != n) {
                        fail("INVALID MCT: expected COUNT = %d\n", count);
                    }
                }
                done = false;
        }
    }

    return tests;
}