[mp2 Patch] Apache::Directive->lookup($directive, [$args]);

2003-01-27 Thread Philippe M. Chiasson
Following a discussion about how to best access the information stored in
Apache's configuration tree, I now submit Apache::Directive->lookup()

In a nutshell, one could now do this:

 my $tree = Apache::Directive->conftree;
 my $port = $tree->lookup('Listen');

Or even cooler:

 my @vhosts = Apache::Directive->lookup('VirtualHost');

Or to search

 my $vhost = Apache::Directive->lookup('VirtualHost','localhost:');

Feedback please ;-)

P.S. I also kinda wanted lookup() to finish off  sections ;-p

$Id: Apache-Directive-lookup.patch,v 1.7 2003/01/27 11:59:23 gozer Exp $

--- /dev/null   2002-08-31 07:31:37.0 +0800
+++ docs/api/mod_perl-2.0/Apache/Directive.pod  2003-01-25 17:23:56.0 +0800
@@ -0,0 +1,134 @@
+=head1 NAME
+
+Apache::Directive -- A Perl API for manipulating Apache configuration tree
+
+=head1 SYNOPSIS
+
+  use Apache::Directive;
+
+  my $tree = Apache::Directive->conftree;
+  
+  my $documentroot = $tree->lookup('DocumentRoot');
+
+  my $vhost = $tree->lookup('VirtualHost', 'localhost:8000');
+  my $servername = $vhost->{'ServerName'};
+
+  print $tree->as_string;
+  print Dumper($tree->as_hash);
+  
+  while ($node) {
+
+#do something with $node
+
+if (my $kid = $node->first_child) {
+  $node = $kid;
+} 
+elsif (my $next = $node->next) {
+  $node = $next;
+}
+else {
+  if (my $parent = $node->parent) {
+$node = $parent->next;
+  }
+  else {
+$node = undef;
+  }
+}
+  }
+
+=head1 DESCRIPTION
+
+C allows its users to search and navigate the internal Apache
+configuration.
+
+Internally, this information is stored in a tree structure. Each node in the tree
+has a reference to it's parent (if it's not the root), it's first child (if any),
+and to its next sibling.
+
+=head1 API
+
+Function arguments (if any) and return values are shown in the
+function's synopsis.
+
+=over 4
+
+=item * conftree()
+
+   $tree = Apache::Directive->conftree();
+
+Returns the root of the configuration tree.
+
+=item * next()
+
+   $node = $node->next;
+
+Returns the next sibbling of C<$node>, undef otherwise
+
+=item * first_child()
+
+  $subtree = $node->first_child;
+
+Returns the first child node of C<$node>, undef otherwise
+
+=item * parent()
+
+  $parent = $node->parent;
+
+Returns the parent of C<$node>, undef if this node is the root node
+
+=item * directive()
+
+  $name = $node->directive;
+
+Returns the name of the directive in C<$node>
+
+=item * args()
+
+  $args = $node->args;
+
+Returns the arguments to this C<$node>
+
+=item * filename()
+
+  $fname = $node->filename;
+
+Returns the filename this C<$node> was created from
+
+=item * line_number()
+
+  $lineno = $node->line_number;
+
+Returns the line number in C this C<$node> was created from
+
+=item * as_string()
+
+   print $tree->as_string();
+
+Returns a string representation of the configuration tree, in httpd.conf format.
+
+=item * as_hash()
+
+   $config = $tree->as_hash();
+
+Returns a hash representation of the configuration tree, in a format suitable
+for inclusion in EPerlE sections
+
+=item * lookup($directive, [$args])
+
+Returns node(s) matching a certain value. In list context, it will return all 
+matching nodes.
+In scalar context, it will return only the first matching node.
+
+If called with only one C<$directive> value, this will return all nodes from that 
+directive:
+
+  @Alias = $tree->lookup('Alias');
+  
+Would return all nodes for Alias directives.
+
+If called with an extra C<$args> argument, this will return only nodes where both the 
+directive
+and the args matched:
+
+  $VHost = $tree->lookup('VirtualHosts', '_default_:8000');
+
+=back
+
+=cut

