Pasta alla vongoline ;)

Posted: 17th aprile 2018 by luca (E-mail) in Cucina

 

Volando…

Posted: 28th marzo 2018 by luca (E-mail) in me?!

Zuppa di pesce

Posted: 25th marzo 2018 by luca (E-mail) in Cucina

Vellutata porri e patate

Posted: 19th febbraio 2018 by luca (E-mail) in Cucina

Ossobuco con risotto giallo

Posted: 18th febbraio 2018 by luca (E-mail) in Cucina

Muffin

Posted: 18th febbraio 2018 by luca (E-mail) in Cucina

Salmone in crosta croccante

Posted: 18th febbraio 2018 by luca (E-mail) in Cucina

In questi giorni ho avuto la necessità di modificare il modulo di autenticazione mod_auth_form di apache per aggiungere il supporto dell’OTP come campo separato e non per forza accodato alla password (questo perchè ho la necessità di salvare separatamente i due campi per successivi utilizzi in backend).

Con questa piccola patch si ottengono due nuovi parametri di configurazione inerenti a mod_auth_form, ovvero:

AuthFormOtp = Permette di impostare il nome del campo form che cotiene il campo OTP (come per AuthFormPassword) [default httpd_otp]
AuthFormOtpReuse = se impostato ad On rimanda il token otp accodato alla password al provider di autenticazione scelto anche quando tutte le credenziali arrivano dalla sessione (cookie nel nostro caso) [default off]

La logica di funzionamento è molto semplice; se nella POST il campo httpd_otp NON esiste il modulo funziona in maniera tradizionale, invece se questo campo è presente allora la password e l’otp vengono uniti in una unica stringa ed inviati al sottostante provider autenticazione scelto.
Il salvataggio dei dati nella sessione avviene mantendendo separati user password e otp.

Attenzione, l’otp e la password vengono uniti SOLO nel caso di una autenticazione proveniente da form (quindi una post http), se la ri-autenticazione sta avvenendo mediante la sessione (es: cookie) l’otp viene ignorato perchè, verosimilmente, sarà scaduto… questo comportamento però modificabile tramite l’apposita riga di configurazione AuthFormOtpReuse.

Ecco la patch:

--- mod_auth_form.c.orig	2014-06-03 14:14:22.000000000 +0200
+++ mod_auth_form.c	2018-02-09 10:11:56.274877918 +0100
@@ -40,6 +40,8 @@
 #define FORM_REDIRECT_HANDLER "form-redirect-handler"
 #define MOD_AUTH_FORM_HASH "site"
 
+#define MOD_SESSION_OTP "otp"
+
 static int (*ap_session_load_fn) (request_rec * r, session_rec ** z) = NULL;
 static apr_status_t (*ap_session_get_fn)(request_rec * r, session_rec * z,
         const char *key, const char **value) = NULL;
@@ -59,10 +61,14 @@
     int username_set;
     const char *password;
     int password_set;
+    const char *otp;
+    int otp_set;
     apr_size_t form_size;
     int form_size_set;
     int fakebasicauth;
     int fakebasicauth_set;
+    int otpreuse;
+    int otpreuse_set;
     const char *location;
     int location_set;
     const char *method;
@@ -95,6 +101,7 @@
     /* default form field names */
     conf->username = "httpd_username";
     conf->password = "httpd_password";
+    conf->otp = "httpd_otp";
     conf->location = "httpd_location";
     conf->method = "httpd_method";
     conf->mimetype = "httpd_mimetype";
@@ -118,12 +125,16 @@
     new->username_set = add->username_set || base->username_set;
     new->password = (add->password_set == 0) ? base->password : add->password;
     new->password_set = add->password_set || base->password_set;
+    new->otp = (add->otp_set == 0) ? base->otp : add->otp;
+    new->otp_set = add->otp_set || base->otp_set;
     new->location = (add->location_set == 0) ? base->location : add->location;
     new->location_set = add->location_set || base->location_set;
     new->form_size = (add->form_size_set == 0) ? base->form_size : add->form_size;
     new->form_size_set = add->form_size_set || base->form_size_set;
     new->fakebasicauth = (add->fakebasicauth_set == 0) ? base->fakebasicauth : add->fakebasicauth;
     new->fakebasicauth_set = add->fakebasicauth_set || base->fakebasicauth_set;
