Re: Authorization callback in rr-sasl

Andrea Campi <[email protected]> Tue, 13 May 2003 18:54:36 +0200
Newsgroups gmane.network.beep.roadrunner.general
Organization I.NET S.p.A.
Message-ID <[email protected]>
--w7PDEPdKQumQfZlR
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

There were a couple of last-minute changes that (obviously) introduced
bugs...

I'm resending the patch.


Bye,
	Andrea

On Tue, May 13, 2003 at 05:20:39PM +0200, Andrea Campi wrote:
> Hi Jonas,
> 
> I've patched rr-sasl to allow a server to specify a callback to use
> in "proxy authorization". I strived to do maintain consistency with
> the rest of the API and with the style of the modified files; however,
> if you are interested in committing it, please feel free to modify it
> as you see fit.
> 
> There's one minor issue I'd like to get your opinion on. I modeled
> cb_authorize on the other callbacks, in that it does some processing,
> the checks if there is a user callback, if not calls some internal function
> (sasl_authorize in this case). I chose to make this a separate function
> to keep code cleaner, but I see no advantage in exporting it in the
> way rr_sasl_get_* are. Do you agree with this? It also arguably doesnt'
> need RRConnection, but I left it for uniformity.
> I also chose to pass the user and auth as gchar instead of a buffer with
> explicit length.
> 
> 
> Bye,
> 	Andrea
> 
> -- 
> Andrea Campi                              mailto:[email protected]
> I.NET S.p.A. - BT Ignite                  http://www.inet.it
> Technical Dept. - R&D			  phone: +39 02 32863 ext 1
> v. Darwin, 85 - I-20019			  fax: +39 02 32863 ext 7705
> Settimo Milanese (MI), Italy

> ==== //depot/rrsasl_inet/librrsasl/librrsasl.exp#2 - /home/src/acampi/ws/rrsasl_inet/librrsasl/librrsasl.exp ====
> @@ -1,6 +1,7 @@
>  rr_sasl_anonymous_get_type
>  rr_sasl_config_new
>  rr_sasl_config_destroy
> +rr_sasl_config_set_authorize_cb
>  rr_sasl_config_set_password_cb
>  rr_sasl_cram_md5_get_type
>  rr_sasl_digest_md5_get_type
> ==== //depot/rrsasl_inet/librrsasl/rr-sasl.c#7 - /home/src/acampi/ws/rrsasl_inet/librrsasl/rr-sasl.c ====
> @@ -75,6 +75,11 @@
>  		    unsigned *len);
>  static int cb_authname (void *context, int id, const char **result, 
>  			unsigned *len);
> +static int cb_authorize (sasl_conn_t *conn, void *context,
> +			 const char *requested_user, unsigned rlen,
> +			 const char *auth_identity, unsigned alen,
> +			 const char *def_realm, unsigned urlen,
> +			 struct propctx *propctx);
>  static gboolean init_sasl_conn (RRSASL *sasl, gboolean server, 
>  				GError **error);
>  static gboolean client_init (RRChannel *channel, GError **error);
> @@ -203,6 +208,51 @@
>  	return SASL_OK;
>  }
>  
> +static int
> +sasl_authorize (RRConnection *connection,
> +				const gchar *user, const gchar *auth)
> +{
> +	g_return_val_if_fail (RR_IS_CONNECTION (connection), NULL);
> +
> +	if (!strcmp(user, auth))
> +		return SASL_OK;
> +
> +	return SASL_NOAUTHZ;
> +}
> +
> +static int
> +cb_authorize (sasl_conn_t *conn, void *context,
> +	      const char *requested_user, unsigned rlen,
> +	      const char *auth_identity, unsigned alen,
> +	      const char *def_realm, unsigned urlen,
> +	      struct propctx *propctx)
> +{
> +	RRSASL *sasl = RR_SASL (context);
> +	RRSASLPriv *priv = sasl->priv;
> +	RRConnection *rr_conn = RR_CHANNEL (sasl)->connection;
> +	gchar *auth, *user;
> +	int rc;
> +
> +	g_message("cb_authorize: %d(%s) %d(%s) %d(%s)",
> +		rlen, requested_user, alen, auth_identity, urlen, def_realm);
> +
> +	user = g_malloc0(rlen+1);
> +	strncpy(user, requested_user, rlen);
> +	user[0] = '\0';
> +	
> +	auth = g_malloc0(alen+1);
> +	strncpy(auth, auth_identity, alen);
> +	auth[0] = '\0';
> +
> +	if (priv->cfg && priv->cfg->authorize_cb)
> +		rc = priv->cfg->authorize_cb (sasl, auth, user,
> +					      priv->cfg->authorize_data);
> +	else
> +		rc = sasl_authorize (rr_conn, auth, user);
> +
> +	return rc;
> +}
> +
>  static void
>  rr_sasl_init (GObject *object)
>  {
> @@ -872,10 +922,17 @@
>  	else
>  		service = "beep";
>  
> -	if (server)
> +	if (server) {
> +		priv->callbacks = g_new0 (sasl_callback_t, 2);
> +		priv->callbacks[0].id = SASL_CB_PROXY_POLICY;
> +		priv->callbacks[1].id = SASL_CB_LIST_END;
> +		priv->callbacks[0].proc = &cb_authorize;
> +		priv->callbacks[0].context = sasl;
> +
>  		r = sasl_server_new(service, myhostname, NULL, localaddr, 
> -				    remoteaddr, NULL, 0, &priv->sasl_conn);
> -	else {
> +				    remoteaddr, priv->callbacks, 0,
> +				    &priv->sasl_conn);
> +	} else {
>  		priv->callbacks = g_new0 (sasl_callback_t, 4);
>  		priv->callbacks[0].id = SASL_CB_USER;
>  		priv->callbacks[1].id = SASL_CB_AUTHNAME;
> ==== //depot/rrsasl_inet/librrsasl/rr-saslconfig-priv.h#1 - /home/src/acampi/ws/rrsasl_inet/librrsasl/rr-saslconfig-priv.h ====
> @@ -22,10 +22,12 @@
>  	RRSASLGetUsername user_cb;
>  	RRSASLGetAuthname auth_cb;
>  	RRSASLGetPassword pass_cb;
> +	RRSASLAuthorize   authorize_cb;
>  
>  	gpointer user_data;
>  	gpointer auth_data;
>  	gpointer pass_data;
> +	gpointer authorize_data;
>  };
>  
>  G_END_DECLS
> ==== //depot/rrsasl_inet/librrsasl/rr-saslconfig.c#2 - /home/src/acampi/ws/rrsasl_inet/librrsasl/rr-saslconfig.c ====
> @@ -75,3 +75,14 @@
>  	config->pass_data = user_data;
>  }
>  
> +void
> +rr_sasl_config_set_authorize_cb (RRSASLConfig *config,
> +				 RRSASLAuthorize cb,
> +				 gpointer authorize_data)
> +{
> +	g_return_if_fail (config != NULL);
> +
> +	config->authorize_cb = cb;
> +	config->authorize_data = authorize_data;
> +}
> +
> ==== //depot/rrsasl_inet/librrsasl/rr-saslconfig.h#2 - /home/src/acampi/ws/rrsasl_inet/librrsasl/rr-saslconfig.h ====
> @@ -21,6 +21,8 @@
>  typedef gchar *(*RRSASLGetUsername)  (RRSASL *sasl, gpointer user_data);
>  typedef gchar *(*RRSASLGetAuthname)  (RRSASL *sasl, gpointer user_data);
>  typedef gchar *(*RRSASLGetPassword)  (RRSASL *sasl, gpointer user_data);
> +typedef int    (*RRSASLAuthorize)    (RRSASL *sasl, gchar *auth, gchar *user,
> +				      gpointer user_data);
>  
>  RRSASLConfig *rr_sasl_config_new            (void);
>  
> @@ -41,6 +43,10 @@
>  					     RRSASLGetPassword cb,
>  					     gpointer user_data);
>  
> +void         rr_sasl_config_set_authorize_cb (RRSASLConfig *config,
> +					      RRSASLAuthorize cb,
> +					      gpointer authorize_data);
> +
>  G_END_DECLS
>  
>  #endif

