Bug 596971 - Drop support for Kerberos 4
authorH.Habighorst <h.habighorst@googlemail.com>
Fri, 2 Oct 2009 00:02:20 +0000 (20:02 -0400)
committerMatthew Barnes <mbarnes@redhat.com>
Fri, 2 Oct 2009 00:02:20 +0000 (20:02 -0400)
camel/Makefile.am
camel/camel-sasl-kerberos4.c [deleted file]
camel/camel-sasl-kerberos4.h [deleted file]
camel/camel-sasl.c
camel/camel.h
configure.ac
docs/reference/camel/camel-docs.sgml
docs/reference/camel/camel-sections.txt
docs/reference/camel/tmpl/camel-sasl-kerberos4.sgml [deleted file]
docs/reference/camel/tree_index.sgml

index 5115d0e..e3d160d 100644 (file)
@@ -12,9 +12,7 @@ else
 LIBCAMEL_PLATFORM_DEP_SOURCES = \
        camel-lock-client.c \
        camel-stream-process.c
-LIBCAMEL_PROVIDER_PLATFORM_DEP_SOURCES =       \
-       camel-movemail.c                        \
-       camel-sasl-kerberos4.c
+LIBCAMEL_PROVIDER_PLATFORM_DEP_SOURCES = camel-movemail.c
 LOCK_HELPER = camel-lock-helper-1.2
 endif
 
@@ -119,7 +117,6 @@ libcamel_providerinclude_HEADERS =          \
        camel-sasl-cram-md5.h                   \
        camel-sasl-digest-md5.h                 \
        camel-sasl-gssapi.h                     \
-       camel-sasl-kerberos4.h                  \
        camel-sasl-login.h                      \
        camel-sasl-ntlm.h                       \
        camel-sasl-plain.h                      \
