gsasl-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gsasl branch, master, updated. gsasl-1-7-1-16-g01213ea


From: Simon Josefsson
Subject: [SCM] GNU gsasl branch, master, updated. gsasl-1-7-1-16-g01213ea
Date: Mon, 26 Mar 2012 20:17:29 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gsasl".

http://git.savannah.gnu.org/cgit/gsasl.git/commit/?id=01213eae08e5b736781d0e14f6d10a7e35e1e3c8

The branch, master has been updated
       via  01213eae08e5b736781d0e14f6d10a7e35e1e3c8 (commit)
       via  f4bc359074ca470fcbf43bef2f7994a067941c74 (commit)
       via  4e3b6f70b4c3f55d6207ea2de72d6526304eb161 (commit)
       via  5d0ad5517d1b4586c41550ea477de5aa19482d1e (commit)
       via  0a18684417d625d40898f9bd019894bfdbcc48bb (commit)
      from  337a07ef42b02ed9235e5e153818e61f2b95ea76 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 01213eae08e5b736781d0e14f6d10a7e35e1e3c8
Author: Simon Josefsson <address@hidden>
Date:   Mon Mar 26 20:51:00 2012 +0200

    Add example SMTP server.

commit f4bc359074ca470fcbf43bef2f7994a067941c74
Author: Simon Josefsson <address@hidden>
Date:   Mon Mar 26 20:50:24 2012 +0200

    Support SAML20 callbacks.

commit 4e3b6f70b4c3f55d6207ea2de72d6526304eb161
Author: Simon Josefsson <address@hidden>
Date:   Fri Mar 23 14:37:33 2012 +0100

    Handle when AUTH tokens are on final 250 line.

commit 5d0ad5517d1b4586c41550ea477de5aa19482d1e
Author: Simon Josefsson <address@hidden>
Date:   Fri Mar 23 13:15:17 2012 +0100

    Prepare for --listen.

commit 0a18684417d625d40898f9bd019894bfdbcc48bb
Author: Simon Josefsson <address@hidden>
Date:   Fri Mar 23 13:11:24 2012 +0100

    Don't even try to get channel binding when --no-cb was given.

-----------------------------------------------------------------------

Summary of changes:
 .gitignore             |    2 +
 examples/Makefile.am   |    2 +-
 examples/smtp-server.c |  288 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/callbacks.c        |   21 ++++
 src/gsasl.c            |    1 +
 src/gsasl.ggo          |    1 +
 src/smtp.c             |    9 +-
 7 files changed, 320 insertions(+), 4 deletions(-)
 create mode 100644 examples/smtp-server.c

diff --git a/.gitignore b/.gitignore
index 63fd66b..cc8f785 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,6 +102,8 @@ examples/client-xmpp-saml20.o
 examples/client.o
 examples/server-xmpp-saml20
 examples/server-xmpp-saml20.o
+examples/smtp-server
+examples/smtp-server.o
 gl/.deps/
 gl/.libs/
 gl/Makefile
diff --git a/examples/Makefile.am b/examples/Makefile.am
index d4454ca..8313d63 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -22,5 +22,5 @@ LDADD = ../lib/src/libgsasl.la
 
 EXTRA_DIST = README
 
-noinst_PROGRAMS = client client-serverfirst client-mech        \
+noinst_PROGRAMS = client client-serverfirst client-mech smtp-server \
        client-callback client-xmpp-saml20 server-xmpp-saml20
