GithubHelp home page GithubHelp logo

bmuller / mod_auth_openid Goto Github PK

View Code? Open in Web Editor NEW
74.0 13.0 27.0 1.33 MB

mod_auth_openid is an authentication module for the Apache 2 webserver. It handles the functions of an OpenID consumer as specified in the OpenID 2.0 specification.

Home Page: http://findingscience.com/mod_auth_openid

License: Other

Shell 0.17% C++ 99.83%

mod_auth_openid's Introduction

This project is no longer actively maintained. If you'd like to take it over, email the author.

Basic Installation

First, you'll need a few prerequisites.

Next, run:

 ./configure

or

 ./configure --help

to see additional options that can be specified.

Next, run:

 make
 su root
 make install

Make sure that the file /tmp/mod_auth_openid.db is owned by the user running Apache. You can do this by (assuming www-data is the user running apache):

 su root
 touch /tmp/mod_auth_openid.db
 chown www-data /tmp/mod_auth_openid.db

Or you can specify an alternate location that the user running apache has write privieges on (see the docs for the AuthOpenIDDBLocation directive on the homepage).

Usage

In either a Directory, Location, or File directive in httpd.conf, place the following directive:

 AuthType            OpenID
 Require             valid-user

There are also additional, optional directives. See the homepage for a list and docs.

The user's identity URL will be available in the REMOTE_USER cgi environment variable after authentication.

Usage with HTTP Basic

You can configure Apache's HTTP Basic mechanism ahead of mod_auth_openid, allowing a client to present either a valid Basic auth credential first or an OpenID credential second.

 AuthType               Basic
 AuthBasicAuthoritative Off
 AuthUserFile           .htpasswd

 AuthType               OpenID
 Require                valid-user

See the project page for more information.

mod_auth_openid's People

Contributors

bmuller avatar jiepan avatar osteenbergen avatar sodabrew avatar steelpangolin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mod_auth_openid's Issues

dynamic extend lifespan

currently, if the user passes the lifespan, he has to reauthenticate, even he was active just the moment before.
suggestion: dynamically extend the lifespan of the session, if there is activity in a certain timeframe before the timeout.

REMOTE_USER not set

Hi, I can't get the REMOTE_USER after successfully authenticating with google/yahoo.

I compiled with --enable-debug.

If I DO NOT set "AuthOpenIDAXUsername email" i get this in error.log

[Sat Aug 04 23:07:05 2012] [debug] mod_auth_openid.cpp(578): [client 84.114.190.180] *** mod_auth_openid 0.7 module has been called *** [Sat Aug 04 23:07:08 2012] [debug] mod_auth_openid.cpp(578): [client 84.114.190.180] *** mod_auth_openid 0.7 module has been called ***, referer: http://www.spatialmood.com/login?modauthopenid.referrer=http%3A%2F%2Fwww.spatialmood.com%2Fads%3F [Sat Aug 04 23:07:08 2012] [debug] mod_auth_openid.cpp(361): [client 84.114.190.180] identity = https://www.google.com/accounts/o8/id, use_single_idp = false, referer: http://www.spatialmood.com/login?modauthopenid.referrer=http%3A%2F%2Fwww.spatialmood.com%2Fads%3F [Sat Aug 04 23:07:12 2012] [debug] mod_auth_openid.cpp(578): [client 84.114.190.180] *** mod_auth_openid 0.7 module has been called *** [Sat Aug 04 23:07:13 2012] [debug] mod_auth_openid.cpp(432): [client 84.114.190.180] Setting cookie after authentication of user https://www.google.com/accounts/o8/id?id=AItOawkeu45eeCoiCJ1wZnd3J_hIAu8CeBlz9zA [Sat Aug 04 23:07:14 2012] [debug] mod_auth_openid.cpp(578): [client 84.114.190.180] *** mod_auth_openid 0.7 module has been called *** [Sat Aug 04 23:07:14 2012] [debug] mod_auth_openid.cpp(342): [client 84.114.190.180] setting REMOTE_USER to https://www.google.com/accounts/o8/id?id=AItOawkeu45eeCoiCJ1wZnd3J_hIAu8CeBlz9zA

And if DO set "AuthOpenIDAXUsername email" I get this:
[Sat Aug 04 23:18:06 2012] [debug] mod_auth_openid.cpp(578): [client 84.114.190.180] *** mod_auth_openid 0.7 module has been called *** [Sat Aug 04 23:18:09 2012] [debug] mod_auth_openid.cpp(578): [client 84.114.190.180] *** mod_auth_openid 0.7 module has been called ***, referer: http://www.spatialmood.com/login?modauthopenid.referrer=http%3A%2F%2Fwww.spatialmood.com%2Fads%3F [Sat Aug 04 23:18:09 2012] [debug] mod_auth_openid.cpp(361): [client 84.114.190.180] identity = https://www.google.com/accounts/o8/id, use_single_idp = false, referer: http://www.spatialmood.com/login?modauthopenid.referrer=http%3A%2F%2Fwww.spatialmood.com%2Fads%3F [Sat Aug 04 23:18:17 2012] [debug] mod_auth_openid.cpp(578): [client 84.114.190.180] *** mod_auth_openid 0.7 module has been called *** [Sat Aug 04 23:18:19 2012] [debug] mod_auth_openid.cpp(432): [client 84.114.190.180] Setting cookie after authentication of user https://www.google.com/accounts/o8/id?id=AItOawkeu45eeCoiCJ1wZnd3J_hIAu8CeBlz9zA [Sat Aug 04 23:18:19 2012] [debug] mod_deflate.c(615): [client 84.114.190.180] Zlib: Compressed 313 to 234 : URL /ads [Sat Aug 04 23:18:19 2012] [debug] mod_auth_openid.cpp(578): [client 84.114.190.180] *** mod_auth_openid 0.7 module has been called *** [Sat Aug 04 23:18:19 2012] [debug] mod_auth_openid.cpp(342): [client 84.114.190.180] setting REMOTE_USER to [Sat Aug 04 23:18:19 2012] [debug] mod_deflate.c(615): [client 84.114.190.180] Zlib: Compressed 2884 to 1244 : URL /index.php [Sat Aug 04 23:18:20 2012] [debug] mod_deflate.c(615): [client 84.114.190.180] Zlib: Compressed 522 to 344 : URL /index.php

My apache config looks like this:

<Location /ads> AuthType OpenID require valid-user AuthOpenIDAXUsername email AuthOpenIDLoginPage /login </Location>

and i do have set these form fields:

<input id="openid_identifier" name="openid_identifier" type="text" value="http://" /> <input type="hidden" name="openid.ns.ext1" value="http://openid.net/srv/ax/1.0" /> <input type="hidden" name="openid.ext1.mode" value="fetch_request" /> <input type="hidden" name="openid.ext1.type.email" value="http://axschema.org/contact/email" /> <input type="hidden" name="openid.ext1.required" value="email" /> <input id="openid_submit" type="submit" value="Sign-In"/>

Am I missing something or is this a bug?
I am using version 0.7.

thanks.

Error in authentication: openid.modauthopenid.nonce: no such field

With mod_auth_openid 0.6 (installed with Chef) configured as follows to protect a subdirectory of my site…

<Location /admin>
    AuthType OpenID
    require user <%= @node[:apache][:allowed_openids].join(' ') %>
    AuthOpenIDDBLocation <%= @node[:apache][:mod_auth_openid][:dblocation] %>
</Location>

…every authentication attempt fails with “There has been an error while attempting to authenticate.”. This is what appears in the Apache error log:

[Thu Dec 06 05:09:12 2012] [error] [client 10.176.94.172] Error in authentication: openid.modauthopenid.nonce: no such field

What am I doing wrong?

Error in OpenID Stateless Mode