Index: t/response/TestApache/conftree.pm
===
RCS file: /home/cvspublic/modperl-2.0/t/response/TestApache/conftree.pm,v
retrieving revision 1.4
diff -u -b -B -r1.4 conftree.pm
--- t/response/TestApache/conftree.pm   19 May 2002 01:12:24 -  1.4
+++ t/response/TestApache/conftree.pm   27 Jan 2003 11:54:38 -
@@ -4,6 +4,7 @@
 use warnings FATAL => 'all';
 
 use Apache::Test;
+use Apache::TestUtil;
 use Apache::TestConfig ();
 
 use Apache::Directive ();
@@ -14,7 +15,7 @@
 my $r = shift;
 
 my $cfg = Apache::Test::config();
-plan $r, tests => 7;
+plan $r, tests => 10;
 
 ok $cfg;
 
@@ -26,43 +27,39 @@
 
 ok $tree;
 
-my $port = find_config_val($tree, 'Listen');
+my $port = $tree->lookup('Listen');
 
 ok $port;
 
-ok $port == $vars->{port};
+ok t_cmp($vars->{port}, $port);
 
-my $documentroot = find_config_val($tree, 'DocumentRoot');
+my $documentroot = $tree->lookup('DocumentRoot');
+
+ok t_cmp('HASH' , ref($tree->as_hash()), 'as_hash');
 
 ok $documentroot;
 
-ok $documentroot eq qq("$vars->{documentroot}");
+ok t_cmp(qq("$vars->{documentroot}"), $documentroot);
 
-Apache::OK;
-}
+ok t_cmp(qq("$vars->{documentroot}"), $tree->lookup("DocumentRoot")

Re: Mitigating XSS in the mod_perl API

2003-01-27 Thread Thomas Eibner

On Mon, Jan 27, 2003 at 09:28:38AM +1100, Stas Bekman wrote:
> Matt Sergeant wrote:
> >At the moment it's possible to do nasty XSS things in mod_perl when you 
> >set a cookie. That's because $r->headers_out->add() (or set()) doesn't 
> >care if you include carriage returns in your header. Simple example 
> >would be:
> >
> >$r->headers_out->add('Set-Cookie' => 'mycookie=' . $r->param('myparam'));
> >
> >Just stick a couple of carriage returns in myparam and you can get the 
> >result:
> >
> >Date: Sun, 26 Jan 2003 10:39:41 GMT
> >Server: Apache/1.3.26 (Unix) AxKit/1.6_01 mod_perl/1.27
> >Client-Date: Sun, 26 Jan 2003 10:39:42 GMT
> >Client-Response-Num: 1
> >Set-Cookie: mycookie=foo
> >
> >
> >
> >
> >Connection: close
> >Transfer-Encoding: chunked
> >Content-Type: text/plain; charset=ISO-8859-1
> >
> >Thus giving you a full blown XSS bug.
> >
> >Now wouldn't it be simple to just ban \n's in headers_out()? Throw an 
> >exception or something? It might be a bit tricky because headers_out is 
> >just a plain Apache table, but there's probably a way.
> >
> >I suppose the opposition is that well, mod_perl is just an API, and we 
> >shouldn't be forcing programming styles onto the programmer, but there 
> >isn't a single legitimate use of \n in an outgoing header, so I don't 
> >think that argument has much weight.
> >
> >Thoughts?
> 
> If that causes a bug, may be this should be fixed in Apache?

So, because a programmer doesn't check the validity of the input he gets
it's a bug that should be fixed in Apache? Maybe someone should make
sure that the same thing can't happen with allowing CGI input going 
straight into a form.. oh wait. 
I don't see anyone from dev@httpd wanting to "fix" this bogus error when
it's really just doing what the programmer wants to do (when he is not
validating the input). Tables should have the ability to store both \r
and \n's IMHO.

/Thomas


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: Mitigating XSS in the mod_perl API

2003-01-27 Thread Geoffrey Young


I suppose the opposition is that well, mod_perl is just an API, and we 
shouldn't be forcing programming styles onto the programmer, but there 
isn't a single legitimate use of \n in an outgoing header, so I don't 
think that argument has much weight.

Thoughts?

If that causes a bug, may be this should be fixed in Apache?



So, because a programmer doesn't check the validity of the input he gets
it's a bug that should be fixed in Apache? Maybe someone should make
sure that the same thing can't happen with allowing CGI input going 
straight into a form.. oh wait. 
I don't see anyone from dev@httpd wanting to "fix" this bogus error when
it's really just doing what the programmer wants to do (when he is not
validating the input). Tables should have the ability to store both \r
and \n's IMHO.


I think both arguments carry some weight.  yes, programmers should be 
responsible for not validating data from clients and, in general, it's not 
our problem to save them from bad programming practices.

however, for HTML-based data we give them utilities, and the problem is well 
known.  I can't remember the last time we told users to chomp variables they 
put in the headers_out table :)

we could probably throw a warning if there are embedded newlines in the 
string sent to headers_out() and err_headers_out(), but that seems like way 
too much regex parsing.  and I can't think of a better way than that since, 
yes, tables should be allowed to hold any string.

I'd probably just vote to publicize the issue on the various lists and in 
the guide, so it becomes rote when dealing with header setting.

--Geoff


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Mitigating XSS in the mod_perl API

2003-01-27 Thread Matt Sergeant
On Mon, 27 Jan 2003, Thomas Eibner wrote:

> So, because a programmer doesn't check the validity of the input he gets
> it's a bug that should be fixed in Apache? Maybe someone should make
> sure that the same thing can't happen with allowing CGI input going
> straight into a form.. oh wait.
> I don't see anyone from dev@httpd wanting to "fix" this bogus error when
> it's really just doing what the programmer wants to do (when he is not
> validating the input).

The programmer wants to output a header. If he accidentally tries to
output something thats not a header he actually ends up outputting body.
Thats a bug.

> Tables should have the ability to store both \r
> and \n's IMHO.

I never said otherwise. The patch I sent to dev@ only affects outgoing
headers. There is no legitimate use for allowing multiple line feeds in
headers.

Though I do realise now that my patch is wrong. It needs to check for \n
in the header value followed by something that isn't space or htab. I'll
fix that and re-send to the list.

-- 

<:->get a SMart net
Spam trap - do not mail: [EMAIL PROTECTED]


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: Mitigating XSS in the mod_perl API

2003-01-27 Thread Thomas Eibner

On Mon, Jan 27, 2003 at 02:45:13PM +, Matt Sergeant wrote:
> On Mon, 27 Jan 2003, Thomas Eibner wrote:
> 
> > So, because a programmer doesn't check the validity of the input he gets
> > it's a bug that should be fixed in Apache? Maybe someone should make
> > sure that the same thing can't happen with allowing CGI input going
> > straight into a form.. oh wait.
> > I don't see anyone from dev@httpd wanting to "fix" this bogus error when
> > it's really just doing what the programmer wants to do (when he is not
> > validating the input).
> 
> The programmer wants to output a header. If he accidentally tries to
> output something thats not a header he actually ends up outputting body.
> Thats a bug.

I can see the validity of your point, but it's still a programmer error.
The same thing could happen if you did this as plain CGI and outputted
something you weren't supposed to do. We have full access to the API and
can do whatever we want (both in Perl and C), that doesn't mean we should
let our guards down. I still don't consider this a serious problem :) 

/Thomas


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: Mitigating XSS in the mod_perl API

2003-01-27 Thread Matt Sergeant
On Mon, 27 Jan 2003, Thomas Eibner wrote:

>
> On Mon, Jan 27, 2003 at 02:45:13PM +, Matt Sergeant wrote:
> > On Mon, 27 Jan 2003, Thomas Eibner wrote:
> >
> > > So, because a programmer doesn't check the validity of the input he gets
> > > it's a bug that should be fixed in Apache? Maybe someone should make
> > > sure that the same thing can't happen with allowing CGI input going
> > > straight into a form.. oh wait.
> > > I don't see anyone from dev@httpd wanting to "fix" this bogus error when
> > > it's really just doing what the programmer wants to do (when he is not
> > > validating the input).
> >
> > The programmer wants to output a header. If he accidentally tries to
> > output something thats not a header he actually ends up outputting body.
> > Thats a bug.
>
> I can see the validity of your point, but it's still a programmer error.
> The same thing could happen if you did this as plain CGI and outputted
> something you weren't supposed to do. We have full access to the API and
> can do whatever we want (both in Perl and C), that doesn't mean we should
> let our guards down. I still don't consider this a serious problem :)

