00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 }