diff --git a/camel/camel-sasl-kerberos4.c b/camel/camel-sasl-kerberos4.c
deleted file mode 100644 (file)
index 3c18a23..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- *  Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 Lesser General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_KRB4
-
-#include <krb.h>
-/* MIT krb4 des.h #defines _. Sigh. We don't need it. #undef it here
- * so we get the gettexty _ definition later.
- */
-#undef _
-
-#include <netdb.h>
-#include <string.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-
-#include "camel-net-utils.h"
-#include "camel-sasl-kerberos4.h"
-#include "camel-service.h"
-#include "camel-string-utils.h"
-
-CamelServiceAuthType camel_sasl_kerberos4_authtype = {
-       N_("Kerberos 4"),
-
-       N_("This option will connect to the server using "
-          "Kerberos 4 authentication."),
-
-       "KERBEROS_V4",
-       FALSE
-};
-
-#define KERBEROS_V4_PROTECTION_NONE      1
-#define KERBEROS_V4_PROTECTION_INTEGRITY 2
-#define KERBEROS_V4_PROTECTION_PRIVACY   4
-
-static CamelSaslClass *parent_class = NULL;
-
-/* Returns the class for a CamelSaslKerberos4 */
-#define CSK4_CLASS(so) CAMEL_SASL_KERBEROS4_CLASS (CAMEL_OBJECT_GET_CLASS (so))
-
-static GByteArray *krb4_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex);
-
-struct _CamelSaslKerberos4Private {
-       gint state;
-
-       guint32 nonce_n;
-       guint32 nonce_h;
-
-       des_cblock session;
-       des_key_schedule schedule;
-};
-
-static void
-camel_sasl_kerberos4_class_init (CamelSaslKerberos4Class *camel_sasl_kerberos4_class)
-{
-       CamelSaslClass *camel_sasl_class = CAMEL_SASL_CLASS (camel_sasl_kerberos4_class);
-
-       parent_class = CAMEL_SASL_CLASS (camel_type_get_global_classfuncs (camel_sasl_get_type ()));
-
-       /* virtual method overload */
-       camel_sasl_class->challenge = krb4_challenge;
-}
-
-static void
-camel_sasl_kerberos4_init (gpointer object, gpointer klass)
-{
-       CamelSaslKerberos4 *sasl_krb4 = CAMEL_SASL_KERBEROS4 (object);
-
-       sasl_krb4->priv = g_new0 (struct _CamelSaslKerberos4Private, 1);
-}
-
-static void
-camel_sasl_kerberos4_finalize (CamelObject *object)
-{
-       CamelSaslKerberos4 *sasl = CAMEL_SASL_KERBEROS4 (object);
-
-       if (sasl->priv) {
-               memset (sasl->priv, 0, sizeof (sasl->priv));
-               g_free (sasl->priv);
-       }
-}
-
-CamelType
-camel_sasl_kerberos4_get_type (void)
-{
-       static CamelType type = CAMEL_INVALID_TYPE;
-
-       if (type == CAMEL_INVALID_TYPE) {
-               type = camel_type_register (camel_sasl_get_type (),
-                                           "CamelSaslKerberos4",
-                                           sizeof (CamelSaslKerberos4),
-                                           sizeof (CamelSaslKerberos4Class),
-                                           (CamelObjectClassInitFunc) camel_sasl_kerberos4_class_init,
-                                           NULL,
-                                           (CamelObjectInitFunc) camel_sasl_kerberos4_init,
-                                           (CamelObjectFinalizeFunc) camel_sasl_kerberos4_finalize);
-       }
-
-       return type;
-}
-
-static GByteArray *
-krb4_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex)
-{
-       struct _CamelSaslKerberos4Private *priv = CAMEL_SASL_KERBEROS4 (sasl)->priv;
-       GByteArray *ret = NULL;
-       gchar *inst, *realm, *username;
-       struct hostent *h;
-       gint status, len;
-       KTEXT_ST authenticator;
-       CREDENTIALS credentials;
-       guint32 plus1;
-       struct addrinfo *ai, hints;
-
-       /* Need to wait for the server */
-       if (!token)
-               return NULL;
-
-       switch (priv->state) {
-       case 0:
-               if (token->len != 4)
-                       goto lose;
-
-               memcpy (&priv->nonce_n, token->data, 4);
-               priv->nonce_h = ntohl (priv->nonce_n);
-
-               memset(&hints, 0, sizeof(hints));
-               hints.ai_flags = AI_CANONNAME;
-               ai = camel_getaddrinfo(sasl->service->url->host?sasl->service->url->host:"localhost", NULL, &hints, ex);
-               if (ai == NULL)
-                       goto lose;
-
-               /* Our response is an authenticator including that number. */
-               inst = g_strndup (ai->ai_canonname, strcspn (ai->ai_canonname, "."));
-               camel_strdown (inst);
-               realm = g_strdup (krb_realmofhost (ai->ai_canonname));
-               camel_freeaddrinfo(ai);
-               status = krb_mk_req (&authenticator, sasl->service_name, inst, realm, priv->nonce_h);
-               if (status == KSUCCESS) {
-                       status = krb_get_cred (sasl->service_name, inst, realm, &credentials);
-                       memcpy (priv->session, credentials.session, sizeof (priv->session));
-                       memset (&credentials, 0, sizeof (credentials));
-               }
-               g_free (inst);
-               g_free (realm);
-
-               if (status != KSUCCESS) {
-                       camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
-                                             _("Could not get Kerberos ticket:\n%s"),
-                                             krb_err_txt[status]);
-                       goto lose;
-               }
-               des_key_sched (&priv->session, priv->schedule);
-
-               ret = g_byte_array_new ();
-               g_byte_array_append (ret, (const guint8 *)authenticator.dat, authenticator.length);
-               break;
-
-       case 1:
-               if (token->len != 8)
-                       goto lose;
-
-               /* This one is encrypted. */
-               des_ecb_encrypt ((des_cblock *)token->data, (des_cblock *)token->data, priv->schedule, 0);
-
-               /* Check that the returned value is the original nonce plus one. */
-               memcpy (&plus1, token->data, 4);
-               if (ntohl (plus1) != priv->nonce_h + 1)
-                       goto lose;
-
-               /* "the fifth octet contain[s] a bit-mask specifying the
-                * protection mechanisms supported by the server"
-                */
-               if (!(token->data[4] & KERBEROS_V4_PROTECTION_NONE)) {
-                       g_warning ("Server does not support 'no protection' :-(");
-                       goto lose;
-               }
-
-               username = sasl->service->url->user;
-               len = strlen (username) + 9;
-               len += 8 - len % 8;
-               ret = g_byte_array_new ();
-               g_byte_array_set_size (ret, len);
-               memset (ret->data, 0, len);
-               memcpy (ret->data, &priv->nonce_n, 4);
-               ret->data[4] = KERBEROS_V4_PROTECTION_NONE;
-               ret->data[5] = ret->data[6] = ret->data[7] = 0;
-               strcpy (ret->data + 8, username);
-
-               des_pcbc_encrypt ((gpointer)ret->data, (gpointer)ret->data, len,
-                                 priv->schedule, &priv->session, 1);
-               memset (&priv->session, 0, sizeof (priv->session));
-
-               sasl->authenticated = TRUE;
-               break;
-       }
-
-       priv->state++;
-       return ret;
-
- lose:
-       memset (&priv->session, 0, sizeof (priv->session));
-
-       if (!camel_exception_is_set (ex)) {
-               camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
-                                    _("Bad authentication response from server."));
-       }
-       return NULL;
-}
-
-#endif /* HAVE_KRB4 */
diff --git a/camel/camel-sasl-kerberos4.h b/camel/camel-sasl-kerberos4.h
deleted file mode 100644 (file)
index 29e4eb7..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- *  Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 Lesser General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef CAMEL_SASL_KERBEROS4_H
-#define CAMEL_SASL_KERBEROS4_H
-
-#include <sys/types.h>
-#include <camel/camel-sasl.h>
-
-#define CAMEL_SASL_KERBEROS4_TYPE     (camel_sasl_kerberos4_get_type ())
-#define CAMEL_SASL_KERBEROS4(obj)     (CAMEL_CHECK_CAST((obj), CAMEL_SASL_KERBEROS4_TYPE, CamelSaslKerberos4))
-#define CAMEL_SASL_KERBEROS4_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SASL_KERBEROS4_TYPE, CamelSaslKerberos4Class))
-#define CAMEL_IS_SASL_KERBEROS4(o)    (CAMEL_CHECK_TYPE((o), CAMEL_SASL_KERBEROS4_TYPE))
-
-G_BEGIN_DECLS
-
-typedef struct _CamelSaslKerberos4 {
-       CamelSasl parent_object;
-       struct _CamelSaslKerberos4Private *priv;
-
-} CamelSaslKerberos4;
-
-typedef struct _CamelSaslKerberos4Class {
-       CamelSaslClass parent_class;
-
-} CamelSaslKerberos4Class;
-
-/* Standard Camel function */
-CamelType camel_sasl_kerberos4_get_type (void);
-
-extern CamelServiceAuthType camel_sasl_kerberos4_authtype;
-
-G_END_DECLS
-
-#endif /* CAMEL_SASL_KERBEROS4_H */
index 5733b97..908cb47 100644 (file)
@@ -30,7 +30,6 @@
 #include "camel-sasl-cram-md5.h"
 #include "camel-sasl-digest-md5.h"
 #include "camel-sasl-gssapi.h"
