Authorization callback in rr-sasl

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

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

--Y7xTucakfITjPcLV
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[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

--Y7xTucakfITjPcLV
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

--Y7xTucakfITjPcLV--