Commit e39c8f41 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Implement distinct read/write access control for variables.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@4741 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent ebe4e059
......@@ -69,7 +69,7 @@ parse_error(struct tokenlist *tl)
vcc_NextToken(tl);
if (tl->t->tok == VAR) {
vp = vcc_FindVar(tl, tl->t, vcc_vars);
vp = vcc_FindVar(tl, tl->t, vcc_vars, 0, "read");
ERRCHK(tl);
assert(vp != NULL);
if (vp->fmt == INT) {
......@@ -111,16 +111,6 @@ illegal_assignment(const struct tokenlist *tl, const char *type)
" only '=' is legal for %s\n", type);
}
static void
check_writebit(struct tokenlist *tl, const struct var *vp)
{
if (vp->access == V_RW || vp->access == V_WO)
return;
vsb_printf(tl->sb, "Variable %.*s cannot be modified.\n", PF(tl->t));
vcc_ErrWhere(tl, tl->t);
}
static void
parse_set(struct tokenlist *tl)
{
......@@ -130,11 +120,9 @@ parse_set(struct tokenlist *tl)
vcc_NextToken(tl);
ExpectErr(tl, VAR);
vt = tl->t;
vp = vcc_FindVar(tl, tl->t, vcc_vars);
vp = vcc_FindVar(tl, tl->t, vcc_vars, 1, "set");
ERRCHK(tl);
assert(vp != NULL);
check_writebit(tl, vp);
ERRCHK(tl);
Fb(tl, 1, "%s", vp->lname);
vcc_NextToken(tl);
switch (vp->fmt) {
......@@ -262,15 +250,15 @@ parse_unset(struct tokenlist *tl)
vcc_NextToken(tl);
ExpectErr(tl, VAR);
vp = vcc_FindVar(tl, tl->t, vcc_vars);
vp = vcc_FindVar(tl, tl->t, vcc_vars, 1, "unset");
ERRCHK(tl);
assert(vp != NULL);
if (vp->fmt != STRING || vp->hdr == NULL) {
vsb_printf(tl->sb, "Only http header lines can be unset.\n");
vsb_printf(tl->sb,
"Only http header variables can be unset.\n");
vcc_ErrWhere(tl, tl->t);
return;
}
check_writebit(tl, vp);
ERRCHK(tl);
Fb(tl, 1, "%s0);\n", vp->lname);
vcc_NextToken(tl);
......
......@@ -109,12 +109,6 @@ enum var_type {
HEADER
};
enum var_access {
V_RO,
V_RW,
V_WO
};
enum ref_type {
R_FUNC,
R_ACL,
......@@ -134,10 +128,10 @@ struct var {
enum var_type fmt;
unsigned len;
const char *rname;
unsigned r_methods;
const char *lname;
enum var_access access;
unsigned l_methods;
const char *hdr;
unsigned methods;
};
struct method {
......@@ -225,7 +219,7 @@ void vcc_AddToken(struct tokenlist *tl, unsigned tok, const char *b,
/* vcc_var.c */
struct var *vcc_FindVar(struct tokenlist *tl, const struct token *t,
struct var *vl);
struct var *vl, int wr_access, const char *use);
void vcc_VarVal(struct tokenlist *tl, const struct var *vp,
const struct token *vt);
......@@ -238,7 +232,8 @@ void vcc_AddCall(struct tokenlist *tl, struct token *t);
struct proc *vcc_AddProc(struct tokenlist *tl, struct token *t);
void vcc_ProcAction(struct proc *p, unsigned action, struct token *t);
int vcc_CheckAction(struct tokenlist *tl);
void vcc_AddUses(struct tokenlist *tl, struct var *v);
void vcc_AddUses(struct tokenlist *tl, const struct token *t, unsigned mask,
const char *use);
int vcc_CheckUses(struct tokenlist *tl);
#define ERRCHK(tl) do { if ((tl)->err) return; } while (0)
......
......@@ -215,8 +215,8 @@ vcl_output_lang_h(struct vsb *sb)
"OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR "
"TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"
" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE "
"POSSIBILITY OF\n * SUCH DAMAGE.\n *\n * $Id: vrt.h 4668 2010-04-"
"16 10:24:59Z phk $\n *\n * Runtime support for compiled VCL "
"POSSIBILITY OF\n * SUCH DAMAGE.\n *\n * $Id: vrt.h 4735 2010-04-"
"27 15:19:41Z phk $\n *\n * Runtime support for compiled VCL "
"programs.\n *\n * XXX: When this file is changed, lib/libvcl/gen"
"erate.py *MUST* be rerun.\n */\n\nstruct sess;\nstruct vsb;\n"
"struct cli;\nstruct director;\nstruct VCL_conf;\n"
......
This diff is collapsed.
......@@ -333,7 +333,7 @@ vcc_Cond_2(struct tokenlist *tl)
vcc_Cond_0(tl);
SkipToken(tl, ')');
} else if (tl->t->tok == VAR) {
vp = vcc_FindVar(tl, tl->t, vcc_vars);
vp = vcc_FindVar(tl, tl->t, vcc_vars, 0, "read");
ERRCHK(tl);
assert(vp != NULL);
vcc_NextToken(tl);
......
......@@ -154,7 +154,7 @@ vcc_StringVal(struct tokenlist *tl)
if (tl->t->tok == ID && vcc_IdIs(tl->t, "regsuball"))
return (vcc_regsub(tl, 1));
if (tl->t->tok == VAR) {
vp = vcc_FindVar(tl, tl->t, vcc_vars);
vp = vcc_FindVar(tl, tl->t, vcc_vars, 0, "read");
if (tl->err)
return (0);
assert(vp != NULL);
......
......@@ -61,10 +61,10 @@ HeaderVar(struct tokenlist *tl, const struct token *t, const struct var *vh)
memcpy(p, t->b, i);
p[i] = '\0';
v->name = p;
v->access = V_RW;
v->r_methods = vh->r_methods;
v->l_methods = vh->l_methods;
v->fmt = STRING;
v->hdr = vh->hdr;
v->methods = vh->methods;
l = strlen(v->name + vh->len) + 1;
bprintf(buf, "VRT_GetHdr(sp, %s, \"\\%03o%s:\")",
......@@ -87,7 +87,8 @@ HeaderVar(struct tokenlist *tl, const struct token *t, const struct var *vh)
/*--------------------------------------------------------------------*/
struct var *
vcc_FindVar(struct tokenlist *tl, const struct token *t, struct var *vl)
vcc_FindVar(struct tokenlist *tl, const struct token *t, struct var *vl,
int wr_access, const char *use)
{
struct var *v;
......@@ -98,7 +99,25 @@ vcc_FindVar(struct tokenlist *tl, const struct token *t, struct var *vl)
continue;
if (memcmp(t->b, v->name, v->len))
continue;
vcc_AddUses(tl, v);
if (wr_access && v->l_methods == 0) {
vsb_printf(tl->sb, "Variable ");
vcc_ErrToken(tl, t);
vsb_printf(tl->sb, " is read only.");
vsb_cat(tl->sb, "\nAt: ");
vcc_ErrWhere(tl, t);
return (NULL);
} else if (wr_access) {
vcc_AddUses(tl, t, v->l_methods, use);
} else if (v->r_methods == 0) {
vsb_printf(tl->sb, "Variable ");
vcc_ErrToken(tl, t);
vsb_printf(tl->sb, " is write only.");
vsb_cat(tl->sb, "\nAt: ");
vcc_ErrWhere(tl, t);
return (NULL);
} else {
vcc_AddUses(tl, t, v->r_methods, use);
}
if (v->fmt != HEADER)
return (v);
return (HeaderVar(tl, t, v));
......
......@@ -61,7 +61,8 @@ struct proccall {
struct procuse {
VTAILQ_ENTRY(procuse) list;
struct token *t;
struct var *v;
unsigned mask;
const char *use;
};
struct proc {
......@@ -212,16 +213,19 @@ vcc_AddProc(struct tokenlist *tl, struct token *t)
}
void
vcc_AddUses(struct tokenlist *tl, struct var *v)
vcc_AddUses(struct tokenlist *tl, const struct token *t, unsigned mask,
const char *use)
{
struct procuse *pu;
(void)t;
if (tl->curproc == NULL) /* backend */
return;
pu = TlAlloc(tl, sizeof *pu);
assert(pu != NULL);
pu->v = v;
pu->t = tl->t;
pu->mask = mask;
pu->use = use;
VTAILQ_INSERT_TAIL(&tl->curproc->uses, pu, list);
}
......@@ -339,7 +343,7 @@ vcc_FindIllegalUse(const struct proc *p, const struct method *m)
struct procuse *pu;
VTAILQ_FOREACH(pu, &p->uses, list)
if (!(pu->v->methods & m->bitval))
if (!(pu->mask & m->bitval))
return (pu);
return (NULL);
}
......@@ -389,8 +393,8 @@ vcc_CheckUses(struct tokenlist *tl)
pu = vcc_FindIllegalUse(p, m);
if (pu != NULL) {
vsb_printf(tl->sb,
"Variable '%.*s' not accessible in method '%.*s'.",
PF(pu->t), PF(p->name));
"Variable '%.*s': %s not allowed in method '%.*s'.",
PF(pu->t), pu->use, PF(p->name));
vsb_cat(tl->sb, "\nAt: ");
vcc_ErrWhere(tl, pu->t);
return (1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment