WvStreams
unisecuregen.cc
1/*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 2002 Net Integration Technologies, Inc.
4 *
5 * UniSecureGen is a UniConfGen for checking permissions before allowing
6 * access to a UniConf tree. See unisecuregen.h and unipermgen.h.
7 */
8#include "unisecuregen.h"
9#include "wvmoniker.h"
10#include "wvstringlist.h"
11#include "wvtclstring.h"
12#include "wvlog.h"
13#include "wvbuf.h"
14#include "wvlinkerhack.h"
15
16WV_LINK(UniSecureGen);
17
18
19static IUniConfGen *creator(WvStringParm s, IObject *)
20{
21 return new UniSecureGen(s);
22}
23
24static WvMoniker<IUniConfGen> reg("perm", creator);
25
26
27UniSecureGen::UniSecureGen(WvStringParm moniker, UniPermGen *_perms)
28 : UniFilterGen(NULL)
29{
30 WvString mainmon(moniker), permmon;
31
32 if (!_perms)
33 {
34 WvConstInPlaceBuf buf(moniker, moniker.len());
35 permmon = wvtcl_getword(buf);
36 mainmon = wvtcl_getword(buf);
37
38 IUniConfGen *_perms = wvcreate<IUniConfGen>(permmon);
39 assert(_perms);
40 perms = new UniPermGen(_perms);
41 perms->refresh();
42 }
43
44 IUniConfGen *main = wvcreate<IUniConfGen>(mainmon);
45 setinner(main);
46}
47
48
49UniSecureGen::UniSecureGen(IUniConfGen *_gen, UniPermGen *_perms)
50 : UniFilterGen(_gen)
51{
52 assert(_perms);
53 perms = _perms;
54 perms->refresh();
55}
56
57
58void UniSecureGen::setcredentials(const UniPermGen::Credentials &_cred)
59{
60 cred.user = _cred.user;
61 cred.groups.zap();
62 WvStringTable::Iter i(_cred.groups);
63 for (i.rewind(); i.next(); )
64 cred.groups.add(new WvString(*i), true);
65}
66
67
68void UniSecureGen::setcredentials(WvStringParm user, const WvStringList &groups)
69{
70 cred.user = user;
71 cred.groups.zap();
72 WvStringList::Iter i(groups);
73 for (i.rewind(); i.next(); )
74 cred.groups.add(new WvString(*i), true);
75}
76
77
79{
80 perms->refresh();
81 return UniFilterGen::refresh();
82}
83
84
86{
87 perms->commit();
89}
90
91
93{
94 if (findperm(key, UniPermGen::READ))
95 {
96 WvString val = UniFilterGen::get(key);
97 return val;
98 }
99
100 return WvString::null;
101}
102
103
105{
106 if (findperm(key.removelast(), UniPermGen::EXEC))
107 return UniFilterGen::exists(key);
108 return false;
109}
110
111
113{
114 if (findperm(key, UniPermGen::WRITE))
115 UniFilterGen::set(key, value);
116}
117
118
120{
121 if (findperm(key, UniPermGen::EXEC))
122 return UniFilterGen::haschildren(key);
123 return false;
124}
125
126
128{
130 UniSecureGen *gen;
131 UniConfKey subpath;
132
133public:
135 it(_it),
136 gen(_gen),
137 subpath(_subpath)
138 { }
139 virtual ~_UniSecureIter()
140 { delete it; }
141
142 virtual void rewind()
143 { it->rewind(); }
144
145 virtual bool next()
146 { return it->next(); }
147
148 virtual UniConfKey key() const
149 { return it->key(); } // if we've come this far, this is ok
150
151 virtual WvString value() const
152 {
153 UniConfKey realkey = it->key();
154 realkey.prepend(subpath);
155 return gen->get(realkey);
156 }
157};
158
159
161{
162 // we don't check the permissions on keys returned by the iterator, but
163 // that's okay: since this iterator is non-recursive, and we've checked
164 // permissions on the parent key, we know we're allowed to at least read
165 // the *names* of all child keys (even if the value itself is unreadable)
166 if (findperm(key, UniPermGen::EXEC))
167 return new _UniSecureIter(UniFilterGen::iterator(key), this, key);
168
169 return NULL;
170}
171
172
174{
175 // FIXME: this needs to check permissions on *every* key, not just the
176 // top one, so we'll cheat: use the default UniConfGen recursiveiterator
177 // instead, which just calls the non-recursive iterator recursively.
178 // This can be bad for performance, but not in any of the situations
179 // we currently need. (ie. security is usually done on the server side,
180 // but it's the client-to-server connection that needs a fast recursive
181 // iterator, so it'll be fine.)
182 if (findperm(key, UniPermGen::EXEC))
184
185 return NULL;
186}
187
188
189void UniSecureGen::gencallback(const UniConfKey &key, WvStringParm value)
190{
191 if (findperm(key, UniPermGen::READ))
192 delta(key, value);
193}
194
195
196bool UniSecureGen::findperm(const UniConfKey &key, UniPermGen::Type type)
197{
198 if (!drilldown(key))
199 return false;
200 else
201 return perms->getperm(key, cred, type);
202}
203
204
205bool UniSecureGen::drilldown(const UniConfKey &key)
206{
207 UniConfKey check;
208 UniConfKey left = key;
209
210 while (!left.isempty())
211 {
212 // check the exec perm
213 if (!perms->getperm(check, cred, UniPermGen::EXEC))
214 return false;
215
216 // move the first segment of left to check
217 // note that when left is empty, we exit the loop before checking the
218 // last segment. That's on purpose: the last segment is the 'file'
219 // and we only need to check the 'directories'
220 check.append(left.first());
221 left = left.removefirst();
222 }
223 return true;
224}
The basic interface which is included by all other XPLC interfaces and objects.
Definition IObject.h:65
An abstract data container that backs a UniConf tree.
Definition uniconfgen.h:40
An abstract iterator over keys and values in a generator.
Definition uniconfgen.h:324
virtual bool next()=0
Seeks to the next element in the sequence.
virtual void rewind()=0
Rewinds the iterator.
virtual UniConfKey key() const =0
Returns the current key.
void delta(const UniConfKey &key, WvStringParm value)
Call this when a key's value or children have possibly changed.
Definition uniconfgen.cc:77
virtual Iter * recursiveiterator(const UniConfKey &key)
Like iterator(), but the returned iterator is recursive, that is, it will return children of the imme...
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition uniconfkey.h:39
UniConfKey removefirst(int n=1) const
Returns the path formed by removing the first n segments of this path.
Definition uniconfkey.h:335
UniConfKey removelast(int n=1) const
Returns the path formed by removing the last n segments of this path.
Definition uniconfkey.h:346
void prepend(const UniConfKey &other)
Prepends a path to this path.
void append(const UniConfKey &other)
Appends a path to this path.
bool isempty() const
Returns true if this path has zero segments (also known as root).
Definition uniconfkey.h:264
UniConfKey first(int n=1) const
Returns the path formed by the n first segments of this path.
Definition uniconfkey.h:314
A UniConfGen that delegates all requests to an inner generator.
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
virtual bool exists(const UniConfKey &key)
Without fetching its value, returns true if a key exists.
virtual bool refresh()
Refreshes information about a key recursively.
virtual void commit()
Commits any changes.
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
UniPermGen wraps a tree encoding Unix-style permissions, and provides an API for setting and checking...
Definition unipermgen.h:27
UniSecureGen wraps a given generator and checks permissions (using a Unix-style scheme) before respon...
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
virtual Iter * recursiveiterator(const UniConfKey &key)
Like iterator(), but the returned iterator is recursive, that is, it will return children of the imme...
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
virtual bool refresh()
Refreshes information about a key recursively.
virtual void commit()
Commits any changes.
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
virtual bool exists(const UniConfKey &key)
Without fetching its value, returns true if a key exists.
The const in place raw memory buffer type.
Definition wvbuf.h:188
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition wvstring.h:94
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition wvmoniker.h:62
This is a WvList of WvStrings, and is a really handy way to parse strings.
WvString is an implementation of a simple and efficient printable-string class.
Definition wvstring.h:330
virtual void rewind()
Rewinds the iterator.
virtual WvString value() const
Returns the value of the current key.
virtual UniConfKey key() const
Returns the current key.
virtual bool next()
Seeks to the next element in the sequence.
Functions to handle "tcl-style" strings and lists.
WvString wvtcl_getword(WvBuf &buf, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
Get a single tcl word from an input buffer, and return the rest of the buffer untouched.