When we use 'Stateless Mode', an error was occured.
(http://openid.net/specs/openid-authentication-2_0.html#check_auth)
Can anyone succeed in Stateless Mode ?

[Tue Apr 23 15:16:15 2013] [debug] mod_auth_openid.cpp(588): [client xx.211.169.106] *** mod_auth_openid 0.7 module has been called ***
[Tue Apr 23 15:16:15 2013] [mod_auth_openid] Request GET params: &modauthopenid.nonce=dOC6vQCtRJ&openid.mode=id_res&openid.claimed_id=http%%3A%%2F%%2Fweb.icewallcloud.com%%2Fuser01&openid.identity=http%%3A%%2F%%2Fweb.icewallcloud.com%%2Fu
ser01&openid.op_endpoint=http%%3A%%2F%%2Fweb.icewallcloud.com%%2Fiwop%%2Fendpoint&openid.return_to=http%%3A%%2F%%2Fweb.icewallcloud.com%%2Fcgi-bin%%2Fprintenv%%3F%%26modauthopenid.nonce%%3DdOC6vQCtRJ&openid.response_nonce=2013-04-23T06%%3
A16%%3A14Z0&openid.assoc_handle=EQBix8IkrNv9W3fWBxsF00pDrPqZf6ZJ&openid.ns=http%%3A%%2F%%2Fspecs.openid.net%%2Fauth%%2F2.0&openid.signed=op_endpoint%%2Cclaimed_id%%2Cidentity%%2Creturn_to%%2Cresponse_nonce%%2Cassoc_handle&openid.sig=aRa%%
2BmxzbKMgT7iDxEu5tYUl%%2BRpZqTapKeZRL7MaHY2o%%3D
[Tue Apr 23 15:16:15 2013] [debug] mod_auth_openid.cpp(609): [client xx.211.169.106] *** mod_auth_openid 0.7: openid.assoc_handle is exist ***
[Tue Apr 23 15:16:15 2013] [mod_auth_openid] looking up association: server = http://web.icewallcloud.com/iwop/endpoint handle = EQBix8IkrNv9W3fWBxsF00pDrPqZf6ZJ
[Tue Apr 23 15:16:15 2013] [mod_auth_openid] could not find server "http://web.icewallcloud.com/iwop/endpoint" and handle "EQBix8IkrNv9W3fWBxsF00pDrPqZf6ZJ" in db.
throwing exception("Could not find association.")
throwing exception("openid.openid.assoc_handle: no such field")
[Tue Apr 23 15:16:15 2013] [error] [client xx.211.169.106] Error in authentication: openid.openid.assoc_handle: no such field

mod_auth_openid does not inherit configuration options

I am not sure, but I think this is a regression in 0.5 over 0.4. In the following configuration:
<Directory /var/www/nomeata.de/openid-test>
AuthOpenIDDBLocation /var/lib/apache2/mod_auth_openid/mod_auth_openid.db
AuthOpenIDUserProgram /root/openid.sh

AuthOpenIDEnabled On


AuthOpenIDEnabled On
#AuthOpenIDLoginPage background.svg
AuthOpenIDTrusted ^http://www.xxx.*

AuthOpenIDUseCookie On

the AuthOpenIDDBLocation /var/lib/apache2/mod_auth_openid/mod_auth_openid.db setting does not have any effect. If I move it into one of the sections, it works for that section.

I would expect settings from the outer scope to still apply.

REMOTE_USER not accessable to Mod_Rewrite even when using LA-U

Normally with an AUTH module, you are able to read and process the REMOTE_USER directive using Rewrite using a special map directive LA-U... simple example:

RewriteEngine On

RewriteCond %{LA-U:REMOTE_USER} (.+)

RewriteRule .* - [E=RU:%1]

RequestHeader set X_REMOTE_USER %{RU}e

This simply sets a request header with X_REMOTE_USER equal to REMOTE_USER... this works with a variety of the auth modules... for some reason when processing the above with auth_openid, I get the following in the rewrite log:

XXXX - - [19/Nov/2008:15:28:00 +0000] [dev.XXXX.com/sid#7f5401f8ce80]rid#7f54022025c8/initial init rewrite engine with requested uri /test/index.php

XXXX - - [19/Nov/2008:15:28:00 +0000] [dev.XXXX.com/sid#7f5401f8ce80]rid#7f54022025c8/initial applying pattern '.*' to uri '/test/index.php'

XXXX - - [19/Nov/2008:15:28:00 +0000] [dev.XXXX.com/sid#7f5401f8ce80]rid#7f54022025c8/initial lookahead: path=/test/index.php var=REMOTE_USER -> val=

XXXX - - [19/Nov/2008:15:28:00 +0000] [dev.XXXX.com/sid#7f5401f8ce80]rid#7f54022025c8/initial RewriteCond: input='' pattern='(.+)' => not-matched

This is despite the final page getting a REMOTE_USER environment variable set. So the end result is a null X_REMOTE_USER header with REMOTE_USER set...

The above is just a simple example really only useful when redirecting (proxying) an internal site externally handling authentication at the root site, but there are other applications esp around rewrite maps which would be useful with mod_auth_openid.

Compile fails with httpd 2.4.2

Building in Fedora rawhide with gcc 4.7 and httpd 2.4.2, I get:

libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -L/usr/lib -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -c moid_utils.cpp -fPIC -DPIC -o .libs/moid_utils.o
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -L/usr/lib -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -c mod_auth_openid.cpp -fPIC -DPIC -o .libs/mod_auth_openid.o
moid_utils.cpp: In function 'void modauthopenid::print_sqlite_table(sqlite3_, std::string)':
moid_utils.cpp:146:9: warning: variable 'rc' set but not used [-Wunused-but-set-variable]
mod_auth_openid.cpp: In function 'bool is_trusted_provider(modauthopenid_config_, std::string, request_rec_)':
mod_auth_openid.cpp:287:7: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:296:3: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp: In function 'bool is_distrusted_provider(modauthopenid_config_, std::string, request_rec_)':
mod_auth_openid.cpp:308:7: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:310:7: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:317:3: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp: In function 'bool has_valid_session(request_rec_, modauthopenid_config_)':
mod_auth_openid.cpp:342:9: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:346:9: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp: In function 'int start_authentication_session(request_rec_, modauthopenid_config_, opkele::params_t&, std::string&, std::string&)':
mod_auth_openid.cpp:361:3: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp: In function 'int set_session_cookie(request_rec_, modauthopenid_config_, opkele::params_t&, std::string, std::string)':
mod_auth_openid.cpp:432:3: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp: In function 'int validate_authentication_session(request_rec_, modauthopenid_config_, opkele::params_t&, std::string&)':
mod_auth_openid.cpp:485:9: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:489:9: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:499:11: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:510:11: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:513:11: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:522:11: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:525:11: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:537:9: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:541:9: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:558:5: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp:562:5: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp: In function 'int mod_authopenid_method_handler(request_rec_)':
mod_auth_openid.cpp:578:3: error: 'aplog_module_index' was not declared in this scope
mod_auth_openid.cpp: In function 'int mod_authopenid_check_user_access(request_rec_)':
mod_auth_openid.cpp:619:53: error: 'ap_requires' was not declared in this scope
mod_auth_openid.cpp:648:3: error: 'aplog_module_index' was not declared in this scope
make[2]: *_* [mod_auth_openid.lo] Error 1

looking in /usr/include/httpd/http_log.h I see:

ifdef __cplusplus
/**

  • C++ modules must invoke ::APLOG_USE_MODULE or ::AP_DECLARE_MODULE in
  • every file which uses ap_log_* before the first use of ::APLOG_MARK
  • or ::APLOG_MODULE_INDEX.
  • (C modules should do that as well, to enable module-specific log
  • levels. C modules need not obey the ordering, though).
    /
    #else /
    __cplusplus /
    /
    *
  • Constant to store module_index for the current file.
  • Objects with static storage duration are set to NULL if not
  • initialized explicitly. This means that if aplog_module_index
  • is not initalized using the ::APLOG_USE_MODULE or the
  • ::AP_DECLARE_MODULE macro, we can safely fall back to
  • use ::APLOG_NO_MODULE. This variable will usually be optimized away.
    /
    static int * const aplog_module_index;
    #endif /
    __cplusplus */

I don't know if this is a recent change or what... happy to provide more info or test patches.

Module fails behind Proxy

Please have the module look at the X-Forward-For headers to determine the correct hostname to use if behind a Proxy.

Our previous discussion.

bamuller: yeah
I know it wouldn't be optimal, but could you just run apache on 443 instead of 9443?
me: i can't because i'm doing SSL termination on an Elastic Load Balancer in Amazon's infrastructure..
I actually go from ELB -> Apache -> HaProxy -> Tomcat
bamuller: you could run regular http on 443
me: and it would still have the same problem since AuthOpenIDTrustRoot is defined per hosts.. right?
actually i see what you're saying.. not a fun change on my part but I could give it a try.
bamuller: other than that I could add a AuthOpenIDTrustRootPort option fairly easily
or look at the x_forwarded_for headers
me: either of those options would work for me..
would you like to see what my headers look like?
bamuller: the right way is to look at the x-forwarded-for header
me: yep.. that is what i use in my app
bamuller: yeah
me: ----Start header dump--
host : carter-test.integritylogin.com
accept : text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
accept-charset : ISO-8859-1,utf-8;q=0.7,*;q=0.7
accept-encoding : gzip,deflate
accept-language : en-us,en;q=0.5
cache-control : max-age=0
cookie : JSESSIONID=EA7EDED3BA2E8FDB2B12BD3A12237C5C; __utma=237901074.946345200.1293738685.1294684106.1294771116.11; __utmz=237901074.1293738685.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=237901074
user-agent : Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13
x-forwarded-for : 24.173.16.65, 10.192.141.21
x-forwarded-port : 443
x-forwarded-proto : https
req_id : TSyuQgrRv2QAAFTnBAIAAABH
via : 1.1 domU-12-31-39-07-BC-96.compute-1.internal:9443
x-forwarded-host : carter-test.integritylogin.com
x-forwarded-server : domU-12-31-39-07-BC-96.compute-1.internal
connection : Keep-Alive
----End header dump--
bamuller: yup
can you file a bug and include that header dump?
me: Sure thing! Thanks! Hope this will make the product better
bamuller: it should be titled something like "module fails behind proxy"
yup - thanks
me: yep.

auth_openid: Couldn't resolve host name

I am running apache2.4 under chrooted environment and getting the following error with auth_openid module. I do have libcurl, libpcre, libopkele, etc available in chroot jail. The Identity URL I am trying to use is http://aselvan.clavid.com

[Sun Feb 02 09:43:27.488881 2014] [auth_openid:error] [pid 17958] [client 192.168.1.1:59297] Error while fetching idP location: failed to perform curly request [Couldn't resolve host name], referer: http://selvans.net/openid

Any idea why it could not resolve the idP ?

Old Debian Repos

Depian repositories still contain old versions of mod_auth_openid. Specifically, while setting up an Ubuntu 12.04 amd64 server, apt-get pulled in version 0.5 and failed to load the module with a2enmod commands. Additionally some of the nice features such as AuthOpenIDAXRequire are not available in that version.

For the benefit of those having the same issue, you can install 0.7v from this github repo:

sudo apt-get install automake autotools-dev libtool libtidy-dev libcurl4-openssl-dev libopkele-dev

Pull Repo:

git clone https://github.com/bmuller/mod_auth_openid.git
cd mod_auth_openid

And build:

./autogen.sh
./configure
make
make install

Activate module:

sudo a2enmod authopenid

Use Location directive in Apache configuration, create database for server session (see http://findingscience.com/mod_auth_openid/‎ for setup instructions), and enjoy!

Error:

Hi, guys. I installed mod_auth_openid, but there is an error like below.

「There was either no identity provider found for the identity given or there was trouble connecting to it.」

I tried many solutions but the error is still there. I also tried #17. but it is no use.

I use centos5, mod_auth_openid_0.7.
Any ideas? Thank you.

Segfault when writing to AuthOpenIDDBLocation

If the user running apache httpd does not have write access to the directory where the sqlite3 database file lives, attempts to log in using an OpenID will cause a segfault. This happens even if the user has write access to the db file itself.

Changing permission on the directory allowing write access to the directory for the user resolves the issue.

make fails

small background information: I am not a programmer but a technical consultant on a project to implement a consumer application integration in Autonomy Interwoven CMS for a renowned international football club in Europe. I am considering options and I am looking at Apache in particular as I believe it might be the least overhead on the site. The web servers will be on windows, which is a pain. For now I was just trying to configure it on RHE5, but I got a make error. I hope you could help me. Not sure if this is a bug or where I should log this request. I am sorry if it is the wrong forum.

environment: redhat enterprise 5 (vm on win7)
installers used: libopkele-2.0.4, mod_auth_openid-0.6, tidy4aug00, libsqlite 3.3, http 2.2.3
modules added along the way
apr-1.2.7-11.el5_6.5.i386.rpm, apr-devel-1.2.7-11.el5_6.5.i386.rpm, pr-util-devel-1.2.7-11.el5.i386.rpm, httpd-devel-2.2.3-43.el5.i386.rpm
site used: http://ftp.riken.go.jp/pub/Linux/cern/slc52test/updates/i386/RPMS/

installed apr-1.2.7-11.el5_6.5.i386.rpm from http://zid-luxinst.uibk.ac.at/linux/rpm2html/search.php?query=apr

then installed apr-devel-1.2.7-11.el5_6.5.i386.rpm from http://rpm.pbone.net/index.php3/stat/4/idpl/16466459/dir/scientific_linux_5/com/apr-devel-1.2.7-11.el5_6.5.i386.rpm.html

then installed apr-util-devel-1.2.7-11.el5.i386.rpm from http://ftp.riken.go.jp/pub/Linux/cern/slc52test/updates/i386/RPMS/apr-util-devel-1.2.7-11.el5.i386.rpm

installed httpd-devel-2.2.3-43.el5.i386.rpm

Set:

OPKELE_CFLAGS=-I/usr/include/opkele
OPKELE_LIBS=-I/usr/lib

then require pcre libraries (perl compatible regular expressions) pcre-6.6-6.el5.i386.rpm,
then installed pcre-devel-6.6-6.el5.i386.rpm both
from http://ftp.riken.go.jp/pub/Linux/cern/slc52test/updates/i386/RPMS/

then installed the mod_auth_openid-0.6 in /usr/installers/apache/mod_auth_openid-0.6:
./configure

DONE WORKS!
./make

fails with this error stack:

[root@RH55WS71 mod_auth_openid-0.6]# make
make all-am
make[1]: Entering directory /usr/installers/apache/mod_auth_openid-0.6' /bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT mod_auth_openid.lo -MD -MP -MF .deps/mod_auth_openid.Tpo -c -o mod_auth_openid.lo mod_auth_openid.cpp libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT mod_auth_openid.lo -MD -MP -MF .deps/mod_auth_openid.Tpo -c mod_auth_openid.cpp -fPIC -DPIC -o .libs/mod_auth_openid.o libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT mod_auth_openid.lo -MD -MP -MF .deps/mod_auth_openid.Tpo -c mod_auth_openid.cpp -o mod_auth_openid.o >/dev/null 2>&1 mv -f .deps/mod_auth_openid.Tpo .deps/mod_auth_openid.Plo /bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT MoidConsumer.lo -MD -MP -MF .deps/MoidConsumer.Tpo -c -o MoidConsumer.lo MoidConsumer.cpp libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT MoidConsumer.lo -MD -MP -MF .deps/MoidConsumer.Tpo -c MoidConsumer.cpp -fPIC -DPIC -o .libs/MoidConsumer.o libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT MoidConsumer.lo -MD -MP -MF .deps/MoidConsumer.Tpo -c MoidConsumer.cpp -o MoidConsumer.o >/dev/null 2>&1 mv -f .deps/MoidConsumer.Tpo .deps/MoidConsumer.Plo /bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT moid_utils.lo -MD -MP -MF .deps/moid_utils.Tpo -c -o moid_utils.lo moid_utils.cpp libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT moid_utils.lo -MD -MP -MF .deps/moid_utils.Tpo -c moid_utils.cpp -fPIC -DPIC -o .libs/moid_utils.o libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT moid_utils.lo -MD -MP -MF .deps/moid_utils.Tpo -c moid_utils.cpp -o moid_utils.o >/dev/null 2>&1 mv -f .deps/moid_utils.Tpo .deps/moid_utils.Plo /bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT http_helpers.lo -MD -MP -MF .deps/http_helpers.Tpo -c -o http_helpers.lo http_helpers.cpp libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT http_helpers.lo -MD -MP -MF .deps/http_helpers.Tpo -c http_helpers.cpp -fPIC -DPIC -o .libs/http_helpers.o libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT http_helpers.lo -MD -MP -MF .deps/http_helpers.Tpo -c http_helpers.cpp -o http_helpers.o >/dev/null 2>&1 mv -f .deps/http_helpers.Tpo .deps/http_helpers.Plo /bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT SessionManager.lo -MD -MP -MF .deps/SessionManager.Tpo -c -o SessionManager.lo SessionManager.cpp libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT SessionManager.lo -MD -MP -MF .deps/SessionManager.Tpo -c SessionManager.cpp -fPIC -DPIC -o .libs/SessionManager.o libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT SessionManager.lo -MD -MP -MF .deps/SessionManager.Tpo -c SessionManager.cpp -o SessionManager.o >/dev/null 2>&1 mv -f .deps/SessionManager.Tpo .deps/SessionManager.Plo /bin/sh ./libtool --tag=CXX --mode=link g++ -g -O2 -I/usr/local/lib -I/usr/include -lsqlite3 -lpcre -L/usr/kerberos/lib -lcurl -ldl -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lidn -lssl -lcrypto -lz -lapr-1 -lpthread -ldl -L/usr/lib -o libmodauthopenid.la mod_auth_openid.lo MoidConsumer.lo moid_utils.lo http_helpers.lo SessionManager.lo -lpcre libtool: link: ar cru .libs/libmodauthopenid.a .libs/mod_auth_openid.o .libs/MoidConsumer.o .libs/moid_utils.o .libs/http_helpers.o .libs/SessionManager.o libtool: link: ranlib .libs/libmodauthopenid.a libtool: link: ( cd ".libs" && rm -f "libmodauthopenid.la" && ln -s "../libmodauthopenid.la" "libmodauthopenid.la" ) g++ -DHAVE_CONFIG_H -I. -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/opkele -L/usr/lib -g -O2 -MT db_info.o -MD -MP -MF .deps/db_info.Tpo -c -o db_info.o db_info.cpp mv -f .deps/db_info.Tpo .deps/db_info.Po /bin/sh ./libtool --tag=CXX --mode=link g++ -g -O2 -lmodauthopenid -L/usr/lib -o db_info db_info.o -lpcre libtool: link: g++ -g -O2 -o db_info db_info.o /usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a -lsqlite3 -L/usr/kerberos/lib -lcurl -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lidn -lssl -lcrypto -lz /usr/lib/libapr-1.so -lpthread -ldl -L/usr/lib -lpcre db_info.o: In function~basic_RP':
/usr/local/include/opkele/basic_rp.h:22: undefined reference to vtable for opkele::basic_RP' /usr/local/include/opkele/basic_rp.h:22: undefined reference tovtable for opkele::basic_RP'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function modauthopenid::MoidConsumer::get_normalized_id() const': /usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:299: undefined reference toopkele::exception::exception(std::basic_string<char, std::char_traits, std::allocator > const&)'
/usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:299: undefined reference to opkele::exception::~exception()' /usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:299: undefined reference totypeinfo for opkele::exception'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function modauthopenid::MoidConsumer::get_endpoint() const': /usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:247: undefined reference toopkele::exception::exception(std::basic_string<char, std::char_traits, std::allocator > const&)'
/usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:247: undefined reference to opkele::exception::~exception()' /usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:247: undefined reference totypeinfo for opkele::exception'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function id_res_failed': /usr/local/include/opkele/exception.h:156: undefined reference toopkele::exception::exception(std::basic_string<char, std::char_traits, std::allocator > const&)'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function failed_lookup': /usr/local/include/opkele/exception.h:103: undefined reference toopkele::exception::exception(std::basic_string<char, std::char_traits, std::allocator > const&)'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function modauthopenid::MoidConsumer::retrieve_assoc(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': /usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:100: undefined reference toopkele::util::decode_base64(std::basic_string<char, std::char_traits, std::allocator > const&, std::vector<unsigned char, std::allocator >&)'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function ~basic_RP': /usr/local/include/opkele/basic_rp.h:22: undefined reference tovtable for opkele::basic_RP'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function failed_lookup': /usr/local/include/opkele/exception.h:103: undefined reference toopkele::exception::exception(std::basic_string<char, std::char_traits, std::allocator > const&)'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function modauthopenid::MoidConsumer::find_assoc(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': /usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:136: undefined reference toopkele::util::decode_base64(std::basic_string<char, std::char_traits, std::allocator > const&, std::vector<unsigned char, std::allocator >&)'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function modauthopenid::MoidConsumer::store_assoc(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, opkele::secret_t const&, int)': /usr/installers/apache/mod_auth_openid-0.6/MoidConsumer.cpp:72: undefined reference toopkele::util::encode_base64(void const_, unsigned int)'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function ~basic_RP': /usr/local/include/opkele/basic_rp.h:22: undefined reference tovtable for opkele::basic_RP'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function ~failed_lookup': /usr/local/include/opkele/exception.h:100: undefined reference toopkele::exception::~exception()'
/usr/local/include/opkele/exception.h:100: undefined reference to opkele::exception::~exception()' /usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function~id_res_failed':
/usr/local/include/opkele/exception.h:153: undefined reference to opkele::exception::~exception()' /usr/local/include/opkele/exception.h:153: undefined reference toopkele::exception::~exception()'
/usr/local/include/opkele/exception.h:153: undefined reference to opkele::exception::~exception()' /usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):/usr/local/include/opkele/exception.h:153: more undefined references toopkele::exception::~exception()' follow
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o): In function ~basic_RP': /usr/local/include/opkele/basic_rp.h:22: undefined reference tovtable for opkele::basic_RP'
/usr/local/include/opkele/basic_rp.h:22: undefined reference to vtable for opkele::basic_RP' /usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTVN13modauthopenid12MoidConsumerE[vtable for modauthopenid::MoidConsumer]+0x30): undefined reference toopkele::prequeue_RP::initiate(std::basic_string<char, std::char_traits, std::allocator > const&)'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTVN13modauthopenid12MoidConsumerE[vtable for modauthopenid::MoidConsumer]+0x34): undefined reference to opkele::basic_RP::associate(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTVN13modauthopenid12MoidConsumerE[vtable for modauthopenid::MoidConsumer]+0x38): undefined reference toopkele::prequeue_RP::verify_OP(std::basic_string<char, std::char_traits, std::allocator > const&, std::basic_string<char, std::char_traits, std::allocator > const&, std::basic_string<char, std::char_traits, std::allocator > const&) const'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTVN13modauthopenid12MoidConsumerE[vtable for modauthopenid::MoidConsumer]+0x50): undefined reference to opkele::prequeue_RP::discover(opkele::util::output_iterator_proxy<opkele::openid_endpoint_t>, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const' /usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTIN13modauthopenid12MoidConsumerE[typeinfo for modauthopenid::MoidConsumer]+0x8): undefined reference totypeinfo for opkele::prequeue_RP'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTIN6opkele13id_res_failedE[typeinfo for opkele::id_res_failed]+0x8): undefined reference to typeinfo for opkele::exception' /usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTVN6opkele16id_res_bad_nonceE[vtable for opkele::id_res_bad_nonce]+0x10): undefined reference toopkele::exception::what() const'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTVN6opkele13id_res_failedE[vtable for opkele::id_res_failed]+0x10): undefined reference to opkele::exception::what() const' /usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTIN6opkele13failed_lookupE[typeinfo for opkele::failed_lookup]+0x8): undefined reference totypeinfo for opkele::exception'
/usr/installers/apache/mod_auth_openid-0.6/.libs/libmodauthopenid.a(MoidConsumer.o):(.data.rel.ro._ZTVN6opkele13failed_lookupE[vtable for opkele::failed_lookup]+0x10): undefined reference to opkele::exception::what() const' collect2: ld returned 1 exit status make[1]: *_\* [db_info] Error 1 make[1]: Leaving directory /usr/installers/apache/mod_auth_openid-0.6'
make: *** [all] Error 2

./make install

Could you advise on this issue please?

AUTH_TYPE not set

mod_auth_openid doesn't seem to be setting the AUTH_TYPE environment variable (which things like basic and digest do).

There is a check in mod_auth_openid.cpp that checks auth_type..

// if we're not enabled for this location/dir, decline doing anything
const char *current_auth = ap_auth_type(r);
if (!current_auth || strcasecmp(current_auth, "openid"))
return DECLINED;

but as far as I can tell... auth_type never gets set. I might be totally wrong, but I'd think you'd want to set auth_type to "openid", and change the test to something like...

if (!current_auth || ( strcasecmp(current_auth, "openid") != 0 ))
return DECLINED;

Several responses in the same page

Hi,

I'm using mod_auth_openid 0.6 (this is the newest version on Gentoo's portage).

I have an openid provider over HTTP (without SSL)

I have restricted the access to a HTTPS website with mod_auth_openid.

When I access my restricted website, Chrome shows a strange page. It consists in a 200 OK response followed by a 302 one (with a Location pointing to what seems to be the call to the provider).

Then it hangs. It seems not to happen with Firefox. Is it a Chrome related problem, or is Firefox less strict and can understand the bizarre response coming from Apache?

Thanks for your help!

mod_auth_openid fails when an associated server expires its nonces

A few times per week, and sometimes a few times per day, mod_auth_openid fails with the "unspecified" error code and this message in the debug output:

Error in authentication: openid.modauthopenid.nonce: no such field

This seems to occur when mod_auth_openid had established an assocition with the openid provder in the past, but the provider has since expired its old associations & nonces. Considering that such expiration is normal, it seems to me that mod_auth_openid should automatically establish a new association/nonce/whatever in this case, rather than triggering a mysterious authentication failure.

mod_auth_openid sends a 200 OK

Similar to #39, mod_auth_openid seems to be prepending an HTML document to the response sent to Chrome browsers when the request is received as the second or any subsequent request on an HTTP Keep-Alive connection.

To reproduce this, I simply log into my site protected by mod_auth_openid, then refresh the page quickly a couple of times. The first refresh opens a new HTTP connection to load the page, which displays normally in the browser, then the second refresh is made via the same connection. Here’s what Apache sends the browser in response:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>200 OK</title>
</head><body>
<h1>OK</h1>
<p>This server could not verify that you
are authorized to access the document
requested.  Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
<hr>
<address>Apache Server at mysite.com Port 443</address>
</body></html>
HTTP/1.1 200 OK
Date: Mon, 25 Feb 2013 05:02:41 GMT
Server: Apache
X-Powered-By: PHP/5.3.10-1ubuntu3.5
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html

1feb
<!DOCTYPE html>
<html>
<head>
… the rest of the requested page …

Chrome does its best to display this as a web page, with the “OK” message at the top, followed by the HTTP headers of my actual page, followed by its contents.

This issue is 100% reproducible for me with Chrome 25 running on OS X 10.8.2. This problem does not occur with other browsers.

the auth_openid_cookie should be ssl protected

the authentication cookie set for openid is not set for ssl_only nor there is a mechanism to set it up. Since this cookie is expected to grant privileges to the end user its default behavior should be to be ssl protected by default.

In lieu with being an authorization cookie, it should also be HttpOnly and not available to javascript (to prevent a class of XSS attacks).

Here is the diff of the one liner to do this:

diff -crB mod_auth_openid-0.6/http_helpers.cpp mod_auth_openid-0.6-new/http_helpers.cpp
*** mod_auth_openid-0.6/http_helpers.cpp 2010-11-27 18:41:45.000000000 +0000
--- mod_auth_openid-0.6-new/http_helpers.cpp 2011-12-19 21:25:39.000000000 +0000


*** 263,268 ****
--- 263,269 ----
strftime(expires, sizeof(expires), "%a, %d-%b-%Y %H:%M:%S GMT", tmp);
cookie_value = name + "=" + session_id + "; expires=" + string(expires) + "; path=" + path;
}

  • cookie_value.append("; secure; HttpOnly");
    

    };

    // Get the post query string from a HTTP POST

Not respecting apache proxy settings

Hello! It seems that the open id module does not respect apache's proxy settings when making calls to the OAuth provider. This means it is impossible to use it on an apache that does not have direct connection to the internet.

Setting ProxyRemote * <my proxy> and inspecting the network activity shows that the open id module tries to talk to the OpenID provider directly, rather than going through the proxy as you would expect.

It doesn't seem like there is any way to configure a proxy setting in the module directly, so it seems like this is a bug, unless there is some other way of setting the proxy for the OpenID calls?

OpenID after checking for HTTP Basic?

I'd like to be able to first check for HTTP Basic auth with an htpasswd file, and if that fails, go to OpenID. This would allow me to write some command line scripts to interact with my site while retaining OpenID for browser use.

I can't seem to configure these together, though. HTTP Basic wants to issue the WWW-Authenticate header for an unauthorized user and close the connection before mod_auth_openid can get a look at it. Help appreciated from those watching the issues list here :)

Specifying CAPATH for CURL

We specified a custom OpenID server over HTTPS. CURL uses a default certificate bundle to check certs against, but specifying CAPATH allows you to specify a path to check for additional certs. This was necessary for us to authenticate. If the certificate is not found, the error "There was either no identity provider found for the identity given or there was trouble connecting to it." comes up. I customized CAPATH specification as an Apache Directive called AuthOpenIDCurlCapath to read in the path where we want to check server certificates in addition to the default curl cert bundle and it worked great for our server.

I specified char *capath; in curl.cc and modified misc_sets() in curl.cc to add the following options:
|| (r=easy_setopt(CURLOPT_SSL_VERIFYHOST,2))
|| (r=easy_setopt(CURLOPT_SSL_VERIFYPEER,1))
|| (r=easy_setopt(CURLOPT_CAPATH,capath))

In mod_auth_openid.cpp:

  1. I specified extern char *capath;

  2. char *curl_capath; was added as an attribute to modauthopenid_config struct

  3. newcfg->curl_capath = "/default"; was added to create_modauthopenid_config function

  4. added function: static const char *set_modauthopenid_curl_capath(cmd_parms *parms, void *mconfig, const char *arg) {
    modauthopenid_config *s_cfg = (modauthopenid_config *) mconfig;
    s_cfg->curl_capath = (char *) arg;
    return NULL;
    }

  5. added line: AP_INIT_TAKE1("AuthOpenIDCurlCapath", (CMD_HAND_TYPE) set_modauthopenid_curl_capath, NULL, OR_AUTHCFG,
    "AuthOpenIDCurlCapath ") to static const command_rec mod_authopenid_cmds[]

  6. added line capath = s_cfg->curl_capath; to function mod_authopenid_method_handler in beginning

Failures when combined with mod_deflate

We have a simple clean install of Apache containing some simple HTML files.

When using mod_authn_openid with mod_deflate (enabled by default on Ubuntu, at least) we often get failures. Instead of returning the HTML, it returns a binary download, which appears to contain some HTTP headers and some binary data.

Tested using the current Git master (0fea1d5).

Mailing List dead?

Hi,

Sorry to leave this here as an issue - it's more of a question:
Is the mailing list still read by anyone?
I posted a question to it, but that's the only activity it's had this month..

Cheers,
Frode

query_string length issue

Via Maxim Bashevoy:

We found a small problem in the module and managed to fix it, just wanted you to know and hopefully have the code updated in the next version: "query_string" in get_post_data() method in http_helpers.cpp was not assigned correctly (it was ignoring "len" argument) resulting in all sorts of problems such as: "could not find handle for server .. in db" or lots of random garbage at the end of the hostname, all resulting in "no idp found" error.

Here is the diff:

diff --git a/http_helpers.cpp b/http_helpers.cpp
index a78f740..6c23355 100644
--- a/http_helpers.cpp
+++ b/http_helpers.cpp
@@ -285,7 +285,7 @@ namespace modauthopenid {
     apr_status_t ret;
     int seen_eos, child_stopped_reading;
     seen_eos = child_stopped_reading = 0; 
-    char *query_string = NULL;
+    string query_string = string("");
 
     do { 
       ret = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, APR_BLOCK_READ, 8192); 
@@ -309,16 +309,14 @@ namespace modauthopenid {
        if(ret != APR_SUCCESS) {
          child_stopped_reading = 1;
        } else {
-         if (query_string == NULL) 
-           query_string = apr_pstrdup(r->pool, data);
-         else 
-           query_string = apr_pstrcat(r->pool, query_string, data, NULL);
+           string c_data = string(data, len);
+           query_string = query_string + c_data;
        }
       } 
       apr_brigade_cleanup(bb); 
     } while (!seen_eos); 
 
-    qs = (query_string == NULL) ? "" : string(query_string);
+    qs = query_string;
     return true; 
   };