I guess it depends which school of thought you come from - that the
programmer is stupid for not having checks in every inch of his code, or
that if we can, and if it has little impact, then we should do some checks
to stop the programmer hurting himself.

Anyway the main reason for doing this is there's no other way. Since
headers_out is just a plain table object, and there are no "setter" hooks
for tables, so I couldn't do it in mod_perl space. And I couldn't do it in
AxKit space, so I had to patch Apache, which has a single exit point for
all headers. I find it quite disappointing that people don't support
fixing security issues here :-/

-- 

<:->get a SMart net
Spam trap - do not mail: [EMAIL PROTECTED]


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: Mitigating XSS in the mod_perl API

2003-01-27 Thread Thomas Eibner

On Mon, Jan 27, 2003 at 03:07:01PM +, Matt Sergeant wrote:
> Anyway the main reason for doing this is there's no other way. Since
> headers_out is just a plain table object, and there are no "setter" hooks
> for tables, so I couldn't do it in mod_perl space. And I couldn't do it in
> AxKit space, so I had to patch Apache, which has a single exit point for
> all headers. I find it quite disappointing that people don't support
> fixing security issues here :-/

Please, you where the one that posted this snippet of code in the first
place:

$r->headers_out->add('Set-Cookie' => 'mycookie=' .
$r->param('myparam'));

I do support fixing security issues, and to all fairness you should have
brought this to [EMAIL PROTECTED]'s attention.


As a reminder, we respectfully request that anyone who finds a potential
vulnerability in our software reports it to [EMAIL PROTECTED]


I've given my two cents and so have you, you said you posted a patch to
dev@httpd that fixes it in the right place and I applaud that.

/Thomas


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: Mitigating XSS in the mod_perl API

2003-01-27 Thread Matthew Byng-Maddick
On Mon, Jan 27, 2003 at 08:57:38AM -0600, Thomas Eibner wrote:
> On Mon, Jan 27, 2003 at 02:45:13PM +, Matt Sergeant wrote:
> > The programmer wants to output a header. If he accidentally tries to
> > output something thats not a header he actually ends up outputting body.
> > Thats a bug.
> I can see the validity of your point, but it's still a programmer error.

Yes, but have you ever heard of the concept of defensive programming?

> The same thing could happen if you did this as plain CGI and outputted
> something you weren't supposed to do. We have full access to the API and
> can do whatever we want (both in Perl and C), that doesn't mean we should
> let our guards down. I still don't consider this a serious problem :) 

If the API is for dealing with headers, and can output something that isn't
a header, I'd say that's a brokenness in the API. I agree that not
validating your input is a reason for deserving to lose, but on the other
hand, this is equally of the Apache API in this case.

My tuppence.

MBM

-- 
Matthew Byng-Maddick <[EMAIL PROTECTED]>   http://colondot.net/

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: [mp2] Sections, Method handlers

2003-01-27 Thread Philippe M. Chiasson
On Tue, 2003-01-28 at 09:01, Stas Bekman wrote:
> Randy J. Ray wrote:
> > Any indication of when/if these features will make it to mp2? I've been 
> > trying to get my RPC::XML code (specifically the Apache::RPC::Server and 
> > Apache::RPC::Status modules) to work under Apache2 and mod_perl2 (thanks 
> > to Red Hat for pushing up my timetable on this by installing those).
> 
> I guess Philippe can comment on the  sections part, I think it should 
> be in RSN. What about method handlers? What's wrong with them?

Well,  sections are mostly done, except for :

