You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ma...@apache.org on 2005/07/20 18:42:59 UTC
svn commit: r219940 - in /httpd/httpd/trunk: docs/manual/mod/mod_ssl.xml
modules/ssl/ssl_expr.h modules/ssl/ssl_expr_eval.c
modules/ssl/ssl_expr_parse.y modules/ssl/ssl_expr_scan.l
Author: martin
Date: Wed Jul 20 09:42:58 2005
New Revision: 219940
URL: http://svn.apache.org/viewcvs?rev=219940&view=rev
Log:
Collaborative work: (Thanks, dreid!)
Implement OID checking for mod_ssl. This code allows for checking of arbitrary client
certificate extensions by OID, in a syntax like:
SSLRequire "BaDCA Generated Certificate" in Oid("2.16.840.1.113730.1.13") \
|| "committers" in Oid("1.3.6.1.4.1.18060.1")
Note the following:
* A given OID can occur multiple times in one cert, with different values. Therefore
the OID function compares the left-hand string against each of the OID values,
until a complete match is found. If none patches, the result is FALSE
* The left hand side can be another expression, so can be a reference to a variable
or an file() invocation etc.
* The OID is also just a reference to a string, or function, or whatever.
* My manual description is very short. Someone else please help improve the description
Modified:
httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
httpd/httpd/trunk/modules/ssl/ssl_expr.h
httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
Modified: httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml Wed Jul 20 09:42:58 2005
@@ -1188,7 +1188,7 @@
<usage>
<p>
This directive specifies a general access requirement which has to be
-fulfilled in order to allow access. It's a very powerful directive because the
+fulfilled in order to allow access. It is a very powerful directive because the
requirement specification is an arbitrarily complex boolean expression
containing any number of access checks.</p>
<note type="warning">
@@ -1216,6 +1216,7 @@
| word "<strong>></strong>" word | word "<strong>gt</strong>" word
| word "<strong>>=</strong>" word | word "<strong>ge</strong>" word
| word "<strong>in</strong>" "<strong>{</strong>" wordlist "<strong>}</strong>"
+ | word "<strong>in</strong>" "<strong>OID(</strong>" word "<strong>)</strong>"
| word "<strong>=~</strong>" regex
| word "<strong>!~</strong>" regex
@@ -1258,6 +1259,11 @@
and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \<br />
or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
</example>
+<p>The <code>OID()</code> function expects to find zero or more instances
+of the given OID in the client certificate, and compares the left-hand side
+string against the value of matching OID attributes. Every matching OID is
+checked, until a match is found.
+</p>
<p><em>Standard CGI/1.0 and Apache variables:</em></p>
<pre>
Modified: httpd/httpd/trunk/modules/ssl/ssl_expr.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ssl/ssl_expr.h?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_expr.h Wed Jul 20 09:42:58 2005
@@ -61,7 +61,7 @@
#endif
typedef enum {
- op_NOP, op_ListElement,
+ op_NOP, op_ListElement, op_OidListElement,
op_True, op_False, op_Not, op_Or, op_And, op_Comp,
op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE, op_IN, op_REG, op_NRE,
op_Digit, op_String, op_Regex, op_Var, op_Func
Modified: httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c Wed Jul 20 09:42:58 2005
@@ -36,6 +36,7 @@
static BOOL ssl_expr_eval_comp(request_rec *, ssl_expr *);
static char *ssl_expr_eval_word(request_rec *, ssl_expr *);
+static BOOL ssl_expr_eval_oid(const char *w, request_rec *r, const char *oidstr);
static char *ssl_expr_eval_func_file(request_rec *, char *);
static int ssl_expr_eval_strcmplex(char *, char *);
@@ -113,8 +114,19 @@
char *w1 = ssl_expr_eval_word(r, e1);
BOOL found = FALSE;
do {
+ ssl_expr_node_op op = e2->node_op;
e3 = (ssl_expr *)e2->node_arg1;
e2 = (ssl_expr *)e2->node_arg2;
+
+ if (op == op_OidListElement) {
+ char *w3 = ssl_expr_eval_word(r, e3);
+
+ found = ssl_expr_eval_oid(w1, r, w3);
+
+ /* There will be no more nodes on the list, so the result is authoritative */
+ break;
+ }
+
if (strcmp(w1, ssl_expr_eval_word(r, e3)) == 0) {
found = TRUE;
break;
@@ -185,6 +197,60 @@
}
}
}
+
+static BOOL ssl_expr_eval_oid(const char *word, request_rec *r, const char *oidstr)
+{
+ SSLConnRec *sslconn = myConnConfig(r->connection);
+ SSL *ssl;
+ X509 *xs = NULL;
+ ASN1_OBJECT *oid;
+ int count = 0, j;
+ BOOL result = FALSE;
+
+ if (!oidstr || !sslconn || !sslconn->ssl)
+ return FALSE;
+
+ ssl = sslconn->ssl;
+
+ oid = OBJ_txt2obj(oidstr, 1);
+ if (!oid) {
+ ERR_clear_error();
+ return FALSE;
+ }
+
+ xs = SSL_get_peer_certificate(ssl);
+ if (xs == NULL) {
+ return FALSE;
+ }
+
+ count = X509_get_ext_count(xs);
+
+ for (j = 0; j < count; j++) {
+ X509_EXTENSION *ext = X509_get_ext(xs, j);
+
+ if (OBJ_cmp(ext->object, oid) == 0) {
+ BIO *bio = BIO_new(BIO_s_mem());
+
+ if (X509V3_EXT_print(bio, ext, 0, 0) == 1) {
+ BUF_MEM *buf;
+
+ BIO_get_mem_ptr(bio, &buf);
+
+ if (strcmp(word, buf->data) == 0)
+ result = TRUE;
+ }
+
+ BIO_vfree(bio);
+ if (result != FALSE)
+ break;
+ }
+ }
+
+ X509_free(xs);
+ ERR_clear_error();
+ return result;
+}
+
static char *ssl_expr_eval_func_file(request_rec *r, char *filename)
{
Modified: httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y Wed Jul 20 09:42:58 2005
@@ -61,6 +61,7 @@
%token T_OP_REG
%token T_OP_NRE
%token T_OP_IN
+%token T_OP_OID
%token T_OP_OR
%token T_OP_AND
@@ -75,6 +76,7 @@
%type <exVal> funccall
%type <exVal> regex
%type <exVal> words
+%type <exVal> wordlist
%type <exVal> word
%%
@@ -97,10 +99,14 @@
| word T_OP_LE word { $$ = ssl_expr_make(op_LE, $1, $3); }
| word T_OP_GT word { $$ = ssl_expr_make(op_GT, $1, $3); }
| word T_OP_GE word { $$ = ssl_expr_make(op_GE, $1, $3); }
- | word T_OP_IN '{' words '}' { $$ = ssl_expr_make(op_IN, $1, $4); }
+ | word T_OP_IN wordlist { $$ = ssl_expr_make(op_IN, $1, $3); }
| word T_OP_REG regex { $$ = ssl_expr_make(op_REG, $1, $3); }
| word T_OP_NRE regex { $$ = ssl_expr_make(op_NRE, $1, $3); }
;
+
+wordlist : T_OP_OID '(' word ')' { $$ = ssl_expr_make(op_OidListElement, $3, NULL); }
+ | '{' words '}' { $$ = $2 ; }
+ ;
words : word { $$ = ssl_expr_make(op_ListElement, $1, NULL); }
| words ',' word { $$ = ssl_expr_make(op_ListElement, $3, $1); }
Modified: httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l Wed Jul 20 09:42:58 2005
@@ -173,6 +173,7 @@
"not" { return T_OP_NOT; }
"!" { return T_OP_NOT; }
"in" { return T_OP_IN; }
+[Oo][Ii][Dd] { return T_OP_OID; }
/*
* Functions
Re: svn commit: r219940 - in /httpd/httpd/trunk: docs/manual/mod/mod_ssl.xml modules/ssl/ssl_expr.h modules/ssl/ssl_expr_eval.c modules/ssl/ssl_expr_parse.y modules/ssl/ssl_expr_scan.l
Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
On Fri, Jul 22, 2005 at 12:02:29PM +0100, Joe Orton wrote:
> and since I can't update to fix (2) myself, here's another...
Try again. All should be operational again. -- justin
Re: svn commit: r219940 - in /httpd/httpd/trunk: docs/manual/mod/mod_ssl.xml modules/ssl/ssl_expr.h modules/ssl/ssl_expr_eval.c modules/ssl/ssl_expr_parse.y modules/ssl/ssl_expr_scan.l
Posted by Joe Orton <jo...@redhat.com>.
On Fri, Jul 22, 2005 at 11:12:07AM +0100, Joe Orton wrote:
> On Wed, Jul 20, 2005 at 04:42:59PM -0000, Martin Kraemer wrote:
> > Author: martin
> > Date: Wed Jul 20 09:42:58 2005
> > New Revision: 219940
> >
> > URL: http://svn.apache.org/viewcvs?rev=219940&view=rev
> > Log:
> > Collaborative work: (Thanks, dreid!)
> > Implement OID checking for mod_ssl. This code allows for checking of arbitrary client
> > certificate extensions by OID, in a syntax like:
> > SSLRequire "BaDCA Generated Certificate" in Oid("2.16.840.1.113730.1.13") \
> > || "committers" in Oid("1.3.6.1.4.1.18060.1")
> > Note the following:
> > * A given OID can occur multiple times in one cert, with different values. Therefore
> > the OID function compares the left-hand string against each of the OID values,
> > until a complete match is found. If none patches, the result is FALSE
> > * The left hand side can be another expression, so can be a reference to a variable
> > or an file() invocation etc.
> > * The OID is also just a reference to a string, or function, or whatever.
> > * My manual description is very short. Someone else please help improve the description
and since I can't update to fix (2) myself, here's another...
3) oid() is a terrible name for this; it's simply the type of the
parameter. It would be like calling malloc() "size()". The function
expands (conceptually) to the values of an extension in the peer's
certificate, identified by OID; so call it peerext() or something
meaningful like that.
Re: svn commit: r219940 - in /httpd/httpd/trunk: docs/manual/mod/mod_ssl.xml modules/ssl/ssl_expr.h modules/ssl/ssl_expr_eval.c modules/ssl/ssl_expr_parse.y modules/ssl/ssl_expr_scan.l
Posted by Joe Orton <jo...@redhat.com>.
On Wed, Jul 20, 2005 at 04:42:59PM -0000, Martin Kraemer wrote:
> Author: martin
> Date: Wed Jul 20 09:42:58 2005
> New Revision: 219940
>
> URL: http://svn.apache.org/viewcvs?rev=219940&view=rev
> Log:
> Collaborative work: (Thanks, dreid!)
> Implement OID checking for mod_ssl. This code allows for checking of arbitrary client
> certificate extensions by OID, in a syntax like:
> SSLRequire "BaDCA Generated Certificate" in Oid("2.16.840.1.113730.1.13") \
> || "committers" in Oid("1.3.6.1.4.1.18060.1")
> Note the following:
> * A given OID can occur multiple times in one cert, with different values. Therefore
> the OID function compares the left-hand string against each of the OID values,
> until a complete match is found. If none patches, the result is FALSE
> * The left hand side can be another expression, so can be a reference to a variable
> or an file() invocation etc.
> * The OID is also just a reference to a string, or function, or whatever.
> * My manual description is very short. Someone else please help improve the description
1) this is a pretty specific to way to code it. Is there no way to make
it more general so that OID() is just a function like file() and can be
used e.g. in regex matches too?
2) you must always check in the regenerated generated scanner source
along with changes to the lex file.
Regards,
joe