+    new->otpreuse = (add->otpreuse_set == 0) ? base->otpreuse : add->otpreuse;
+    new->otpreuse_set = add->otpreuse_set || base->otpreuse_set;
     new->method = (add->method_set == 0) ? base->method : add->method;
     new->method_set = add->method_set || base->method_set;
     new->mimetype = (add->mimetype_set == 0) ? base->mimetype : add->mimetype;
@@ -227,6 +238,14 @@
     return check_string(cmd, password);
 }
 
+static const char *set_cookie_form_otp(cmd_parms * cmd, void *config, const char *otp)
+{
+    auth_form_config_rec *conf = (auth_form_config_rec *) config;
+    conf->otp = otp;
+    conf->otp_set = 1;
+    return check_string(cmd, otp);
+}
+
 static const char *set_cookie_form_method(cmd_parms * cmd, void *config, const char *method)
 {
     auth_form_config_rec *conf = (auth_form_config_rec *) config;
@@ -342,6 +361,14 @@
     return NULL;
 }
 
+static const char *set_disable_otp_reuse(cmd_parms * cmd, void *config, int flag)
+{
+    auth_form_config_rec *conf = (auth_form_config_rec *) config;
+    conf->otpreuse = flag;
+    conf->otpreuse_set = 1;
+    return NULL;
+}
+
 static const char *set_disable_no_store(cmd_parms * cmd, void *config, int flag)
 {
     auth_form_config_rec *conf = (auth_form_config_rec *) config;
@@ -358,6 +385,8 @@
                   "The field of the login form carrying the username"),
     AP_INIT_TAKE1("AuthFormPassword", set_cookie_form_password, NULL, OR_AUTHCFG,
                   "The field of the login form carrying the password"),
+    AP_INIT_TAKE1("AuthFormOtp", set_cookie_form_otp, NULL, OR_AUTHCFG,
+                  "The field of the login form carrying the OTP"),
     AP_INIT_TAKE1("AuthFormLocation", set_cookie_form_location, NULL, OR_AUTHCFG,
                   "The field of the login form carrying the URL to redirect on "
                   "successful login."),
@@ -396,6 +425,10 @@
                  NULL, OR_AUTHCFG,
                  "Set to 'On' to pass through authentication to the rest of the "
                  "server as a basic authentication header."),
+    AP_INIT_FLAG("AuthFormOtpReuse", set_disable_otp_reuse,
+                 NULL, OR_AUTHCFG,
+                 "Set to 'On' for reuse OTP number from cookie and send'it to "
+                 "to authentication provider."),
     AP_INIT_FLAG("AuthFormDisableNoStore", set_disable_no_store,
                  NULL, OR_AUTHCFG,
                  "Set to 'on' to stop the sending of a Cache-Control no-store header with "
@@ -432,7 +465,7 @@
  * notes table.
  */
 static void set_notes_auth(request_rec * r,
-                                const char *user, const char *pw,
+                                const char *user, const char *pw, const char *otp,
                                 const char *method, const char *mimetype)
 {
     apr_table_t *notes = NULL;
@@ -456,6 +489,9 @@
     if (pw) {
         apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-pw", NULL), pw);
     }
+    if (otp) {
+        apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-otp", NULL), otp);
+    }
     if (method) {
         apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-method", NULL), method);
     }
@@ -471,7 +507,7 @@
  */
 static void get_notes_auth(request_rec *r,
                            const char **user, const char **pw,
-                           const char **method, const char **mimetype)
+                           const char **method, const char **mimetype, const char **otp)
 {
     const char *authname;
     request_rec *m = r;
@@ -493,6 +529,9 @@
     if (pw) {
         *pw = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-pw", NULL));
     }
+    if (otp) {
+        *otp = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-otp", NULL));
+    }
     if (method) {
         *method = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-method", NULL));
     }
@@ -506,9 +545,9 @@
     }
 
     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
-                  "from notes: user: %s, pw: %s, method: %s, mimetype: %s",
-                  user ? *user : "", pw ? *pw : "",
-                  method ? *method : "", mimetype ? *mimetype : "");
+                  "from notes: user: %s, pw: %s, method: %s, mimetype: %s, otp: %s",
+                  user ? *user : "", pw ? *pw : "", 
+                  method ? *method : "", mimetype ? *mimetype : "",otp ? *otp : "");
 
 }
 
