summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md80
-rw-r--r--cynagoauth.service6
-rw-r--r--src/cynagoauth-launch.c66
-rw-r--r--src/cynagoauth-server.c105
4 files changed, 207 insertions, 50 deletions
diff --git a/README.md b/README.md
index 448aed1..6012177 100644
--- a/README.md
+++ b/README.md
@@ -8,9 +8,8 @@ It currently only implments the client credential flow, checking
the client identity using the Smack label. A tiny launcher,
cynagoauth-launch, is provided to negociate the token and run
the final client, setting CYNAGOAUTH_TOKEN environment
-variable and substi
-
-
+variable and substitute the patterns for the token of the
+arguments of the launched program.
LICENSE
-------
@@ -24,18 +23,18 @@ DEPENDENCIES
It depends of:
- - json-c
- - libmicrohttpd
- - openssl
- - libcurl
-
+- json-c
+- libmicrohttpd
+- openssl
+- libcurl
+- cynagora
COMPILING
---------
To compile and install it:
-```
+```sh
mkdir build
cd build
cmake ..
@@ -45,8 +44,65 @@ make
RFCs
----
-OAuth 2.0 Authorization Server Metadata: https://tools.ietf.org/html/rfc8414
+OAuth 2.0 Authorization Framework: <https://tools.ietf.org/html/rfc6749>
+
+OAuth 2.0 Authorization Server Metadata: <https://tools.ietf.org/html/rfc8414>
+
+OAuth 2.0 Dynamic Client Registration Protocol: <https://tools.ietf.org/html/rfc7591>
+
+OpenID Connect Discovery 1.0: <https://openid.net/specs/openid-connect-discovery-1_0.html>
+
+cynagoauth-server
+-----------------
+
+```text
+> cynagoauth-server -h
+
+usage: cynagoauth-server [options...] [interfaces...]
+
+Run a basic OAuth server, currently only implementing client credential
+flow based on Smack labels and Cynagora backend.
+
+The interfaces specify ip adresses and port to listen. It must be of
+the form [HOST][:SERVICE]. Default host: *, default port: 7777.
+Examples:
-OAuth 2.0 Dynamic Client Registration Protocol: https://tools.ietf.org/html/rfc7591
+ localhost:5555 listen on loopback on port 5555
+ *:1234 listen any interface on port 1234
+ localhost listen on default port of localhost
-OpenID Connect Discovery 1.0: https://openid.net/specs/openid-connect-discovery-1_0.html
+Default interface if none is given: *:7777
+
+Options:
+
+ -h, --help this help
+ -s, --secure serves https
+ -u, --unsecure serves http
+```
+
+cynagoauth-launcher
+-------------------
+
+```text
+usage: cynagoauth-launch [options...] program [args...]
+
+Ask an OAuth2 server for an access token and launches the given program
+with this retrieved token. The URL of the token end point to be queried
+can be set by option (see below) or environment variable CYNAGOAUTH_URL.
+The default value is http://localhost:7777/tok
+
+When launched the program has the following environment variables defined:
+
+ - the access token CYNAGOAUTH_TOKEN
+
+The arguments of the program to launch are scanned and patterns for the token
+are substituted by the effective value of the token. The default pattern is @t
+
+Options:
+
+ -h, --help this help
+ -n, --name NAME name of the environement variable to set
+ -r, --replace PATTERN redefine the pattern to be replaced
+ -t, --token TOKEN the token to use, token end point is not queried
+ -u, --url URL URL of the token end point
+```
diff --git a/cynagoauth.service b/cynagoauth.service
index cd84afb..9468a7a 100644
--- a/cynagoauth.service
+++ b/cynagoauth.service
@@ -3,9 +3,9 @@ Description=Authorization server OAuth2
BindsTo=cynagora.service
[Service]
-#User=daemon
-#Group=nobody
-#SupplementaryGroups=cynagora
+User=daemon
+Group=nobody
+SupplementaryGroups=cynagora
ExecStart=/usr/bin/cynagoauth-server
Restart=on-failure
RestartSec=5
diff --git a/src/cynagoauth-launch.c b/src/cynagoauth-launch.c
index a762877..b2d6401 100644
--- a/src/cynagoauth-launch.c
+++ b/src/cynagoauth-launch.c
@@ -31,6 +31,12 @@
#if !defined(DEFAULTNAME)
# define DEFAULTNAME "CYNAGOAUTH_TOKEN"
#endif
+#if !defined(DEFAULTNAMETYPE)
+# define DEFAULTNAMETYPE DEFAULTNAME"_TYPE"
+#endif
+#if !defined(DEFAULTNAMEEXPIRE)
+# define DEFAULTNAMEEXPIRE DEFAULTNAME"_EXPIRE"
+#endif
#if !defined(VARURL)
# define VARURL "CYNAGOAUTH_URL"
#endif
@@ -38,9 +44,10 @@
# define DEFAULTURL "http://localhost:7777/tok"
#endif
-const char shortopts[] = "+n:r:t:u:";
+const char shortopts[] = "+hn:r:t:u:";
const struct option longopts[] = {
+ { "help", 0, 0, 'h' },
{ "name", 1, 0, 'n' },
{ "replace", 1, 0, 'r' },
{ "token", 1, 0, 't' },
@@ -48,6 +55,39 @@ const struct option longopts[] = {
{ 0, 0, 0, 0 }
};
+const char helpmsg[] =
+ "\n"
+ "usage: %s [options...] program [args...]\n"
+ "\n"
+ "Ask an OAuth2 server for an access token and launches the given program\n"
+ "with this retrieved token. The URL of the token end point to be queried\n"
+ "can be set by option (see below) or environment variable "VARURL".\n"
+ "The default value is "DEFAULTURL"\n"
+ "\n"
+ "When launched the program has the following environment variables defined:\n"
+ "\n"
+ " - the access token "DEFAULTNAME"\n"
+ "\n"
+ "The arguments of the program to launch are scanned and patterns for the token\n"
+ "are substituted by the effective value of the token. The default pattern is @t\n"
+ "\n"
+ "Options:\n"
+ "\n"
+ " -h, --help this help\n"
+ " -n, --name NAME name of the environement variable to set\n"
+ " -r, --replace PATTERN redefine the pattern to be replaced\n"
+ " -t, --token TOKEN the token to use, token end point is not queried\n"
+ " -u, --url URL URL of the token end point\n"
+ "\n"
+;
+
+void printhelp(char *prog)
+{
+ prog = strchr(prog, '/') ? strrchr(prog, '/') + 1 : prog;
+ printf(helpmsg, prog);
+ exit(0);
+}
+
char *optname = NULL;
char *optreplace = NULL;
char *opttoken = NULL;
@@ -67,7 +107,8 @@ char *rewrite_search(char *string, const char *defs[], int *idxpat)
for (iit = 0 ; (spat = defs[iit]) ; iit += 2) {
if (*spat) {
sit = strstr(string, spat);
- if (sit && (sfound == NULL || sfound > sit)) {
+ if (sit && (sfound == NULL || sfound > sit ||
+ (sfound == sit && strlen(spat) > strlen(defs[ifound])))) {
ifound = iit;
sfound = sit;
}
@@ -132,17 +173,9 @@ char *rewrite(char *arg, const char *token)
{
const char *defs[5];
- if (optreplace) {
- defs[0] = optreplace;
- defs[1] = token;
- defs[4] = NULL;
- } else {
- defs[0] = "@t";
- defs[1] = token;
- defs[2] = "@@";
- defs[3] = "@";
- defs[4] = NULL;
- }
+ defs[0] = optreplace ?: "@t";
+ defs[1] = token;
+ defs[2] = NULL;
return rewrite_replace(arg, defs);
}
@@ -191,22 +224,21 @@ void process_arguments(int ac, char **av)
return;
}
switch (optid) {
+ case 'h':
+ printhelp(av[0]);
+ break;
case 'n':
optname = optarg;
break;
-
case 'r':
optreplace = optarg;
break;
-
case 't':
opttoken = optarg;
break;
-
case 'u':
opturl = optarg;
break;
-
default:
fprintf(stderr, "Bad option detected");
exit(1);
diff --git a/src/cynagoauth-server.c b/src/cynagoauth-server.c
index f826c88..627e5d6 100644
--- a/src/cynagoauth-server.c
+++ b/src/cynagoauth-server.c
@@ -26,6 +26,7 @@
#include <poll.h>
#include <netdb.h>
#include <sys/socket.h>
+#include <getopt.h>
#include <microhttpd.h>
#include <json-c/json.h>
@@ -54,6 +55,47 @@
# define ENVHOSTS "CYNAGOAUTH_HOSTS_SPEC"
#endif
+static const char shortopts[] = "hs";
+
+static const struct option longopts[] = {
+ { "help", 0, 0, 'h' },
+ { "secure", 0, 0, 's' },
+ { "unsecure", 0, 0, 'u' },
+ { 0, 0, 0, 0 }
+};
+
+const char helpmsg[] =
+ "\n"
+ "usage: %s [options...] [interfaces...]\n"
+ "\n"
+ "Run a basic OAuth server, currently only implementing client credential\n"
+ "flow based on Smack labels and Cynagora backend.\n"
+ "\n"
+ "The interfaces specify ip adresses and port to listen. It must be of\n"
+ "the form [HOST][:SERVICE]. Default host: *, default port: "DEFAULTPORT".\n"
+ "Examples:\n"
+ "\n"
+ " localhost:5555 listen on loopback on port 5555\n"
+ " *:1234 listen any interface on port 1234\n"
+ " localhost listen on default port of localhost\n"
+ "\n"
+ "Default interface if none is given: "DEFAULTHOSTS"\n"
+ "\n"
+ "Options:\n"
+ "\n"
+ " -h, --help this help\n"
+ " -s, --secure serves https\n"
+ " -u, --unsecure serves http\n"
+ "\n"
+;
+
+void printhelp(char *prog)
+{
+ prog = strchr(prog, '/') ? strrchr(prog, '/') + 1 : prog;
+ printf(helpmsg, prog);
+ exit(0);
+}
+
static char cert[] =
"-----BEGIN CERTIFICATE-----\n"
"MIID5TCCAk2gAwIBAgIUBJtxecHlDMYCJfnDLqo8iWmNREkwDQYJKoZIhvcNAQEL\n"
@@ -644,6 +686,10 @@ int access_handler(
return MHD_YES;
}
+/****************************************************************************/
+/*** SETTING ***/
+/****************************************************************************/
+
int openhost(const char *hostname)
{
int rc, fd;
@@ -747,19 +793,46 @@ void main(int ac, char **av)
struct MHD_Daemon *mhd;
const union MHD_DaemonInfo *info;
MHD_UNSIGNED_LONG_LONG to;
- int i, r, n, s;
- unsigned int flags = 0;
+ int i, r, n, s, o;
+ unsigned int flags;
struct pollfd pfds[20];
credset_create(&creds);
uidset_create(&uids, 50);
- i = 1;
- if (av[i] && !strcmp(av[i], "-s")) {
- flags |= MHD_USE_TLS;
- i++;
+ flags = 0;
+ while((o = getopt_long(ac, av, shortopts, longopts, NULL)) >= 0) {
+ switch (o) {
+ case 'h':
+ printhelp(av[0]);
+ break;
+ case 's':
+ flags |= MHD_USE_TLS;
+ break;
+ case 'u':
+ flags &= ~MHD_USE_TLS;
+ break;
+ default:
+ fprintf(stderr, "Bad option detected");
+ exit(1);
+ break;
+ }
}
+ /* open hosts */
+ s = (int)(sizeof pfds / sizeof *pfds);
+ n = 1;
+ if (!av[optind])
+ n += openhosts(getenv(ENVHOSTS)?:DEFAULTHOSTS, &pfds[n], s - n);
+ else
+ while (av[optind])
+ n += openhosts(av[optind++], &pfds[n], s - n);
+ if (n == 0) {
+ fprintf(stderr, "not listening");
+ exit(1);
+ }
+
+ /* instanciate LMHD */
mhd = MHD_start_daemon(
MHD_USE_EPOLL
| MHD_USE_DEBUG
@@ -772,43 +845,38 @@ void main(int ac, char **av)
flags ? MHD_OPTION_HTTPS_MEM_KEY : MHD_OPTION_END, key,
MHD_OPTION_HTTPS_MEM_CERT, cert,
MHD_OPTION_END);
-
if (NULL == mhd) {
- fprintf(stderr, "cant't start http server\n");
+ fprintf(stderr, "cant't create http server\n");
exit(1);
}
+ /* add LMHD to polls */
info = MHD_get_daemon_info(mhd, MHD_DAEMON_INFO_EPOLL_FD);
if (info == NULL) {
fprintf(stderr, "cant't get http server\n");
MHD_stop_daemon(mhd);
exit(2);
}
-
- s = (int)(sizeof pfds / sizeof *pfds);
pfds[0].fd = info->epoll_fd;
pfds[0].events = POLLIN;
- n = 1;
-
- /* open hosts */
- if (!av[i])
- n += openhosts(getenv(ENVHOSTS)?:DEFAULTHOSTS, &pfds[n], s - n);
- else
- while (av[i])
- n += openhosts(av[i++], &pfds[n], s - n);
/* main loop */
for(;;) {
+ /* get timeout */
if (MHD_get_timeout(mhd, &to) == MHD_NO)
i = -1;
else
i = (int)to;
+
+ /* wait */
r = poll(pfds, n, i);
if (r < 0) {
fprintf(stderr, "poll error\n");
MHD_stop_daemon (mhd);
exit(3);
}
+
+ /* dispatch LMHD */
if (r == 0 || (pfds[0].revents & POLLIN))
MHD_run(mhd);
if (pfds[0].revents & POLLHUP) {
@@ -817,6 +885,7 @@ void main(int ac, char **av)
exit(4);
}
+ /* dispatch connections listeners */
for (i = 1 ; i < n ; i++) {
if (pfds[i].revents & POLLIN)
makeconnection(mhd, pfds[i].fd);