diff --git a/examples/smtp-server.c b/examples/smtp-server.c
new file mode 100644
index 0000000..74b2427
--- /dev/null
+++ b/examples/smtp-server.c
@@ -0,0 +1,288 @@
+/* smtp-server.c --- Example SMTP server with SASL authentication
+ * Copyright (C) 2012  Simon Josefsson
+ *
+ * This file is part of GNU SASL.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* This is a minimal SMTP server with GNU SASL authentication support.
+   The only valid password is "sesam".  This server will complete
+   authentications using LOGIN, PLAIN, DIGEST-MD5, CRAM-MD5, and
+   SCRAM-SHA-1.  It accepts an optional command line parameter
+   specifying the service name (i.e., a numerical port number or
+   /etc/services name).  By default it listens on port "2000".  */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <netdb.h>
+#include <signal.h>
+
+#include <gsasl.h>
+
+static int
+callback (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop)
+{
+  int rc = GSASL_NO_CALLBACK;
+
+  switch (prop)
+    {
+    case GSASL_PASSWORD:
+      gsasl_property_set (sctx, prop, "sesam");
+      rc = GSASL_OK;
+      break;
+
+    default:
+      /* You may want to log (at debug verbosity level) that an
+         unknown property was requested here, possibly after filtering
+         known rejected property requests. */
+      break;
+    }
+
+  return rc;
+}
+
+static ssize_t
+gettrimline (char **line, size_t * n, FILE * fh)
+{
+  ssize_t s = getline (line, n, fh);
+
+  if (s >= 2)
+    {
+      if ((*line)[strlen (*line) - 1] == '\n')
+       (*line)[strlen (*line) - 1] = '\0';
+      if ((*line)[strlen (*line) - 1] == '\r')
+       (*line)[strlen (*line) - 1] = '\0';
+    }
+
+  printf ("C: %s\n", *line);
+
+  return s;
+}
+
+#define print(fh, ...)                                                 \
+  printf ("S: "), printf (__VA_ARGS__), fprintf (fh, __VA_ARGS__)
+
+static void
+server_auth (FILE * fh, Gsasl_session * session)
+{
+  char *line = NULL;
+  size_t n = 0;
+  char *p;
+  int rc;
+
+  /* The ordering and the type of checks in the following loop has to
+     be adapted for each protocol depending on its SASL properties.
+     SMTP is a "server-first" SASL protocol.  This implementation do
+     not support piggy-backing of the initial client challenge nor
+     piggy-backing of the terminating server response.  See RFC 2554
+     and RFC 4422 for terminology.  That profile results in the
+     following loop structure.  Ask on the help-gsasl list if you are
+     uncertain.  */
+  do
+    {
+      rc = gsasl_step64 (session, line, &p);
+      if (rc == GSASL_NEEDS_MORE || (rc == GSASL_OK && p && *p))
+       {
+         print (fh, "334 %s\n", p);
+         gsasl_free (p);
+
+         if (gettrimline (&line, &n, fh) < 0)
+           {
+             print (fh, "221 localhost getline failure\n");
+             goto done;
+           }
+       }
+    }
+  while (rc == GSASL_NEEDS_MORE);
+
+  if (rc != GSASL_OK)
+    {
+      print (fh, "535 gsasl_step64 (%d): %s\n", rc, gsasl_strerror (rc));
+      goto done;
+    }
+
+  print (fh, "235 OK\n");
+
+done:
+  free (line);
+}
+
+static void
+smtp (FILE * fh, Gsasl * ctx)
+{
+  char *line = NULL;
+  size_t n = 0;
+  int rc;
+
+  print (fh, "220 localhost ESMTP GNU SASL smtp-server\n");
+
+  while (gettrimline (&line, &n, fh) >= 0)
+    {
+      if (strncmp (line, "EHLO ", 5) == 0 || strncmp (line, "ehlo ", 5) == 0)
+       {
+         char *mechlist;
+
+         rc = gsasl_server_mechlist (ctx, &mechlist);
+         if (rc != GSASL_OK)
+           {
+             print (fh, "221 localhost gsasl_server_mechlist (%d): %s\n",
+                    rc, gsasl_strerror (rc));
+             goto done;
+           }
+
+         print (fh, "250-localhost\n");
+         print (fh, "250 AUTH %s\n", mechlist);
+
+         gsasl_free (mechlist);
+       }
+      else if (strncmp (line, "AUTH ", 5) == 0
+              || strncmp (line, "auth ", 5) == 0)
+       {
+         Gsasl_session *session = NULL;
+
+         if ((rc = gsasl_server_start (ctx, line + 5, &session)) != GSASL_OK)
+           {
+             print (fh, "221 localhost gsasl_server_start (%d): %s\n",
+                    rc, gsasl_strerror (rc));
+             goto done;
+           }
+
+         server_auth (fh, session);
+
+         gsasl_finish (session);
+       }
+      else if (strncmp (line, "QUIT", 4) == 0
+              || strncmp (line, "quit", 4) == 0)
+       {
+         print (fh, "221 localhost QUIT\n");
+         goto done;
+       }
+      else
+       print (fh, "500 unrecognized command\n");
+    }
+
+  print (fh, "221 localhost getline failure\n");
+
+done:
+  free (line);
+}
+
+int
+main (int argc, char *argv[])
+{
+  const char *service = argc > 1 ? argv[1] : "2000";
+  volatile int run = 1;
+  struct addrinfo hints, *addrs;
+  int sockfd;
+  int rc;
+  int yes = 1;
+  Gsasl *ctx;
+
+  rc = gsasl_init (&ctx);
+  if (rc < 0)
+    {
+      printf ("gsasl_init (%d): %s\n", rc, gsasl_strerror (rc));
+      exit (EXIT_FAILURE);
+    }
+
+  printf ("smtp-server [gsasl header %s library %s]\n",
+         GSASL_VERSION, gsasl_check_version (NULL));
+
+  gsasl_callback_set (ctx, callback);
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+  hints.ai_socktype = SOCK_STREAM;
+
+  rc = getaddrinfo (NULL, service, &hints, &addrs);
+  if (rc < 0)
+    {
+      printf ("getaddrinfo: %s\n", gai_strerror (rc));
+      exit (EXIT_FAILURE);
+    }
+
+  sockfd = socket (addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
+  if (sockfd < 0)
+    {
+      perror ("socket");
+      exit (EXIT_FAILURE);
+    }
+
+  if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes)) < 0)
+    {
+      perror ("setsockopt");
+      exit (EXIT_FAILURE);
+    }
+
+  rc = bind (sockfd, addrs->ai_addr, addrs->ai_addrlen);
+  if (rc < 0)
+    {
+      perror ("bind");
+      exit (EXIT_FAILURE);
+    }
+
+  freeaddrinfo (addrs);
+
+  rc = listen (sockfd, SOMAXCONN);
+  if (rc < 0)
+    {
+      perror ("listen");
+      exit (EXIT_FAILURE);
+    }
+
+  signal (SIGPIPE, SIG_IGN);
+
+  while (run)
+    {
+      struct sockaddr from;
+      socklen_t fromlen;
+      char host[NI_MAXHOST];
+      int fd;
+      FILE *fh;
+
+      fd = accept (sockfd, &from, &fromlen);
+      if (fd < 0)
+       {
+         perror ("accept");
+         continue;
+       }
+
+      rc = getnameinfo (&from, fromlen, host, sizeof (host),
+                       NULL, 0, NI_NUMERICHOST);
+      if (rc == 0)
+       printf ("connection from %s\n", host);
+      else
+       printf ("getnameinfo: %s\n", gai_strerror (rc));
+
+      fh = fdopen (fd, "w+");
+      if (!fh)
+       {
+         perror ("fdopen");
+         close (fd);
+         continue;
+       }
+
+      smtp (fh, ctx);
+
+      fclose (fh);
+    }
+
+  close (sockfd);
+  gsasl_done (ctx);
+
+  return 0;
+}
diff --git a/src/callbacks.c b/src/callbacks.c
index cfdd942..db7c2e4 100644
--- a/src/callbacks.c
+++ b/src/callbacks.c
@@ -216,6 +216,27 @@ callback (Gsasl * ctx, Gsasl_session * sctx, 
Gsasl_property prop)
       }
       break;
 