@@ -519,7 +558,7 @@
  * and/or password will be removed from the session.
  */
 static apr_status_t set_session_auth(request_rec * r,
-                                     const char *user, const char *pw, const char *site)
+                                     const char *user, const char *pw, const char *site, const char *otp)
 {
     const char *hash = NULL;
     const char *authname = ap_auth_name(r);
@@ -533,6 +572,7 @@
     ap_session_load_fn(r, &z);
     ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_USER, NULL), user);
     ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_PW, NULL), pw);
+    ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_OTP, NULL), otp);
     ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_AUTH_FORM_HASH, NULL), hash);
 
     return APR_SUCCESS;
@@ -544,10 +584,12 @@
  * notes table, if present.
  */
 static apr_status_t get_session_auth(request_rec * r,
-                                     const char **user, const char **pw, const char **hash)
+                                     const char **user, const char **pw, const char **hash, const char **otp)
 {
     const char *authname = ap_auth_name(r);
     session_rec *z = NULL;
+    auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
+                                                      &auth_form_module);
 
     ap_session_load_fn(r, &z);
 
@@ -557,6 +599,11 @@
     if (pw) {
         ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_PW, NULL), pw);
     }
+    if (conf->otpreuse) {
+	    if (otp) {
+	        ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_OTP, NULL), otp);
+	    }
+    }
     if (hash) {
         ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_AUTH_FORM_HASH, NULL), hash);
     }
@@ -568,9 +615,10 @@
 
     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                   "from session: " MOD_SESSION_USER ": %s, " MOD_SESSION_PW
-                  ": %s, " MOD_AUTH_FORM_HASH ": %s",
+                  ": %s, " MOD_AUTH_FORM_HASH ": %s, " MOD_SESSION_OTP ": %s (reuse %s)" ,
                   user ? *user : "", pw ? *pw : "",
-                  hash ? *hash : "");
+                  hash ? *hash : "", otp ? *otp : "",
+                  conf->otpreuse ? "On" : "Off");
 
     return APR_SUCCESS;
 
@@ -590,12 +638,14 @@
 static int get_form_auth(request_rec * r,
                              const char *username,
                              const char *password,
+                             const char *otp,
                              const char *location,
                              const char *method,
                              const char *mimetype,
                              const char *body,
                              const char **sent_user,
                              const char **sent_pw,
+                             const char **sent_otp,
                              const char **sent_loc,
                              const char **sent_method,
                              const char **sent_mimetype,
@@ -612,7 +662,7 @@
     char *buffer;
 
     /* have we isolated the user and pw before? */
-    get_notes_auth(r, sent_user, sent_pw, sent_method, sent_mimetype);
+    get_notes_auth(r, sent_user, sent_pw, sent_method, sent_mimetype, sent_otp);
     if (*sent_user && *sent_pw) {
         return OK;
     }
@@ -639,6 +689,14 @@
             buffer[len] = 0;
             *sent_pw = buffer;
         }
+        else if (otp && !strcmp(pair->name, otp) && sent_otp) {
+            apr_brigade_length(pair->value, 1, &len);
+            size = (apr_size_t) len;
+            buffer = apr_palloc(r->pool, size + 1);
+            apr_brigade_flatten(pair->value, buffer, &size);
+            buffer[len] = 0;
+            *sent_otp = buffer;
+        }
         else if (location && !strcmp(pair->name, location) && sent_loc) {
             apr_brigade_length(pair->value, 1, &len);
             size = (apr_size_t) len;
@@ -669,11 +727,12 @@
     }
 
     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
-                  "from form: user: %s, pw: %s, method: %s, mimetype: %s, location: %s",
+                  "from form: user: %s, pw: %s, method: %s, mimetype: %s, location: %s, otp: %s",
                   sent_user ? *sent_user : "", sent_pw ? *sent_pw : "",
                   sent_method ? *sent_method : "",
                   sent_mimetype ? *sent_mimetype : "",