Apache dumps core (signal 11) with mod_auth_openid

Sometimes apache seems to die on signal 11 when using mod_auth_openid. The crash occurs when login form is submitted.
I managed to get a core dump of it, gdb shows following stack trace:
#0 0x29127e3d in __cxa_allocate_exception () from /usr/lib/libstdc++.so.6

New Thread 28501140 (LWP 100085) bt
#0 0x29127e3d in __cxa_allocate_exception () from /usr/lib/libstdc++.so.6
#1 0x287a6338 in modauthopenid::MoidConsumer::find_assoc ()

from /usr/local/libexec/apache22/mod_auth_openid.so
#2 0x287f984e in opkele::basic_RP::checkid_ ()

from /usr/local/lib/libopkele.so.3
#3 0x287a0fa2 in start_authentication_session ()

from /usr/local/libexec/apache22/mod_auth_openid.so
#4 0x287a2c09 in mod_authopenid_method_handler ()

from /usr/local/libexec/apache22/mod_auth_openid.so
#5 0x080723b9 in ap_run_check_user_id (r=0x2a441058) at request.c:70
#6 0x08074479 in ap_process_request_internal (r=0x2a441058) at request.c:214
#7 0x080851e0 in ap_process_request (r=0x2a441058) at http_request.c:280
#8 0x0808230b in ap_process_http_connection (c=0x2a42f1f0) at http_core.c:190
#9 0x0807e0f9 in ap_run_process_connection (c=0x2a42f1f0) at connection.c:43
#10 0x0808a221 in child_main (child_num_arg=Variable "child_num_arg" is not available.

) at prefork.c:667
#11 0x0808a507 in make_child (s=0x28510f10, slot=2) at prefork.c:768
#12 0x0808a5c4 in startup_children (number_to_start=3) at prefork.c:786
#13 0x0808b1a5 in ap_mpm_run (_pconf=0x2850f018, plog=0x2853d018, s=0x28510f10)

