int rc = 0;
ENTRY;
- if (lli->lli_posix_acl && lli->lli_key_info) {
- /*If they are in the local cache, just fetch them*/
- spin_lock(&lli->lli_lock);
- *acl = posix_acl_dup(lli->lli_posix_acl);
- *lkey = lustre_key_get(lli->lli_key_info);
- spin_unlock(&lli->lli_lock);
- RETURN(rc);
- }
sbi = ll_i2sbi(inode);
ll_inode2id(&id, inode);
*acl = posix_acl_dup(lli->lli_posix_acl);
*lkey = lustre_key_get(lli->lli_key_info);
spin_unlock(&lli->lli_lock);
+ EXIT;
out:
if (req)
ptlrpc_req_finished(req);
- RETURN(rc);
+ return rc;
}
static int ll_init_key_perm(struct key_perm *kperm, struct posix_acl *acl,
__u32 uid, __u32 gid, int mode)
{
+ ENTRY;
if (acl) {
kperm->kp_acl_count = acl->a_count;
memcpy(kperm->kp_acls, acl->a_entries,
}
}
- rc = posix_acl_create_masq(*acl, &mode);
+ rc = posix_acl_create_masq(*acl, &mode);
+ EXIT;
out:
if (buf)
OBD_FREE(buf, buf_size);
- RETURN(rc);
+ return rc;
}
int ll_gks_create_key(struct inode *dir, mode_t mode, void **key,
{
struct obd_export *gs_exp = ll_i2gsexp(dir);
struct key_context *kcontext = NULL;
- struct key_parms kparms;
struct posix_acl *default_acl = NULL;
- int rc = 0;
+ struct key_parms kparms;
+ int rc = 0;
ENTRY;
OBD_ALLOC(kcontext, sizeof(struct key_context));
if (!*key)
GOTO(out, rc = -ENOMEM);
- /*GET an encrypt key from GS server*/
+ /* GET an encrypt key from GS server */
rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
key_size, *key);
if (rc) {
(char*)((struct crypto_key *)(*key))->ck_key,
(char*)((struct crypto_key *)(*key))->ck_mac,
gs_exp);
+ EXIT;
out:
if (kcontext)
OBD_FREE(kcontext, sizeof(struct key_context));
if (default_acl)
posix_acl_release(default_acl);
- RETURN(rc);
+ return rc;
}
RETURN(rc);
ll_gs_intent_init(it);
- if (!(it->it_op & IT_CREAT))
+ if (!(it->it_flags & O_CREAT))
RETURN(rc);
LASSERT(it->d.fs_data != NULL);
GOTO(out, rc);
lustre_data->it_key = key;
- lustre_data->it_key_size = key_size;
+ lustre_data->it_key_size = key_size;
+ EXIT;
out:
if (rc) {
if (key && key_size)
OBD_FREE(key, key_size);
}
- RETURN(rc);
+ return rc;
}
int ll_gks_decrypt_key(struct inode *inode, struct lookup_intent *it)
spin_unlock(&lli->lli_lock);
OBD_ALLOC(kperm, sizeof(struct key_perm));
+ if (!kperm)
+ GOTO(out, rc = -ENOMEM);
+
ll_init_key_perm(kperm, NULL, current->uid, current->gid, 0);
kparms.context = kcontext;
/*copy the decrypt key from kcontext to the lustre key*/
spin_lock(&lli->lli_lock);
- memcpy(&lkey->lk_ck, ckey, sizeof(*ckey));
+ memcpy(&lkey->lk_dk, ckey->ck_key, KEY_SIZE);
SET_DECRYPTED(lkey->lk_flags);
- spin_unlock(&lli->lli_lock);
+ spin_unlock(&lli->lli_lock);
+ EXIT;
out:
if (acl)
posix_acl_release(acl);
OBD_FREE(kcontext, kcontext_size);
if (ckey)
OBD_FREE(ckey, ck_size);
- RETURN(rc);
+ return rc;
+}
+
+static void get_real_parameters(struct inode *inode, struct iattr *iattr,
+ struct posix_acl *new_acl, mode_t *mode,
+ __u32 *uid, __u32 *gid)
+{
+ LASSERT(iattr);
+
+ if (iattr->ia_valid & ATTR_MODE) {
+ *mode = iattr->ia_mode;
+ } else {
+ *mode = inode->i_mode;
+ if (new_acl) {
+ posix_acl_equiv_mode(new_acl, mode);
+ CDEBUG(D_INFO, "get new mode %d \n", *mode);
+ }
+ }
+
+ if (iattr->ia_valid & ATTR_UID)
+ *uid = iattr->ia_uid;
+ else
+ *uid = inode->i_uid;
+
+ if (iattr->ia_valid & ATTR_GID)
+ *gid = iattr->ia_gid;
+ else
+ *gid = inode->i_gid;
}
int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value,
struct key_perm *kperm = NULL;
struct key_parms kparms;
struct lustre_key *lkey = NULL;
+ struct crypto_key *ckey = NULL;
struct posix_acl *acl = NULL, *new_acl = NULL;
int rc = 0, kperm_size = 0, kcontext_size = 0;
mode_t mac_mode;
+ __u32 uid, gid;
int acl_count = 0;
ENTRY;
acl, inode->i_mode, GKS_GET_MAC, iattr->ia_valid);
spin_unlock(&lli->lli_lock);
if (value) {
- new_acl = posix_acl_from_xattr(value, size);
+ new_acl = posix_acl_from_xattr(value, size);
if (IS_ERR(new_acl)) {
rc = PTR_ERR(new_acl);
CERROR("convert from xattr to acl error: %d",rc);
GOTO(out, rc);
}
}
- }
- acl_count = acl ? acl->a_count : 0;
+ } else {
+ new_acl = acl;
+ }
+ acl_count = new_acl ? new_acl->a_count : 0;
kperm_size = crypto_kperm_size(acl_count);
OBD_ALLOC(kperm, kperm_size);
- if (iattr->ia_valid & ATTR_MODE)
- mac_mode = iattr->ia_mode;
- else
- mac_mode = inode->i_mode;
- ll_init_key_perm(kperm, new_acl, iattr->ia_uid, iattr->ia_gid,
- mac_mode);
+ if (!kperm)
+ GOTO(out, rc = -ENOMEM);
+
+ get_real_parameters(inode, iattr, new_acl, &mac_mode, &uid, &gid);
+ ll_init_key_perm(kperm, new_acl, uid, gid, mac_mode);
kparms.context = kcontext;
kparms.context_size = kcontext_size;
kparms.perm = kperm;
kparms.perm_size = kperm_size;
*key_size = sizeof(struct crypto_key);
- OBD_ALLOC(*key, *key_size);
- if (!*key)
+ OBD_ALLOC(ckey, sizeof(struct crypto_key));
+ if (!ckey)
GOTO(out, rc = -ENOMEM);
-
/*GET an encrypt key from GS server*/
rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
- key_size, *key);
+ key_size, ckey);
if (rc) {
CERROR("decrypt key error rc %d \n", rc);
+ *key_size = 0;
GOTO(out, rc);
}
- /*copy the decrypt key from kcontext to the lustre key*/
- spin_lock(&lli->lli_lock);
- memcpy(&lkey->lk_ck, *key, *key_size);
+ *key = ckey;
iattr->ia_valid |= ATTR_MAC;
- spin_unlock(&lli->lli_lock);
out:
if (acl)
posix_acl_release(acl);
RETURN(rc);
}
+static int ll_crypt_permission_check(struct lustre_key *lkey,
+ int flags)
+{
+ ENTRY;
+ if (!IS_DECRYPTED(lkey->lk_flags))
+ RETURN(-EFAULT);
+ if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags))
+ RETURN(-EFAULT);
+ if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags))
+ RETURN(-EFAULT);
+ RETURN(0);
+}
/*key function for calculate the key for countermode method*/
static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count,
int flags)
unsigned char *ptr;
char *key_ptr;
int index = page->index;
- __u64 data_key = 0;
- int i;
+ __u8 data_key = 0;
+ int i, rc = 0;
ENTRY;
if (!lkey)
RETURN(0);
- if (!IS_DECRYPTED(lkey->lk_flags))
- RETURN(-EFAULT);
- if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags))
- RETURN(-EFAULT);
- if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags))
- RETURN(-EFAULT);
-
- /*FIXME: tmp calculate method, should calculate
- the key according to KEY_TYPE*/
-
spin_lock(&lli->lli_lock);
- key_ptr = &lkey->lk_ck.ck_key[0];
+ rc = ll_crypt_permission_check(lkey, flags);
+ if (rc) {
+ spin_unlock(&lli->lli_lock);
+ RETURN(rc);
+ }
+
+ key_ptr = &lkey->lk_dk[0];
for (i=0; i < KEY_SIZE; i++)
data_key += *key_ptr++;
spin_unlock(&lli->lli_lock);
data_key += index;
- CDEBUG(D_INFO, "data_key is "LPU64" \n", data_key);
+ CDEBUG(D_INFO, "data_key is %d \n", data_key);
+ if (data_key == 0) {
+ CDEBUG(D_INFO, "data_key is 0, inc 1 \n");
+ data_key ++;
+ }
+ LASSERT((__u8)data_key != 0);
/*encrypt the data*/
ptr = (char *)kmap(page);
- ptr += offset;
- CDEBUG(D_INFO, "ptr is %s \n", ptr);
+ key_ptr = ptr;
+ ptr += offset & (PAGE_SIZE - 1);
+ //CDEBUG(D_INFO, "ptr is %s \n", ptr);
for (i = 0; i < count; i++)
- *ptr++ ^= data_key;
- CDEBUG(D_INFO, "encrypted ptr is %s \n", ptr);
+ *ptr++ ^= (__u8)data_key;
+ //CDEBUG(D_INFO, "encrypted ptr is %s \n", key_ptr);
kunmap(page);
- RETURN(0);
+ RETURN(rc);
}
int ll_gs_init_inode_key(struct inode *inode, void *mkey)
spin_lock(&lli->lli_lock);
lli->lli_key_info = lkey;
spin_unlock(&lli->lli_lock);
+ CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n",
+ lli->lli_key_info->lk_ck.ck_key,
+ lli->lli_key_info->lk_ck.ck_mac,
+ inode->i_ino);
} else {
lkey = lustre_key_get(lli->lli_key_info);
- if (!IS_DECRYPTED(lkey->lk_flags)) {
- if (memcmp(&lkey->lk_ck, key, sizeof(*key))) {
- CWARN("already have key_info %p in ino %ld \n",
- lli->lli_key_info, inode->i_ino);
- }
- } else {
- spin_lock(&lli->lli_lock);
+ LASSERTF(!memcmp(lkey->lk_ck.ck_key, key->ck_key, KEY_SIZE),
+ "old key %s != new key %s\n", lkey->lk_ck.ck_key,
+ key->ck_key);
+ spin_lock(&lli->lli_lock);
+ if (memcmp(lkey->lk_ck.ck_mac, key->ck_mac, MAC_SIZE)){
+ CDEBUG(D_INFO, "reset mac %s to %s ino %ld \n",
+ lkey->lk_ck.ck_mac, key->ck_mac, inode->i_ino);
+ memcpy(lkey->lk_ck.ck_mac, key->ck_mac, MAC_SIZE);
SET_UNDECRYPTED(lkey->lk_flags);
- memcpy(&lkey->lk_ck, key, sizeof(*key));
- spin_unlock(&lli->lli_lock);
}
+ spin_unlock(&lli->lli_lock);
lustre_key_release(lkey);
}
- CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n",
- lli->lli_key_info->lk_ck.ck_mac,
- lli->lli_key_info->lk_ck.ck_key,
- inode->i_ino);
RETURN(0);
}
LASSERT(it->d.fs_data != NULL);
lustre_data = (struct lustre_intent_data *)it->d.fs_data;
- if (lustre_data->it_key) {
+ if (lustre_data->it_key)
OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
- }
+
OBD_ALLOC(crypto_key, sizeof(struct crypto_key));
-
+ if (!crypto_key)
+ RETURN(-ENOMEM);
+
+ crypto_key->ck_type = MKS_TYPE;
lustre_data->it_key = crypto_key;
lustre_data->it_key_size = sizeof(struct crypto_key);
RETURN(rc);
struct lustre_key *lkey = NULL;
struct posix_acl *acl = NULL;
int rc = 0;
-
ENTRY;
rc = ll_get_acl_key(inode, &acl, &lkey);
GOTO(out, rc);
spin_lock(&lli->lli_lock);
SET_DECRYPTED(lkey->lk_flags);
- spin_unlock(&lli->lli_lock);
+ memcpy(&lkey->lk_dk, lkey->lk_ck.ck_key, KEY_SIZE);
+ spin_unlock(&lli->lli_lock);
+ EXIT;
out:
if (acl)
posix_acl_release(acl);
if (lkey)
lustre_key_release(lkey);
- RETURN(rc);
+ return rc;
}
struct crypto_helper_ops ll_cmd_ops = {
list_for_each_entry(tmp, list, clist) {
if (!strcmp(type, tmp->ctype)) {
CWARN("%s is already registered\n", type);
- rc = -EEXIST;
- GOTO(exit, rc);
+ RETURN(-EEXIST);
}
}
OBD_ALLOC(opi, sizeof(*opi));
+ if (!opi)
+ RETURN(-ENOMEM);
- OBD_ALLOC(opi_name, strlen(type) + 1);
+ OBD_ALLOC(opi_name, strlen(type) + 1);
+ if (!opi_name) {
+ OBD_FREE(opi, sizeof(*opi));
+ RETURN(-ENOMEM);
+ }
- LASSERT(opi && opi_name);
-
memcpy(opi_name, type, strlen(type));
opi->ctype = opi_name;
opi->cops = cops;
list_add_tail(&opi->clist, list);
-exit:
RETURN(rc);
}
ENTRY;
OBD_ALLOC(llci, sizeof(*llci));
-
if (!llci)
RETURN(-ENOMEM);
{
struct list_head *list = &llci->ll_cops_list;
struct crypto_ops_item *tmp, *item;
+ ENTRY;
list_for_each_entry_safe(item, tmp, list, clist) {
list_del_init(&item->clist);
obd_disconnect(llci->ll_gt_exp, 0);
ll_unregister_cops(llci);
- OBD_FREE(llci, sizeof(*llci));
+ OBD_FREE(llci, sizeof(*llci));
+ ll_s2sbi(sb)->ll_crypto_info = NULL;
+
RETURN(0);
}
GOTO(out, rc);
}
ll_s2crpi(sb)->ll_gt_exp = class_conn2export(>_conn);
+ EXIT;
out:
if (rc)
lustre_destroy_crypto(sb);
- RETURN(rc);
+ return rc;
}
struct crypto_helper_ops *
ll_gks_find_ops(struct ll_crypto_info *llc_info, char *type)