-                  sent_loc ? *sent_loc : "");
+                  sent_loc ? *sent_loc : "",
+		  sent_otp ? *sent_otp : "");
 
     /* set the user, even though the user is unauthenticated at this point */
     if (sent_user && *sent_user) {
@@ -702,7 +761,7 @@
      * save away the username, password, mimetype and method, so that they
      * are available should the auth need to be run again.
      */
-    set_notes_auth(r, *sent_user, *sent_pw, sent_method ? *sent_method : NULL,
+    set_notes_auth(r, *sent_user, *sent_pw, *sent_otp ? *sent_otp : NULL, sent_method ? *sent_method : NULL,
                    sent_mimetype ? *sent_mimetype : NULL);
 
     return OK;
@@ -756,12 +815,20 @@
  *
  * Return an HTTP code.
  */
-static int check_authn(request_rec * r, const char *sent_user, const char *sent_pw)
+static int check_authn(request_rec * r, const char *sent_user, const char *sent_pw, const char *sent_otp)
 {
     authn_status auth_result;
     authn_provider_list *current_provider;
     auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                       &auth_form_module);
+    char *sent_secret = NULL;
+
+    // -lm
+    if (sent_otp) {
+	sent_secret = apr_pstrcat(r->pool, sent_pw, sent_otp, NULL);
+    } else {
+	sent_secret = apr_pstrcat(r->pool, sent_pw, NULL);
+    }
 
     current_provider = conf->providers;
     do {
@@ -794,7 +861,12 @@
             break;
         }
 
-        auth_result = provider->check_password(r, sent_user, sent_pw);
+	ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+                  "provider->check_password - sent_user : %s, sent_secret: %s (pw: %s - otp: %s)", 
+		  sent_user, sent_secret, sent_pw, sent_otp);
+
+        auth_result = provider->check_password(r, sent_user, sent_secret);
+        //auth_result = provider->check_password(r, sent_user, sent_pw);
 
         apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
 
@@ -883,7 +955,7 @@
 {
     auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                       &auth_form_module);
-    const char *sent_user = NULL, *sent_pw = NULL, *sent_hash = NULL;
+    const char *sent_user = NULL, *sent_pw = NULL, *sent_hash = NULL, *sent_otp = NULL;
     const char *sent_loc = NULL, *sent_method = "GET", *sent_mimetype = NULL;
     const char *current_auth = NULL;
     const char *err;
@@ -919,11 +991,11 @@
     r->ap_auth_type = (char *) current_auth;
 
     /* try get the username and password from the notes, if present */
-    get_notes_auth(r, &sent_user, &sent_pw, &sent_method, &sent_mimetype);
+    get_notes_auth(r, &sent_user, &sent_pw, &sent_method, &sent_mimetype, &sent_otp);
     if (!sent_user || !sent_pw || !*sent_user || !*sent_pw) {
 
         /* otherwise try get the username and password from a session, if present */
-        res = get_session_auth(r, &sent_user, &sent_pw, &sent_hash);
+        res = get_session_auth(r, &sent_user, &sent_pw, &sent_hash, &sent_otp);
 
     }
     else {
@@ -941,7 +1013,7 @@
 
     /* otherwise test for a normal password match */
     if (APR_SUCCESS == res && sent_user && sent_pw) {
-        rv = check_authn(r, sent_user, sent_pw);
+        rv = check_authn(r, sent_user, sent_pw, sent_otp);
         if (OK == rv) {
             fake_basic_authentication(r, conf, sent_user, sent_pw);
             return OK;
@@ -990,9 +1062,9 @@
         ap_run_insert_filter(rr);
 
         /* parse the form by reading the subrequest */
-        rv = get_form_auth(rr, conf->username, conf->password, conf->location,
+        rv = get_form_auth(rr, conf->username, conf->password, conf->otp, conf->location,
                            conf->method, conf->mimetype, conf->body,
-                           &sent_user, &sent_pw, &sent_loc, &sent_method,
+                           &sent_user, &sent_pw, &sent_otp, &sent_loc, &sent_method,
                            &sent_mimetype, &sent_body, conf);
 
         /* make sure any user detected within the subrequest is saved back to
@@ -1028,10 +1100,10 @@
 
         /* check the authn in the main request, based on the username found */
         if (OK == rv) {
-            rv = check_authn(r, sent_user, sent_pw);
+            rv = check_authn(r, sent_user, sent_pw, sent_otp);
             if (OK == rv) {
                 fake_basic_authentication(r, conf, sent_user, sent_pw);
-                set_session_auth(r, sent_user, sent_pw, conf->site);
+                set_session_auth(r, sent_user, sent_pw, conf->site, sent_otp);
                 if (sent_loc) {
                     apr_table_set(r->headers_out, "Location", sent_loc);
                     return HTTP_MOVED_TEMPORARILY;
@@ -1115,7 +1187,7 @@
     auth_form_config_rec *conf;
     const char *err;
 
-    const char *sent_user = NULL, *sent_pw = NULL, *sent_loc = NULL;
+    const char *sent_user = NULL, *sent_pw = NULL, *sent_otp = NULL, *sent_loc = NULL;
     int rv;
 
     if (strcmp(r->handler, FORM_LOGIN_HANDLER)) {
@@ -1131,14 +1203,14 @@
 
     conf = ap_get_module_config(r->per_dir_config, &auth_form_module);
 
-    rv = get_form_auth(r, conf->username, conf->password, conf->location,
+    rv = get_form_auth(r, conf->username, conf->password, conf->otp, conf->location,
                        NULL, NULL, NULL,
-                       &sent_user, &sent_pw, &sent_loc,
+                       &sent_user, &sent_pw, &sent_otp, &sent_loc,
                        NULL, NULL, NULL, conf);
     if (OK == rv) {
-        rv = check_authn(r, sent_user, sent_pw);
+        rv = check_authn(r, sent_user, sent_pw, sent_otp);
         if (OK == rv) {
-            set_session_auth(r, sent_user, sent_pw, conf->site);
+            set_session_auth(r, sent_user, sent_pw, conf->site, sent_otp);
             if (sent_loc) {
                 apr_table_set(r->headers_out, "Location", sent_loc);
                 return HTTP_MOVED_TEMPORARILY;
@@ -1202,7 +1274,7 @@
     conf = ap_get_module_config(r->per_dir_config, &auth_form_module);
 
     /* remove the username and password, effectively logging the user out */
-    set_session_auth(r, NULL, NULL, NULL);
+    set_session_auth(r, NULL, NULL, NULL, NULL);
 
     /*
      * make sure the logout page is never cached - otherwise the logout won't
@@ -1249,7 +1321,7 @@
     }
 
     /* get the method and mimetype from the notes */
-    get_notes_auth(r, NULL, NULL, &sent_method, &sent_mimetype);
+    get_notes_auth(r, NULL, NULL, &sent_method, &sent_mimetype, NULL);
 
     if (r->kept_body && sent_method && sent_mimetype) {

Qualche giorno addietro mi si è presentata la necessità di inviare, a valle di un reverse proxy, il contenuto di un cookie cifrato.

Apache2 implementa (almeno in teoria) questa funzionalità e si chiama SessionHeader (potete vedere qui le specifiche in “Integrating Sessions with External Applications”).

Tutto molto figo pensavo… peccato non funziona nulla!

La cosa mi ha lasciato abbastanza perplesso e dopo una serie di ricerche ha trovato la segnalazione di un bug di un utente che, come me, si era scontrato con la medesima problematica… bug segnalato sul Bugzilla di apache (Bug n. 56495) in data 2014-05-06 19:19 UTC by David Goldfarb.

Figo ho pensato… quelli di apache se ne sono largamente sbattuti della problematica!

Per fortuna l’utente proponeva una piccola patch a mod_session.c per risolvere la problematica (che è palesemente una dimenticanza nel codice), la patch però risulta instabile per cui ho apportato qualche piccola modifica per evitare il segfault di apache, ecco il diff:

--- httpd-2.4.9.orig/modules/session/mod_session.c   2014-01-24 07:02:42.000000000 -0600
+++ httpd-2.4.9/modules/session/mod_session.c   2014-05-06 13:59:09.084183389 -0500
@@ -385,6 +385,13 @@

     /* decode what we have */
     encoded = apr_pstrdup(r->pool, z->encoded);
+
+    /* Add the Decoded session info into the Input Headers
+     *  for the application to find */
+    session_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+                                                  &session_module);
+    if (conf->header) {  
+         apr_table_set(r->headers_in, conf->header, encoded);
+    }  
+
     pair = apr_strtok(encoded, sep, &last);
     while (pair && pair[0]) {
         char *plast = NULL;