at prefork.c:1007

#14 0x08064276 in main (argc=676384792, argv=0x2a42d018) at main.c:739

This is apache 2.2.21 and mod_auth_openid 0.6. libopkele is 2.0.2.
OS is FreeBSD 8.2.

--
Ari S.

mod_auth_openid occasionally fails with error=invalid_nonce

mod_auth_openid sometimes fails on a perfectly legitimate authentication, passing to my custom login page the error code "invalid_nonce". I have enabled debugging, but the logs don't say anything about the error.

I'm using a mod_auth_openid snapshot from 2010-11-08. The same problem occurred in version 0.5.

(Could this be related to issue #4?)

Redirect to remove openid.ax.mode=fetch_response GET arguments

It would be a lot prettier if mod_auth_openid redirected to remove the openid.ax.mode=fetch_response GET arguments. They make the bookmarks, etc. behave weird immediately after logging in.

Example:

https://example.com/?openid.ax.mode=fetch_response&openid.ax.type.email=http%3A%2F%2Fopenid.net%2Fschema%2Fcontact%2Finternet%2Femail&openid.ax.value.email=user%40example.com&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&application_argument=foobar

...should be redirected to...

https://example.com/?application_argument=foobar

Ciao!

modauthopenid.error stays in browser history, produces phantom errors

I have a custom login page that logs and raises alarms upon detecting an error. Unfortunately, mod_auth_openid communicates errors using query string parameters, which are saved in the browser's history. That means that if a user has ever encountered an error, from that point onward, his browser's autocomplete feature dutifully assists him in reproducing that error every time he starts typing in his address bar and chooses the familiar URL from the autocomplete list. In other words, phantom errors, which annoy the user, make the site appear broken, and trigger misleading alarms for the site operator.

Perhaps a better approach for mod_auth_openid would be to use an apache internal redirect / sub-request (instead of a browser redirect) when displaying a custom login page, and communicate errors to that page using apache/cgi environment variables (instead of query string parameters).

build failed

Building mod_auth_openid under CentOS 5 (32/64-Bit) failed with the following error message:

mod_auth_openid.cpp: In function 'int start_authentication_session(request_rec_, modauthopenid_config_, opkele::params_t&, std::string&, std::string&)':
mod_auth_openid.cpp:375: error: expected primary-expression before 'const'
mod_auth_openid.cpp:375: error: 'APR_ARRAY_IDX' was not declared in this scope
mod_auth_openid.cpp: In function 'int validate_authentication_session(request_rec_, modauthopenid_config_, opkele::params_t&, std::string&)':
mod_auth_openid.cpp:494: error: expected primary-expression before 'const'
mod_auth_openid.cpp:494: error: 'APR_ARRAY_IDX' was not declared in this scope

Building under CentOS 6 is not affected.

REMOTE_USER not available to proxied applications

I'm using mod_proxy and mod_auth_openid together, with a rewrite rule that should populate the X-Forwarded-User header from the contents of REMOTE_USER:

<Proxy *>
    AuthType OpenID
    require valid-user

    RewriteCond %{LA-U:REMOTE_USER} (.+)
    RewriteRule . - [E=RU:%1]
    RequestHeader add X-Forwarded-User %{RU}e
</Proxy>

The trouble is that the header set in the proxied requests always looks like this:

X-Forwarded-User: (null)

I can see that the OpenID session cookie is present in the request, though.

According to the mod-proxy-add-user github project, mod_auth_openid may not be setting REMOTE_USER at the right time, which is why it's not available.

Support "require"-like syntax for authorization

Currently, all authorization must be performed by an external AuthOpenIDUserProgram. While supporting an external authorization program is useful for complex scenarios that involve integration with an external account-database, it is overkill for the common/simple scenario of a small whitelist of valid-users. For this use-case, the "require" syntax used by the http-basic authtype sensible and familiar.

Please consider adding support for a simplified authorization syntax modelled after the "require" directive.

If using SSL, then the login-bg.gif URL should be https

When using SSL on a page and you get the 'Identity URL:' request, the login-bg.gif is gotten from an HTTP (not HTTPS) URL. This causes a warning in most browsers.

It should use the url https://openid.net/images/login-bg.gif instead of http://openid.net/images/login-bg.gif if SSL is detected.

At the least, it could use the URL //openid.net/images/login-bg.gif which will automatically pick up the protocol when hitting openid.net.

Can anybody help me? I received an HTTP/1.1 403 Forbidden error on my sites.

I have a web server which authorized users through google openid api. Several weeks ago, it continuously receive 403 error when user try to log in through openid. I can not find out why. Here are some information:

  1. Affected username(s):
    *[email protected]

  2. Programming language:
    Apache httpd configuration

  3. Name and version of any libraries used:
    Apache 2.2.3, mod_auth_openid 0.7

  4. Frequency of issue:
    every access at present

  5. Exact error code received:
    HTTP/1.1 403 Forbidden

  6. Exact date, time, and timezone at which the above error was last received:
    2013-10-18 16:25:35 CST (GMT +08:00)

  7. Date/time at which the issue was first observed:
    2013-10-04 05:37:16 CST

  8. Relevant code snippet that results in the error:

            AuthType        OpenID
            require         valid-user
            AuthOpenIDTrusted       ^https://www.google.com/accounts/o8/ud
            AuthOpenIDAXRequire     email http://schema.openid.net/contact/email @allmydomain\.(com|net)$
            AuthOpenIDSingleIdP     https://www.google.com/accounts/o8/id
            AuthOpenIDAXUsername    email
    
  9. HTTP Request and Response headers (or full HTTP logs):

httpd access_log:
10.1.2.3 - - [18/Oct/2013:17:02:27 +0800] "GET /cacti HTTP/1.1" 401 1014 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36"

httpd error_log:
[Fri Oct 18 17:02:28 2013] [error] [client 10.1.2.3] Error while fetching idP location: No more endpoints queued

  1. Full CURL test log:

curl -ivvv https://www.google.com/accounts/o8/ud

  • About to connect() to www.google.com port 443
  • Trying 74.125.128.147... connected
  • Connected to www.google.com (74.125.128.147) port 443
  • successfully set certificate verify locations:
  • CAfile: /etc/pki/tls/certs/ca-bundle.crt
    CApath: none
  • SSLv2, Client hello (1):
    SSLv3, TLS handshake, Server hello (2):
    SSLv3, TLS handshake, CERT (11):
    SSLv3, TLS handshake, Server finished (14):
    SSLv3, TLS handshake, Client key exchange (16):
    SSLv3, TLS change cipher, Client hello (1):
    SSLv3, TLS handshake, Finished (20):
    SSLv3, TLS change cipher, Client hello (1):
    SSLv3, TLS handshake, Finished (20):
    SSL connection using RC4-SHA
  • Server certificate:
  • subject: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
  • start date: 2013-10-09 10:59:13 GMT
  • expire date: 2014-10-09 10:59:13 GMT
  • subjectAltName: www.google.com matched
  • issuer: /C=US/O=Google Inc/CN=Google Internet Authority G2
  • SSL certificate verify ok.

    GET /accounts/o8/ud HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Host: www.google.com
    Accept: /

    < HTTP/1.1 403 Forbidden
    HTTP/1.1 403 Forbidden
    < Content-Type: text/html; charset=UTF-8
    Content-Type: text/html; charset=UTF-8
    < Content-Length: 963
    Content-Length: 963
    < Date: Fri, 18 Oct 2013 09:04:18 GMT
    Date: Fri, 18 Oct 2013 09:04:18 GMT
    < Server: GFE/2.0
    Server: GFE/2.0
<title>Error 403 (Forbidden)!!1</title> <style> _{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}_ > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}} </style> Google