* Apache::PerlSections missing features for backwards compatibility:
 - $Apache::Server::SaveConfig
 - $Apache::ReadConfig::DocumentRoot
 - $Apache::Server::StrictPerlSections
 - Apache::PerlSections->store(filename)

 sections were re-implemented from scratch and are supposed to be
theoritically backward-compatible. But the test suite is not quite
extensive... 

Is there anything specific you found not working like in 1.x with your
 sections ?

Gozer out.

> __
> Stas BekmanJAm_pH --> Just Another mod_perl Hacker
> http://stason.org/ mod_perl Guide ---> http://perl.apache.org
> mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
> http://modperlbook.org http://apache.org   http://ticketmaster.com
> 
> 




signature.asc
Description: This is a digitally signed message part


Re: [mp2 Patch] Apache::Directive->lookup($directive, [$args]);

2003-01-27 Thread Stas Bekman
Philippe M. Chiasson wrote:

Following a discussion about how to best access the information stored in
Apache's configuration tree, I now submit Apache::Directive->lookup()

In a nutshell, one could now do this:

 my $tree = Apache::Directive->conftree;
 my $port = $tree->lookup('Listen');

Or even cooler:

 my @vhosts = Apache::Directive->lookup('VirtualHost');

Or to search

 my $vhost = Apache::Directive->lookup('VirtualHost','localhost:');

Feedback please ;-)


+1, looks cool! see a few minor comments inlined, mostly the usual style issues.


P.S. I also kinda wanted lookup() to finish off  sections ;-p


Go gozer!


$Id: Apache-Directive-lookup.patch,v 1.7 2003/01/27 11:59:23 gozer Exp $

--- /dev/null	2002-08-31 07:31:37.0 +0800
+++ docs/api/mod_perl-2.0/Apache/Directive.pod	2003-01-25 17:23:56.0 +0800


s|mod_perl-2.0//; as of yesterday ;)


@@ -0,0 +1,134 @@
+=head1 NAME
+
+Apache::Directive -- A Perl API for manipulating Apache configuration tree
+
+=head1 SYNOPSIS
+
+  use Apache::Directive;
+
+  my $tree = Apache::Directive->conftree;
+  
+  my $documentroot = $tree->lookup('DocumentRoot');
+
+  my $vhost = $tree->lookup('VirtualHost', 'localhost:8000');
+  my $servername = $vhost->{'ServerName'};
+
+  print $tree->as_string;

use Data::Dumper; ?


+  print Dumper($tree->as_hash);
+  
+  while ($node) {

where does $node come from?


+#do something with $node
+
+if (my $kid = $node->first_child) {
+  $node = $kid;
+} 
+elsif (my $next = $node->next) {
+  $node = $next;
+}
+else {
+  if (my $parent = $node->parent) {
+$node = $parent->next;
+  }
+  else {
+$node = undef;
+  }
+}
+  }

indent 4?


+=head1 DESCRIPTION
+
+C allows its users to search and navigate the internal Apache
+configuration.
+
+Internally, this information is stored in a tree structure. Each node in the tree
+has a reference to it's parent (if it's not the root), it's first child (if any),
+and to its next sibling.


wrap 74, s/it's/its/


+=head1 API
+
+Function arguments (if any) and return values are shown in the
+function's synopsis.


We decided to use =head2 for functions, rather =over/=item/..., so one can 
link to them and they appear in the TOC.