-#include "camel-sasl-kerberos4.h"
 #include "camel-sasl-login.h"
 #include "camel-sasl-ntlm.h"
 #include "camel-sasl-plain.h"
@@ -201,10 +200,6 @@ camel_sasl_new (const gchar *service_name, const gchar *mechanism, CamelService
        else if (!strcmp (mechanism, "GSSAPI"))
                sasl = (CamelSasl *) camel_object_new (CAMEL_SASL_GSSAPI_TYPE);
 #endif
-#ifdef HAVE_KRB4
-       else if (!strcmp (mechanism, "KERBEROS_V4"))
-               sasl = (CamelSasl *) camel_object_new (CAMEL_SASL_KERBEROS4_TYPE);
-#endif
        else if (!strcmp (mechanism, "PLAIN"))
                sasl = (CamelSasl *) camel_object_new (CAMEL_SASL_PLAIN_TYPE);
        else if (!strcmp (mechanism, "LOGIN"))
@@ -241,9 +236,6 @@ camel_sasl_authtype_list (gboolean include_plain)
 #ifdef HAVE_KRB5
        types = g_list_prepend (types, &camel_sasl_gssapi_authtype);
 #endif
-#ifdef HAVE_KRB4
-       types = g_list_prepend (types, &camel_sasl_kerberos4_authtype);
-#endif
        types = g_list_prepend (types, &camel_sasl_ntlm_authtype);
        if (include_plain)
                types = g_list_prepend (types, &camel_sasl_plain_authtype);
@@ -269,10 +261,6 @@ camel_sasl_authtype (const gchar *mechanism)
        else if (!strcmp (mechanism, "GSSAPI"))
                return &camel_sasl_gssapi_authtype;
 #endif
-#ifdef HAVE_KRB4
-       else if (!strcmp (mechanism, "KERBEROS_V4"))
-               return &camel_sasl_kerberos4_authtype;
-#endif
        else if (!strcmp (mechanism, "PLAIN"))
                return &camel_sasl_plain_authtype;
        else if (!strcmp (mechanism, "LOGIN"))
index 1965b7d..776b274 100644 (file)
 #include <camel/camel-sasl-cram-md5.h>
 #include <camel/camel-sasl-digest-md5.h>
 #include <camel/camel-sasl-gssapi.h>
-#include <camel/camel-sasl-kerberos4.h>
 #include <camel/camel-sasl-login.h>
 #include <camel/camel-sasl-ntlm.h>
 #include <camel/camel-sasl-plain.h>
index 37233cb..b646df5 100644 (file)
@@ -1153,21 +1153,6 @@ AC_ARG_WITH([krb5-includes],
        [Location of Kerberos 5 headers]),
        [with_krb5_includes="$withval"], [with_krb5_includes=""])
 