403. That鈥檚 an error.

Your client does not have permission to get URL /accounts/o8/ud from this server. That鈥檚 all we know. - Connection #0 to host www.google.com left intact - Closing connection #0 - SSLv3, TLS alert, Client hello (1):

feature: cookie/db valid session-period

right now, the cookie-expiration and the maximum-valid period of that cookie stored in the db of a successfull authentication are the same.
it would be nice to have them spilt.

to be more precise, i give an example: every time the user closes his browser, he has to re-authenticate but as long as he doesn't close his browser, he doesn't have to re-authenticate for - say - the next 24h. right now, there is no way to make mod_auth_openid to behave like that.

OpenID Assertions received via HTTP Post are not processed properly.

mod_auth_openid appears to be looking for it's own nonce parameter (which is not conveyed as any recognizable openId extension) in the POST parameters. This is easily rectified by combining the GET and POST parameters @ http_helpers.cpp line 323:

  query += "&";
  query += r->args;

curl_unescape deprecated / libcurl doesn't unescape '+' as a space

http://curl.haxx.se/libcurl/c/curl_unescape.html
below, you will find a corrected version of url_decode(...).
it also includes a bugfix for the '+', '%20' bug.

string url_decode(string str) {
//if we don't replace them, + won't be unescaped properly and we get validation errors
str = str_replace("+", "%20", str);
CURL *curl = curl_easy_init();
if(!curl)
throw failed_conversion(OPKELE_CP_ "failed to curl_easy_init()");

char * t = curl_easy_unescape(curl, str.c_str(),str.length(), NULL);

if(!t)
  throw failed_conversion(OPKELE_CP_ "failed to curl_easy_unescape()");
string rv(t);
curl_free(t);
curl_easy_cleanup(curl);
return rv;

};