+=over 4
+
+=item * conftree()
+
+   $tree = Apache::Directive->conftree();
+
+Returns the root of the configuration tree.
+
+=item * next()
+
+   $node = $node->next;
+
+Returns the next sibbling of C<$node>, undef otherwise
+
+=item * first_child()
+
+  $subtree = $node->first_child;
+
+Returns the first child node of C<$node>, undef otherwise
+
+=item * parent()
+
+  $parent = $node->parent;
+
+Returns the parent of C<$node>, undef if this node is the root node
+
+=item * directive()
+
+  $name = $node->directive;
+
+Returns the name of the directive in C<$node>
+
+=item * args()
+
+  $args = $node->args;
+
+Returns the arguments to this C<$node>
+
+=item * filename()
+
+  $fname = $node->filename;
+
+Returns the filename this C<$node> was created from
+
+=item * line_number()
+
+  $lineno = $node->line_number;
+
+Returns the line number in C this C<$node> was created from
+
+=item * as_string()
+
+   print $tree->as_string();
+
+Returns a string representation of the configuration tree, in httpd.conf format.
+
+=item * as_hash()
+
+   $config = $tree->as_hash();
+
+Returns a hash representation of the configuration tree, in a format suitable
+for inclusion in EPerlE sections
+
+=item * lookup($directive, [$args])
+
+Returns node(s) matching a certain value. In list context, it will return all matching nodes.
+In scalar context, it will return only the first matching node.
+
+If called with only one C<$directive> value, this will return all nodes from that directive:
+
+  @Alias = $tree->lookup('Alias');
+  
+Would return all nodes for Alias directives.
+
+If called with an extra C<$args> argument, this will return only nodes where both the directive
+and the args matched:
+
+  $VHost = $tree->lookup('VirtualHosts', '_default_:8000');
+
+=back
+
+=cut

Index: t/response/TestApache/conftree.pm
===
RCS file: /home/cvspublic/modperl-2.0/t/response/TestApache/conftree.pm,v
retrieving revision 1.4
diff -u -b -B -r1.4 conftree.pm
--- t/response/TestApache/conftree.pm	19 May 2002 01:12:24 -	1.4
+++ t/response/TestApache/conftree.pm	27 Jan 2003 11:54:38 -
@@ -4,6 +4,7 @@
 use warnings FATAL => 'all';
 
 use Apache::Test;
+use Apache::TestUtil;
 use Apache::TestConfig ();
 
 use Apache::Directive ();
@@ -14,7 +15,7 @@
 my $r = shift;
 
 my $cfg = Apache::Test::config();
-plan $r, tests => 7;
+plan $r, tests => 10;
 
 ok $cfg;
 
@@ -26,43 +27,39 @@
 
 ok $tree;
 
-my $port = find_config_val($tree, 'Listen');
+my $port = $tree->lookup('Listen');
 
 ok $port;

But you test it next, so this could be dropped, no?


-ok $port == $vars->{port};
+ok t_cmp($vars->{port}, $port);
 
-my

Re: [mp2] Sections, Method handlers

2003-01-27 Thread Stas Bekman
Philippe M. Chiasson wrote:

On Tue, 2003-01-28 at 09:01, Stas Bekman wrote:


Randy J. Ray wrote:


Any indication of when/if these features will make it to mp2? I've been 
trying to get my RPC::XML code (specifically the Apache::RPC::Server and 
Apache::RPC::Status modules) to work under Apache2 and mod_perl2 (thanks 
to Red Hat for pushing up my timetable on this by installing those).

I guess Philippe can comment on the  sections part, I think it should 
be in RSN. What about method handlers? What's wrong with them?


Well,  sections are mostly done, except for :

* Apache::PerlSections missing features for backwards compatibility:
 - $Apache::Server::SaveConfig
 - $Apache::ReadConfig::DocumentRoot
 - $Apache::Server::StrictPerlSections
 - Apache::PerlSections->store(filename)


->dump? Apache::Status has:

sub status_section_config {
my($r, $q) = @_;
require Apache::PerlSections;
["", Apache::PerlSections->dump, ""];
}

__
Stas BekmanJAm_pH --> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: [mp2] Sections, Method handlers

2003-01-27 Thread Philippe M. Chiasson
On Tue, 2003-01-28 at 10:22, Randy J. Ray wrote:
> > Is there anything specific you found not working like in 1.x with your
> >  sections ?
> 
> Actually, I got an error saying that  section support was not available 
> yet. I'm running from rpm packages, and have mod_perl 1.99_05.

 sections were introduced in 1.99_08

> Randy
> -- 
> ---
> Randy J. Ray | Men occasionally stumble over the truth, but most of them
> [EMAIL PROTECTED] | pick themselves up and hurry off as if nothing had happened.
> +1 650 930-9097  |   -- Sir Winston Churchill
> 




signature.asc
Description: This is a digitally signed message part