> _______________________________________________
> Roadrunner mailing list
> [email protected]
> http://lists.codefactory.se/cgi-bin/mailman/listinfo/roadrunner


-- 
Andrea Campi                              mailto:[email protected]
I.NET S.p.A. - BT Ignite                  http://www.inet.it
Technical Dept. - R&D			  phone: +39 02 32863 ext 1
v. Darwin, 85 - I-20019			  fax: +39 02 32863 ext 7705
Settimo Milanese (MI), Italy

--w7PDEPdKQumQfZlR
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="rrsasl.diff"

==== //depot/rrsasl_inet/librrsasl/librrsasl.exp#2 - /home/src/acampi/ws/rrsasl_inet/librrsasl/librrsasl.exp ====
@@ -1,6 +1,7 @@
 rr_sasl_anonymous_get_type
 rr_sasl_config_new
 rr_sasl_config_destroy
+rr_sasl_config_set_authorize_cb
 rr_sasl_config_set_password_cb
 rr_sasl_cram_md5_get_type
 rr_sasl_digest_md5_get_type
==== //depot/rrsasl_inet/librrsasl/rr-sasl.c#7 - /home/src/acampi/ws/rrsasl_inet/librrsasl/rr-sasl.c ====
@@ -75,6 +75,11 @@
 		    unsigned *len);
 static int cb_authname (void *context, int id, const char **result, 
 			unsigned *len);
+static int cb_authorize (sasl_conn_t *conn, void *context,
+			 const char *requested_user, unsigned rlen,
+			 const char *auth_identity, unsigned alen,
+			 const char *def_realm, unsigned urlen,
+			 struct propctx *propctx);
 static gboolean init_sasl_conn (RRSASL *sasl, gboolean server, 
 				GError **error);
 static gboolean client_init (RRChannel *channel, GError **error);
@@ -203,6 +208,51 @@
 	return SASL_OK;
 }
 