mod_auth_openid Error!

Hello, guys! I am a newbie. I recently installed mod_auth_openid under centos5 X86_64. But there is an error, 「There was either no identity provider found for the identity given or there was trouble connecting to it.」 . And there is a message in log file like below: Error while fetching idP location: No more endpoints queued!

I thought it may be involved with ssl and curl(the server where I installed mod_auth_openid uses ssl connection.), and I tried to edit the mod_auth_openid.cpp file, but I failed.

I have spent two days solving the problem, but there is no use.
Any ideas? Thank you!!!!

Discrepancy in user authorization

The functoin "mod_authopenid_check_user_access" checks, if the user (as entered in the Indentity URL field) exists in the "require user A B C" directive. If, in addition to that, the user has a valid session, the module grants permission to enter. But: The "get_claimed_id" (which can defer from the actually entered, e.g. by wrapping in http://*/, or by using https://www.google.com/accounts/o8/id) will actually be used in the user program AND in Apache's Own Authorization:

mod_auth_openid will give green light but Apache will give a 401 Error! And the worst part is, that the user cannot go back, because mod_auth_openid is satisfied by the cookie and the login page will not be shown anymore!

Doesn't handle invalidate.handle requests correctly

This is complicated, bare with me.

My openid server, based on the blah ruby gem, had a bug where it would lose track of associations and nonces every so often.

This lead to already remembered associations being invalid. We were fixing it by removing /tmp/mod_auth_openid.db when this happened, but this is not an ideal situation. :-)