-AC_ARG_WITH([krb4],
-       AS_HELP_STRING([--with-krb4=PATH],
-       [Location of Kerberos 4 install dir]),
-       [with_krb4="$withval"], [with_krb4="no"])
-
-AC_ARG_WITH([krb4-libs],
-       AS_HELP_STRING([--with-krb4-libs=DIR],
-       [Location of Kerberos 4 libraries]),
-       [with_krb4_libs="$withval"], [with_krb4_libs="$with_krb4/lib"])
-
-AC_ARG_WITH([krb4-includes],
-       AS_HELP_STRING([--with-krb4-includes=DIR],
-       [Location of Kerberos 4 headers]),
-       [with_krb4_includes="$withval"], [with_krb4_includes=""])
-
 dnl ******************************
 dnl Kerberos 5
 dnl ******************************
@@ -1250,76 +1235,8 @@ AC_CHECK_HEADER([com_err.h],
                #endif
        ]])
 
-dnl ******************************
-dnl Kerberos 4
-dnl ******************************
-msg_krb4="no"
-if test "x${with_krb4}" != "xno"; then
-       LIBS_save="$LIBS"
-       AC_CACHE_CHECK([for Kerberos 4], [ac_cv_lib_kerberos4],
-       [
-               ac_cv_lib_kerberos4="no"
-
-               mitcompatlibs="-lkrb4 -ldes425 -lkrb5 -lk5crypto -lcom_err"
-               dnl Look for MIT krb5 compat krb4
-               LIBS="$LIBS_save -L$with_krb4_libs $mitcompatlibs"
-               AC_LINK_IFELSE([AC_LANG_CALL([], [krb_mk_req])],
-               [ac_cv_lib_kerberos4="$mitcompatlibs"])
-
-               if test "$ac_cv_lib_kerberos4" = "no"; then
-                       dnl Look for KTH krb4
-                       LIBS="$LIBS_save -L$with_krb4_libs -lkrb -lcrypto -lcom_err -lroken"
-                       AC_LINK_IFELSE([AC_LANG_CALL([], [krb_mk_req])],
-                       [ac_cv_lib_kerberos4="-lkrb -lcrypto -lcom_err -lroken"])
-               fi
-               if test "$ac_cv_lib_kerberos4" = "no"; then
-                       dnl Look for old MIT krb4
-                       LIBS="$LIBS_save -L$with_krb4_libs -lkrb"
-                       AC_LINK_IFELSE([AC_LANG_CALL([], [krb_mk_req])],
-                       [ac_cv_lib_kerberos4="-lkrb"],
-                       [
-                               LIBS="$LIBS -ldes"
-                               AC_LINK_IFELSE([AC_LANG_CALL([], [krb_mk_req])],
-                               [ac_cv_lib_kerberos4="-lkrb -ldes"])
-                       ])
-               fi
-       ])
-       LIBS="$LIBS_save"
-       if test "$ac_cv_lib_kerberos4" != "no"; then
-               AC_DEFINE(HAVE_KRB4,1,[Define if you have Krb4])
-               msg_krb4="yes"
-
-               if test -z "$with_krb4_includes"; then
-                       if test -f "$with_krb4/include/krb.h" -o -f "$with_krb4/include/port-sockets.h"; then
-                               KRB4_CFLAGS="-I$with_krb4/include"
-                       fi
-                       if test -d "$with_krb4/include/kerberosIV"; then
-                               KRB4_CFLAGS="$KRB4_CFLAGS -I$with_krb4/include/kerberosIV"
-                       fi
-               else
-                       KRB4_CFLAGS="-I$with_krb4_includes"
-               fi
-               KRB4_LIBS="-L$with_krb4_libs $ac_cv_lib_kerberos4"
-
-               CFLAGS_save="$CFLAGS"
-               CFLAGS="$CFLAGS $KRB4_CFLAGS"
-               AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-                       [[      #include "krb.h"
-                               int krb_sendauth;
-                       ]],
-                       [[      return 0        ]]
-                       )],[AC_DEFINE(NEED_KRB_SENDAUTH_PROTO,1,[Need krb_sendauth proto])],[])
-               CFLAGS="$CFLAGS_save"
-       fi
-else
-       AC_MSG_CHECKING([for Kerberos 4])
-       AC_MSG_RESULT([${with_krb4}])
-fi
-
 AC_SUBST(KRB5_CFLAGS)
 AC_SUBST(KRB5_LIBS)