+    case GSASL_SAML20_IDP_IDENTIFIER:
+      {
+       char *str = readutf8line ("Enter SAML authentication identifier "
+                                 "(e.g. \"http://example.org/\";): ");
+
+       gsasl_property_set (sctx, GSASL_SAML20_IDP_IDENTIFIER, str);
+
+       rc = GSASL_OK;
+      }
+      break;
+
+    case GSASL_SAML20_AUTHENTICATE_IN_BROWSER:
+      {
+       const char *url = gsasl_property_get (sctx, GSASL_SAML20_REDIRECT_URL);
+
+       printf ("Please visit this URL to authenticate:\n%s\n", url);
+
+       rc = GSASL_OK;
+      }
+      break;
+
     default:
       fprintf (stderr,
               "warning: mechanism requested unsupported property `%d'\n",
diff --git a/src/gsasl.c b/src/gsasl.c
index 1c87a86..e214c27 100644
--- a/src/gsasl.c
+++ b/src/gsasl.c
@@ -607,6 +607,7 @@ main (int argc, char *argv[])
        }
 
 #if HAVE_GNUTLS_SESSION_CHANNEL_BINDING
+      if (!args_info.no_cb_flag)
        {
          gnutls_datum cb;
 
diff --git a/src/gsasl.ggo b/src/gsasl.ggo
index b5c31ad..5ba2f93 100644
--- a/src/gsasl.ggo
+++ b/src/gsasl.ggo
@@ -27,6 +27,7 @@ option "server-mechanisms" - "Write name of supported server 
mechanisms separate
 
 section "Network options"
 option "connect" - "Connect to TCP server and negotiate on stream instead of 
stdin/stdout. PORT is the protocol service, or an integer denoting the port, 
and defaults to 143 (imap) if not specified. Also sets the --hostname default." 
string typestr="HOST[:PORT]" no
+#option "listen" - "Listen on network socket and provide authentication 
services following the supported protocols.  This implies --server and defaults 
to IMAP mode." string typestr="HOST:[PORT]" no argoptional 
default="localhost:143"
 
 section "Generic options"
 option "application-data" d "After authentication, read data from stdin and 
run it through the mechanism's security layer and print it base64 encoded to 
stdout. The default is to terminate after authentication." flag on
diff --git a/src/smtp.c b/src/smtp.c
index 61391e8..649b2c7 100644
--- a/src/smtp.c
+++ b/src/smtp.c
@@ -91,9 +91,12 @@ smtp_select_mechanism (char **mechlist)
          if (!readln (&in))
            return 0;
 
-#define GREETING "250-AUTH "
-         if (strncmp (in, GREETING, strlen (GREETING)) == 0)
-           *mechlist = in + strlen (GREETING);
+#define GREETING1 "250-AUTH "
+#define GREETING2 "250 AUTH "
+         if (strncmp (in, GREETING1, strlen (GREETING1)) == 0)
+           *mechlist = in + strlen (GREETING1);
+         else if (strncmp (in, GREETING2, strlen (GREETING2)) == 0)
+           *mechlist = in + strlen (GREETING2);
        }
       while (strncmp (in, "250 ", 4) != 0);
     }


hooks/post-receive
-- 
GNU gsasl



reply via email to

[Prev in Thread] Current Thread [Next in Thread]