static int openssl_xext_data(lua_State* L) { int ret = 0; X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); if (lua_isnone(L, 2)) { ASN1_STRING *s = X509_EXTENSION_get_data(x); s = ASN1_STRING_dup(s); PUSH_OBJECT(s, "openssl.asn1_string"); return 1; } else if (lua_isstring(L, 2)) { size_t size; const char* data = lua_tolstring(L, 2, &size); ASN1_STRING* s = ASN1_STRING_type_new(V_ASN1_OCTET_STRING); if (ASN1_STRING_set(s, data, size) == 1) { ret = X509_EXTENSION_set_data(x, s); } ASN1_STRING_free(s); return openssl_pushresult(L, ret); } else { ASN1_STRING* s = CHECK_GROUP(2, ASN1_STRING, "openssl.asn1group"); if (ASN1_STRING_type(s) == V_ASN1_OCTET_STRING) { int ret; ret = X509_EXTENSION_set_data(x, s); return openssl_pushresult(L, ret); } else { luaL_argerror(L, 2, "asn1_string type must be octet"); } } return 0; };
static X509_ATTRIBUTE* openssl_new_xattribute(lua_State*L, X509_ATTRIBUTE** a, int idx, const char* eprefix) { int arttype; size_t len; int nid; const char* data; lua_getfield(L, idx, "object"); nid = openssl_get_nid(L, -1); if (nid == NID_undef) { if (eprefix) { luaL_error(L, "%s field object is invalid value", eprefix); } else luaL_argcheck(L, nid != NID_undef, idx, "field object is invalid value"); } lua_pop(L, 1); lua_getfield(L, idx, "type"); arttype = luaL_checkint(L, -1); if (arttype == V_ASN1_UNDEF || arttype == 0) { if (eprefix) { luaL_error(L, "%s field type is not invalid value", eprefix); } else luaL_argcheck(L, nid != NID_undef, idx, "field type is not invalid value"); } lua_pop(L, 1); lua_getfield(L, idx, "value"); if (lua_isstring(L, -1)) { data = lua_tolstring(L, -1, &len); } else if (auxiliar_isgroup(L, "openssl.asn1group", -1)) { ASN1_STRING* value = CHECK_GROUP(-1, ASN1_STRING, "openssl.asn1group"); if (ASN1_STRING_type(value) != arttype) { if (eprefix) luaL_error(L, "%s field value not match type", eprefix); else luaL_argcheck(L, ASN1_STRING_type(value) == arttype, idx, "field value not match type"); } data = (const char *)ASN1_STRING_data(value); len = ASN1_STRING_length(value); } else { if (eprefix) { luaL_error(L, "%s filed value only accept string or asn1_string", eprefix); } else luaL_argerror(L, idx, "filed value only accept string or asn1_string"); } lua_pop(L, 1); return X509_ATTRIBUTE_create_by_NID(a, nid, arttype, data, len); }
int pfq_getsockopt(struct socket *sock, int level, int optname, char __user * optval, int __user * optlen) { struct pfq_sock *so = pfq_sk(sock->sk); struct pfq_rx_opt * ro; struct pfq_tx_opt * to; int len; if (so == NULL) return -EFAULT; ro = &so->rx_opt; to = &so->tx_opt; if (get_user(len, optlen)) return -EFAULT; if (len < 0) return -EINVAL; switch(optname) { case Q_SO_GROUP_JOIN: { struct pfq_group_join group; if (len != sizeof(group)) return -EINVAL; if (copy_from_user(&group, optval, sizeof(group))) return -EFAULT; if (group.class_mask == 0) { pr_devel("[PFQ|%d] join error: bad class_mask(%lx)!\n", so->id, group.class_mask); return -EINVAL; } if (group.gid == Q_ANY_GROUP) { group.gid = pfq_join_free_group(so->id, group.class_mask, group.policy); if (group.gid < 0) return -EFAULT; if (copy_to_user(optval, &group, len)) return -EFAULT; } else { CHECK_GROUP(so->id, group.gid, "group join"); if (pfq_join_group(group.gid, so->id, group.class_mask, group.policy) < 0) { pr_devel("[PFQ|%d] join error: permission denied (gid:%d)!\n", so->id, group.gid); return -EACCES; } } pr_devel("[PFQ|%d] join -> gid:%d class_mask:%lx\n", so->id, group.gid, group.class_mask); } break; case Q_SO_GET_ID: { if (len != sizeof(so->id)) return -EINVAL; if (copy_to_user(optval, &so->id, sizeof(so->id))) return -EFAULT; } break; case Q_SO_GET_STATUS: { int enabled; if (len != sizeof(int)) return -EINVAL; enabled = so->mem_addr == NULL ? 0 : 1; if (copy_to_user(optval, &enabled, sizeof(enabled))) return -EFAULT; } break; case Q_SO_GET_STATS: { struct pfq_stats stat; if (len != sizeof(struct pfq_stats)) return -EINVAL; stat.recv = sparse_read(&ro->stat.recv); stat.lost = sparse_read(&ro->stat.lost); stat.drop = sparse_read(&ro->stat.drop); stat.sent = sparse_read(&to->stat.sent); stat.disc = sparse_read(&to->stat.disc); if (copy_to_user(optval, &stat, sizeof(stat))) return -EFAULT; } break; case Q_SO_GET_RX_TSTAMP: { if (len != sizeof(ro->tstamp)) return -EINVAL; if (copy_to_user(optval, &ro->tstamp, sizeof(ro->tstamp))) return -EFAULT; } break; case Q_SO_GET_QUEUE_MEM: { if (len != sizeof(so->mem_size)) return -EINVAL; if (copy_to_user(optval, &so->mem_size, sizeof(so->mem_size))) return -EFAULT; } break; case Q_SO_GET_RX_CAPLEN: { if (len != sizeof(ro->caplen)) return -EINVAL; if (copy_to_user(optval, &ro->caplen, sizeof(ro->caplen))) return -EFAULT; } break; case Q_SO_GET_TX_MAXLEN: { if (len != sizeof(to->maxlen)) return -EINVAL; if (copy_to_user(optval, &to->maxlen, sizeof(to->maxlen))) return -EFAULT; } break; case Q_SO_GET_RX_SLOTS: { if (len != sizeof(ro->size)) return -EINVAL; if (copy_to_user(optval, &ro->size, sizeof(ro->size))) return -EFAULT; } break; case Q_SO_GET_TX_SLOTS: { if (len != sizeof(to->size)) return -EINVAL; if (copy_to_user(optval, &to->size, sizeof(to->size))) return -EFAULT; } break; case Q_SO_GET_GROUPS: { unsigned long grps; if(len != sizeof(unsigned long)) return -EINVAL; grps = pfq_get_groups(so->id); if (copy_to_user(optval, &grps, sizeof(grps))) return -EFAULT; } break; case Q_SO_GET_GROUP_STATS: { struct pfq_group *g; struct pfq_stats stat; int gid; if (len != sizeof(stat)) return -EINVAL; if (copy_from_user(&stat, optval, sizeof(stat))) return -EFAULT; gid = (int)stat.recv; CHECK_GROUP(so->id, gid, "group stat"); g = pfq_get_group(gid); if (!g) { pr_devel("[PFQ|%d] group error: invalid group id %d!\n", so->id, gid); return -EFAULT; } /* check whether the group is joinable.. */ if (!__pfq_group_access(gid, so->id, Q_POLICY_GROUP_UNDEFINED, false)) { pr_devel("[PFQ|%d] group stats error: permission denied (gid:%d)!\n", so->id, gid); return -EACCES; } stat.recv = sparse_read(&g->recv); stat.lost = sparse_read(&g->lost); stat.drop = sparse_read(&g->drop); stat.sent = 0; stat.disc = 0; if (copy_to_user(optval, &stat, sizeof(stat))) return -EFAULT; } break; case Q_SO_GET_GROUP_COUNTERS: { struct pfq_group *g; struct pfq_counters cs; int i, gid; if (len != sizeof(cs)) return -EINVAL; if (copy_from_user(&cs, optval, sizeof(cs))) return -EFAULT; gid = (int)cs.counter[0]; CHECK_GROUP(so->id, gid, "group stat"); g = pfq_get_group(gid); if (!g) { pr_devel("[PFQ|%d] group error: invalid group id %d!\n", so->id, gid); return -EFAULT; } /* check whether the group is joinable.. */ if (!__pfq_group_access(gid, so->id, Q_POLICY_GROUP_UNDEFINED, false)) { pr_devel("[PFQ|%d] group error: permission denied (gid:%d)!\n", so->id, gid); return -EACCES; } for(i = 0; i < Q_MAX_COUNTERS; i++) { cs.counter[i] = sparse_read(&g->ctx.counter[i]); } if (copy_to_user(optval, &cs, sizeof(cs))) return -EFAULT; } break; default: return -EFAULT; } return 0; }
static X509_EXTENSION* openssl_new_xextension(lua_State*L, int idx, int v3) { int nid; int critical = 0; ASN1_OCTET_STRING* value = NULL; X509_EXTENSION* y = NULL; lua_getfield(L, idx, "object"); nid = openssl_get_nid(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "critical"); critical = lua_isnil(L, -1) ? 0 : lua_toboolean(L, -1); lua_pop(L, 1); if (nid == NID_undef) { lua_pushfstring(L, "%s is not valid object id", lua_tostring(L, -1)); luaL_argerror(L, idx, lua_tostring(L, -1)); } lua_getfield(L, idx, "value"); luaL_argcheck(L, lua_isstring(L, -1) || auxiliar_isgroup(L, "openssl.asn1group", -1), 1, "field value must be string or openssl.asn1group object"); if (lua_isstring(L, -1)) { size_t size; const char* data = lua_tolstring(L, -1, &size); if (v3) { const X509V3_EXT_METHOD *method = X509V3_EXT_get_nid(nid); if (method) { void *ext_struc = NULL; STACK_OF(CONF_VALUE) *nval = X509V3_parse_list(data); /* Now get internal extension representation based on type */ if (method->v2i && nval) { if (sk_CONF_VALUE_num(nval) > 0) { ext_struc = method->v2i(method, NULL, nval); } } else if (method->s2i) { ext_struc = method->s2i(method, NULL, data); } if (nval) sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); if (ext_struc) { unsigned char *ext_der = NULL; int ext_len; /* Convert internal representation to DER */ if (method->it) { ext_der = NULL; ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); if (ext_len < 0) { ext_der = NULL; } } else { ext_len = method->i2d(ext_struc, NULL); ext_der = OPENSSL_malloc(ext_len); if (ext_der) { unsigned char* p = ext_der; method->i2d(ext_struc, &p); } } if (ext_der) { value = ASN1_STRING_type_new(V_ASN1_OCTET_STRING); ASN1_STRING_set(value, ext_der, ext_len); } else value = NULL; if (method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); else method->ext_free(ext_struc); } } } else { value = ASN1_STRING_type_new(V_ASN1_OCTET_STRING); ASN1_STRING_set(value, data, size); } if (value) { y = X509_EXTENSION_create_by_NID(NULL, nid, critical, value); ASN1_STRING_free(value); return y; } else { luaL_error(L, "don't support object(%s) with value (%s)", OBJ_nid2ln(nid), data); return NULL; } } else { value = CHECK_GROUP(-1, ASN1_STRING, "openssl.asn1group"); y = X509_EXTENSION_create_by_NID(NULL, nid, critical, value); lua_pop(L, 1); return y; } }