-AC_SUBST(KRB4_CFLAGS)
-AC_SUBST(KRB4_LIBS)
 
 dnl ******************************
 dnl Purify support
@@ -1824,7 +1741,7 @@ echo "
        Mail Directory:         $system_mail_dir, $system_mail_perm
        LDAP support:           $msg_ldap
        NNTP support:           $msg_nntp
-       Kerberos 4/5:           $msg_krb4/$msg_krb5
+       Kerberos 5:             $msg_krb5
        Gnome Keyring:          $enable_gnome_keyring/$with_gnome_keyring
        SSL support:            $msg_ssl
        SMIME support:          $msg_smime
index b3de15d..ca14144 100644 (file)
@@ -81,7 +81,6 @@
 <!ENTITY CamelSASLCRAMMD5 SYSTEM "xml/camel-sasl-cram-md5.xml">
 <!ENTITY CamelSASLDigestMD5 SYSTEM "xml/camel-sasl-digest-md5.xml">
 <!ENTITY CamelSASLGSSAPI SYSTEM "xml/camel-sasl-gssapi.xml">
-<!ENTITY CamelSASLKerberos4 SYSTEM "xml/camel-sasl-kerberos4.xml">
 <!ENTITY CamelSASLLogin SYSTEM "xml/camel-sasl-login.xml">
 <!ENTITY CamelSASLNTLM SYSTEM "xml/camel-sasl-ntlm.xml">
 <!ENTITY CamelSASLPlain SYSTEM "xml/camel-sasl-plain.xml">
       &CamelSASLCRAMMD5;
       &CamelSASLDigestMD5;
       &CamelSASLGSSAPI;
-      &CamelSASLKerberos4;
       &CamelSASLLogin;
       &CamelSASLNTLM;
       &CamelSASLPlain;
index 1a7f09d..e104d5b 100644 (file)
@@ -1509,21 +1509,6 @@ camel_sasl_gssapi_get_type
 </SECTION>
 
 <SECTION>
-<FILE>camel-sasl-kerberos4</FILE>
-<TITLE>CamelSaslKerberos4</TITLE>
-CamelSaslKerberos4
-camel_sasl_kerberos4_authtype
-<SUBSECTION Standard>
-CAMEL_SASL_KERBEROS4
-CAMEL_IS_SASL_KERBEROS4
-CAMEL_SASL_KERBEROS4_TYPE
-CAMEL_SASL_KERBEROS4_CLASS
-CamelSaslKerberos4Class
-<SUBSECTION Private>
-camel_sasl_kerberos4_get_type
-</SECTION>
-
-<SECTION>
 <FILE>camel-sasl-login</FILE>
 <TITLE>CamelSaslLogin</TITLE>
 CamelSaslLogin
diff --git a/docs/reference/camel/tmpl/camel-sasl-kerberos4.sgml b/docs/reference/camel/tmpl/camel-sasl-kerberos4.sgml
deleted file mode 100644 (file)
index a219dd2..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- ##### SECTION Title ##### -->
-CamelSaslKerberos4
-
-<!-- ##### SECTION Short_Description ##### -->
-
-
-<!-- ##### SECTION Long_Description ##### -->
-<para>
-
-</para>
-
-<!-- ##### SECTION See_Also ##### -->
-<para>
-
-</para>
-
-<!-- ##### SECTION Stability_Level ##### -->
-
-
-<!-- ##### STRUCT CamelSaslKerberos4 ##### -->
-<para>
-
-</para>
-
-@parent_object: 
-@priv: 
-
-<!-- ##### VARIABLE camel_sasl_kerberos4_authtype ##### -->
-<para>
-
-</para>
-
-
index e0f6fab..dbb19a5 100644 (file)
@@ -40,7 +40,6 @@
             <link linkend="CamelSaslCramMd5">CamelSaslCramMd5</link>
             <link linkend="CamelSaslDigestMd5">CamelSaslDigestMd5</link>
             <link linkend="CamelSaslGssapi">CamelSaslGssapi</link>
-            <link linkend="CamelSaslKerberos4">CamelSaslKerberos4</link>
             <link linkend="CamelSaslLogin">CamelSaslLogin</link>
             <link linkend="CamelSaslNTLM">CamelSaslNTLM</link>
             <link linkend="CamelSaslPlain">CamelSaslPlain</link>