+static int
+sasl_authorize (RRConnection *connection,
+				const gchar *user, const gchar *auth)
+{
+	g_return_val_if_fail (RR_IS_CONNECTION (connection), NULL);
+
+	if (!strcmp(user, auth))
+		return SASL_OK;
+
+	return SASL_NOAUTHZ;
+}
+
+static int
+cb_authorize (sasl_conn_t *conn, void *context,
+	      const char *requested_user, unsigned rlen,
+	      const char *auth_identity, unsigned alen,
+	      const char *def_realm, unsigned urlen,
+	      struct propctx *propctx)
+{
+	RRSASL *sasl = RR_SASL (context);
+	RRSASLPriv *priv = sasl->priv;
+	RRConnection *rr_conn = RR_CHANNEL (sasl)->connection;
+	gchar *auth, *user;
+	int rc;
+
+	g_message("cb_authorize: %d(%s) %d(%s) %d(%s)",
+		rlen, requested_user, alen, auth_identity, urlen, def_realm);
+
+	user = g_malloc0(rlen+1);
+	strncpy(user, requested_user, rlen);
+	user[rlen] = '\0';
+	
+	auth = g_malloc0(alen+1);
+	strncpy(auth, auth_identity, alen);
+	auth[alen] = '\0';
+
+	if (priv->cfg && priv->cfg->authorize_cb)
+		rc = priv->cfg->authorize_cb (sasl, auth, user,
+					      priv->cfg->authorize_data);
+	else
+		rc = sasl_authorize (rr_conn, auth, user);
+
+	return rc;
+}
+
 static void
 rr_sasl_init (GObject *object)
 {
@@ -872,10 +922,17 @@
 	else
 		service = "beep";
 
-	if (server)
+	if (server) {
+		priv->callbacks = g_new0 (sasl_callback_t, 2);
+		priv->callbacks[0].id = SASL_CB_PROXY_POLICY;
+		priv->callbacks[1].id = SASL_CB_LIST_END;
+		priv->callbacks[0].proc = &cb_authorize;
+		priv->callbacks[0].context = sasl;
+
 		r = sasl_server_new(service, myhostname, NULL, localaddr, 
-				    remoteaddr, NULL, 0, &priv->sasl_conn);
-	else {
+				    remoteaddr, priv->callbacks, 0,
+				    &priv->sasl_conn);
+	} else {
 		priv->callbacks = g_new0 (sasl_callback_t, 4);
 		priv->callbacks[0].id = SASL_CB_USER;
 		priv->callbacks[1].id = SASL_CB_AUTHNAME;
==== //depot/rrsasl_inet/librrsasl/rr-saslconfig-priv.h#1 - /home/src/acampi/ws/rrsasl_inet/librrsasl/rr-saslconfig-priv.h ====
@@ -22,10 +22,12 @@
 	RRSASLGetUsername user_cb;
 	RRSASLGetAuthname auth_cb;
 	RRSASLGetPassword pass_cb;
+	RRSASLAuthorize   authorize_cb;
 
 	gpointer user_data;
 	gpointer auth_data;
 	gpointer pass_data;
+	gpointer authorize_data;
 };
 
 G_END_DECLS
==== //depot/rrsasl_inet/librrsasl/rr-saslconfig.c#2 - /home/src/acampi/ws/rrsasl_inet/librrsasl/rr-saslconfig.c ====
@@ -75,3 +75,14 @@
 	config->pass_data = user_data;
 }
 
+void
+rr_sasl_config_set_authorize_cb (RRSASLConfig *config,
+				 RRSASLAuthorize cb,
+				 gpointer authorize_data)
+{
+	g_return_if_fail (config != NULL);
+
+	config->authorize_cb = cb;
+	config->authorize_data = authorize_data;
+}
+
==== //depot/rrsasl_inet/librrsasl/rr-saslconfig.h#2 - /home/src/acampi/ws/rrsasl_inet/librrsasl/rr-saslconfig.h ====
@@ -21,6 +21,10 @@
 typedef gchar *(*RRSASLGetUsername)  (RRSASL *sasl, gpointer user_data);
 typedef gchar *(*RRSASLGetAuthname)  (RRSASL *sasl, gpointer user_data);
 typedef gchar *(*RRSASLGetPassword)  (RRSASL *sasl, gpointer user_data);
+typedef int    (*RRSASLAuthorize)    (RRSASL *sasl,
+				      const gchar *auth,
+				      const gchar *user,
+				      gpointer user_data);
 
 RRSASLConfig *rr_sasl_config_new            (void);
 
@@ -41,6 +43,10 @@
 					     RRSASLGetPassword cb,
 					     gpointer user_data);
 
+void         rr_sasl_config_set_authorize_cb (RRSASLConfig *config,
+					      RRSASLAuthorize cb,
+					      gpointer authorize_data);
+
 G_END_DECLS
 
 #endif

--w7PDEPdKQumQfZlR
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

_______________________________________________
Roadrunner mailing list
[email protected]
http://lists.codefactory.se/cgi-bin/mailman/listinfo/roadrunner

--w7PDEPdKQumQfZlR--