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); }
/* * 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); }
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); }
/* * 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); }
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; }