The debug log for this looked like so:

[Mon Nov 26 10:39:12 2012] [mod_auth_openid] Queueing endpoint http://specs.openid.net/auth/2.0/identifier_select : http://specs.openid.net/auth/2.0/identifier_select @ https://openid.example.com/server
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] INSERT INTO authentication_sessions (nonce,uri,claimed_id,local_id,expires_on) VALUES('yN1SYmjSxv','https://openid.example.com/server','http://specs.openid.net/auth/2.0/identifier_select','http://specs.openid.net/auth/2.0/identifier_select',1353947952)
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] Set normalized id to: https://openid.example.com/
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] UPDATE authentication_sessions SET normalized_id='https://openid.example.com/' WHERE nonce='yN1SYmjSxv'
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] Fetching endpoint
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] looking up association: server = https://openid.example.com/server
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] found a handle for server "https://openid.example.com/server" in db.
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] Fetching endpoint
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] https://openid.example.com/server is a trusted identity provider
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] Redirecting via HTTP_MOVED_TEMPORARILY to: https://openid.example.com/server?openid.assoc_handle=%%7BHMAC-SHA256%%7D%%7B50abf113%%7D%%7BbSPw2Q%%3D%%3D%%7D&openid.claimed_id=http%%3A%%2F%%2Fspecs.openid.net%%2Fauth%%2F2.0%%2Fidentifier_select&openid.identity=http%%3A%%2F%%2Fspecs.openid.net%%2Fauth%%2F2.0%%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%%3A%%2F%%2Fspecs.openid.net%%2Fauth%%2F2.0&openid.realm=https%%3A%%2F%%2Fpaste.example.com%%2F&openid.return_to=https%%3A%%2F%%2Fpaste.example.com%%2F%%3F%%26modauthopenid.nonce%%3DyN1SYmjSxv&openid.trust_root=https%%3A%%2F%%2Fpaste.example.com%%2F&openid.ax.mode=fetch_request&openid.ax.required=email&openid.ax.type.email=http%%3A%%2F%%2Fopenid.net%%2Fschema%%2Fcontact%%2Finternet%%2Femail&openid.ns.ax=http%%3A%%2F%%2Fopenid.net%%2Fsrv%%2Fax%%2F1.0
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] Request GET params: &modauthopenid.nonce=yN1SYmjSxv&openid.assoc_handle=%%7BHMAC-SHA1%%7D%%7B50b38d20%%7D%%7B6Oo6eA%%3D%%3D%%7D&openid.ax.mode=fetch_response&openid.ax.type.email=http%%3A%%2F%%2Fopenid.net%%2Fschema%%2Fcontact%%2Finternet%%2Femail&openid.ax.value.email=docwhat%%40corp.example.com&openid.claimed_id=https%%3A%%2F%%2Fopenid.example.com%%2Fuser%%2F1&openid.identity=https%%3A%%2F%%2Fopenid.example.com%%2Fuser%%2F1&openid.invalidate_handle=%%7BHMAC-SHA256%%7D%%7B50abf113%%7D%%7BbSPw2Q%%3D%%3D%%7D&openid.mode=id_res&openid.ns=http%%3A%%2F%%2Fspecs.openid.net%%2Fauth%%2F2.0&openid.ns.ax=http%%3A%%2F%%2Fopenid.net%%2Fsrv%%2Fax%%2F1.0&openid.op_endpoint=https%%3A%%2F%%2Fopenid.example.com%%2Fserver&openid.response_nonce=2012-11-26T15%%3A39%%3A12ZEk6eQy&openid.return_to=https%%3A%%2F%%2Fpaste.example.com%%2F%%3F%%26modauthopenid.nonce%%3DyN1SYmjSxv&openid.sig=Ghyx%%2Fve4mi4UV1q6vek68IOm%%2BdI%%3D&openid.signed=assoc_handle%%2Cax.mode%%2Cax.type.email%%2Cax.value.email%%2Cclaimed_id%%2Cidentity%%2Cinvalidate_handle%%2Cmode%%2Cns%%2Cns.ax%%2Cop_endpoint%%2Cresponse_nonce%%2Creturn_to%%2Csigned
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] looking up association: server = https://openid.example.com/server handle = {HMAC-SHA1}{50b38d20}{6Oo6eA==}
[Mon Nov 26 10:39:12 2012] [mod_auth_openid] could not find server "https://openid.example.com/server" and handle "{HMAC-SHA1}{50b38d20}{6Oo6eA==}" in db.
[Mon Nov 26 10:39:12 2012] [error] [client workstation.example.com] Error in authentication: openid.modauthopenid.nonce: no such field
[Mon Nov 26 10:39:13 2012] [mod_auth_openid] Request GET params: &modauthopenid.nonce=gejodtGc5q&openid.assoc_handle=%%7BHMAC-SHA1%%7D%%7B50b38d21%%7D%%7BrVcaQQ%%3D%%3D%%7D&openid.ax.mode=fetch_response&openid.ax.type.email=http%%3A%%2F%%2Fopenid.net%%2Fschema%%2Fcontact%%2Finternet%%2Femail&openid.ax.value.email=docwhat%%40corp.example.com&openid.claimed_id=https%%3A%%2F%%2Fopenid.example.com%%2Fuser%%2F1&openid.identity=https%%3A%%2F%%2Fopenid.example.com%%2Fuser%%2F1&openid.invalidate_handle=%%7BHMAC-SHA256%%7D%%7B50abf113%%7D%%7BbSPw2Q%%3D%%3D%%7D&openid.mode=id_res&openid.ns=http%%3A%%2F%%2Fspecs.openid.net%%2Fauth%%2F2.0&openid.ns.ax=http%%3A%%2F%%2Fopenid.net%%2Fsrv%%2Fax%%2F1.0&openid.op_endpoint=https%%3A%%2F%%2Fopenid.example.com%%2Fserver&openid.response_nonce=2012-11-26T15%%3A39%%3A13Z8AVmce&openid.return_to=https%%3A%%2F%%2Fpaste.example.com%%2Ffavicon.ico%%3F%%26modauthopenid.nonce%%3DgejodtGc5q&openid.sig=OC%%2BJlWjo%%2F4mWtoFjfeLu%%2BvDFdSg%%3D&openid.signed=assoc_handle%%2Cax.mode%%2Cax.type.email%%2Cax.value.email%%2Cclaimed_id%%2Cidentity%%2Cinvalidate_handle%%2Cmode%%2Cns%%2Cns.ax%%2Cop_endpoint%%2Cresponse_nonce%%2Creturn_to%%2Csigned
[Mon Nov 26 10:39:13 2012] [mod_auth_openid] looking up association: server = https://openid.example.com/server handle = {HMAC-SHA1}{50b38d21}{rVcaQQ==}
[Mon Nov 26 10:39:13 2012] [mod_auth_openid] could not find server "https://openid.example.com/server" and handle "{HMAC-SHA1}{50b38d21}{rVcaQQ==}" in db.
[Mon Nov 26 10:39:13 2012] [error] [client workstation.example.com] Error in authentication: openid.modauthopenid.nonce: no such field

As you can see, the openid server is requesting a new handle and invalidating the old handle (openid.invalidate_handle) because it doesn't know it.

I feel like the mod_auth_openid should be able to deal with this.

Meanwhile, I'm off to fix my openid server so it stops forgetting associations.

Ciao!

pcre.h?

On my mac, I'm failing to compile for lack of pcre.h. Perhaps you need to list it on the dependencies?

Cache-Control header not being sent with r->headers_out; works for r->err_headers_out

https://github.com/bmuller/mod_auth_openid/blob/master/src/http_helpers.cpp#L85
I can confirm that switching the above line to:
apr_table_setn(r->err_headers_out, "Cache-Control", "no-cache");
sends the Cache-Control header to the user agent. Otherwise I have never observed it sent.

I might also suggest "no-cache, must-revalidate", as I have read that Firefox will sometimes ignore no-cache.
http://www-archive.mozilla.org/projects/netlib/http/http-caching-faq.html

SB

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.