gsasl  1.8.0
xstart.c
Go to the documentation of this file.
00001 /* xstart.c --- Start libgsasl session.
00002  * Copyright (C) 2002-2012 Simon Josefsson
00003  *
00004  * This file is part of GNU SASL Library.
00005  *
00006  * GNU SASL Library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public License
00008  * as published by the Free Software Foundation; either version 2.1 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * GNU SASL Library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License License along with GNU SASL Library; if not, write to the
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "internal.h"
00024 
00025 static Gsasl_mechanism *
00026 find_mechanism (const char *mech, size_t n_mechs, Gsasl_mechanism * mechs)
00027 {
00028   size_t i;
00029 
00030   if (mech == NULL)
00031     return NULL;
00032 
00033   for (i = 0; i < n_mechs; i++)
00034     if (strcmp (mech, mechs[i].name) == 0)
00035       return &mechs[i];
00036 
00037   return NULL;
00038 }
00039 
00040 static int
00041 setup (Gsasl * ctx,
00042        const char *mech,
00043        Gsasl_session * sctx,
00044        size_t n_mechs, Gsasl_mechanism * mechs, int clientp)
00045 {
00046   Gsasl_mechanism *mechptr = NULL;
00047   int res;
00048 
00049   mechptr = find_mechanism (mech, n_mechs, mechs);
00050   if (mechptr == NULL)
00051     return GSASL_UNKNOWN_MECHANISM;
00052 
00053   sctx->ctx = ctx;
00054   sctx->mech = mechptr;
00055   sctx->clientp = clientp;
00056 
00057   if (clientp)
00058     {
00059       if (sctx->mech->client.start)
00060         res = sctx->mech->client.start (sctx, &sctx->mech_data);
00061       else if (!sctx->mech->client.step)
00062         res = GSASL_NO_CLIENT_CODE;
00063       else
00064         res = GSASL_OK;
00065     }
00066   else
00067     {
00068       if (sctx->mech->server.start)
00069         res = sctx->mech->server.start (sctx, &sctx->mech_data);
00070       else if (!sctx->mech->server.step)
00071         res = GSASL_NO_SERVER_CODE;
00072       else
00073         res = GSASL_OK;
00074     }
00075   if (res != GSASL_OK)
00076     return res;
00077 
00078   return GSASL_OK;
00079 }
00080 
00081 static int
00082 start (Gsasl * ctx,
00083        const char *mech,
00084        Gsasl_session ** sctx,
00085        size_t n_mechs, Gsasl_mechanism * mechs, int clientp)
00086 {
00087   Gsasl_session *out;
00088   int res;
00089 
00090   out = calloc (1, sizeof (*out));
00091   if (out == NULL)
00092     return GSASL_MALLOC_ERROR;
00093 
00094   res = setup (ctx, mech, out, n_mechs, mechs, clientp);
00095   if (res != GSASL_OK)
00096     {
00097       gsasl_finish (out);
00098       return res;
00099     }
00100 
00101   *sctx = out;
00102 
00103   return GSASL_OK;
00104 }
00105 
00118 int
00119 gsasl_client_start (Gsasl * ctx, const char *mech, Gsasl_session ** sctx)
00120 {
00121   return start (ctx, mech, sctx, ctx->n_client_mechs, ctx->client_mechs, 1);
00122 }
00123 
00136 int
00137 gsasl_server_start (Gsasl * ctx, const char *mech, Gsasl_session ** sctx)
00138 {
00139   return start (ctx, mech, sctx, ctx->n_server_mechs, ctx->server_mechs, 0);
00140 }