⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sasl.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 2 页
字号:
        if(out != NULL) free(out);        _sx_nad_write(s, _sx_sasl_response(s, buf, buflen), 0);        if(buf != NULL) free(buf);        return;    }    if(out != NULL) free(out);    /* its over */    _sx_debug(ZONE, "sasl handshake aborted: (%d)", ret);    _sx_nad_write(s, _sx_sasl_abort(s), 0);}/** main nad processor */static int _sx_sasl_process(sx_t s, sx_plugin_t p, nad_t nad) {    scod_t sd = (scod_t) s->plugin_data[p->index];    int attr;    char mech[128];    sx_error_t sxe;    int flags;    char *ns = NULL, *to = NULL, *from = NULL, *version = NULL;    /* only want sasl packets */    if(NAD_ENS(nad, 0) < 0 || NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_SASL) || strncmp(NAD_NURI(nad, NAD_ENS(nad, 0)), uri_SASL, strlen(uri_SASL)) != 0)        return 1;    /* quietly drop it if sasl is disabled, or if not ready */    if(s->state != state_STREAM) {        _sx_debug(ZONE, "not correct state for sasl, ignoring");        nad_free(nad);        return 0;    }    /* packets from the client */    if(s->type == type_SERVER) {        if(!(s->flags & SX_SASL_OFFER)) {            _sx_debug(ZONE, "they tried to do sasl, but we never offered it, ignoring");            nad_free(nad);            return 0;        }#ifdef HAVE_SSL        if((s->flags & SX_SSL_STARTTLS_REQUIRE) && s->ssf == 0) {            _sx_debug(ZONE, "they tried to do sasl, but they have to do starttls first, ignoring");            nad_free(nad);            return 0;        }#endif        /* auth */        if(NAD_ENAME_L(nad, 0) == 4 && strncmp("auth", NAD_ENAME(nad, 0), NAD_ENAME_L(nad, 0)) == 0) {            /* require mechanism */            if((attr = nad_find_attr(nad, 0, -1, "mechanism", NULL)) < 0) {                _sx_nad_write(s, _sx_sasl_failure(s, _sasl_err_INVALID_MECHANISM), 0);                nad_free(nad);                return 0;            }            /* extract */            snprintf(mech, 127, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));            /* go */            _sx_sasl_client_process(s, p, sd, mech, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0));            nad_free(nad);            return 0;        }        /* response */        else if(NAD_ENAME_L(nad, 0) == 8 && strncmp("response", NAD_ENAME(nad, 0), NAD_ENAME_L(nad, 0)) == 0) {            /* process it */            _sx_sasl_client_process(s, p, sd, NULL, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0));            nad_free(nad);            return 0;        }        /* abort */        else if(NAD_ENAME_L(nad, 0) == 5 && strncmp("abort", NAD_ENAME(nad, 0), NAD_ENAME_L(nad, 0)) == 0) {            _sx_debug(ZONE, "sasl handshake aborted");            _sx_nad_write(s, _sx_sasl_failure(s, _sasl_err_ABORTED), 0);            nad_free(nad);            return 0;        }    }        /* packets from the server */    else if(s->type == type_CLIENT) {        if(sd == NULL) {            _sx_debug(ZONE, "got sasl client packets, but they never started sasl, ignoring");            nad_free(nad);            return 0;        }        /* challenge */        if(NAD_ENAME_L(nad, 0) == 9 && strncmp("challenge", NAD_ENAME(nad, 0), NAD_ENAME_L(nad, 0)) == 0) {            /* process it */            _sx_sasl_server_process(s, p, sd, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0));            nad_free(nad);            return 0;        }        /* success */        else if(NAD_ENAME_L(nad, 0) == 7 && strncmp("success", NAD_ENAME(nad, 0), NAD_ENAME_L(nad, 0)) == 0) {            _sx_debug(ZONE, "sasl handshake completed, resetting");            nad_free(nad);            /* save interesting bits */            flags = s->flags;            if(s->ns != NULL) ns = strdup(s->ns);            if(s->req_to != NULL) to = strdup(s->req_to);            if(s->req_from != NULL) from = strdup(s->req_from);            if(s->req_version != NULL) version = strdup(s->req_version);            /* reset state */            _sx_reset(s);            _sx_debug(ZONE, "restarting stream with sasl layer established");            /* second time round */            sx_client_init(s, flags, ns, to, from, version);            /* free bits */            if(ns != NULL) free(ns);            if(to != NULL) free(to);            if(from != NULL) free(from);            if(version != NULL) free(version);            return 0;        }        /* failure */        else if(NAD_ENAME_L(nad, 0) == 7 && strncmp("failure", NAD_ENAME(nad, 0), NAD_ENAME_L(nad, 0)) == 0) {            /* fire the error */            _sx_gen_error(sxe, SX_ERR_AUTH, "Authentication failed", NULL);            _sx_event(s, event_ERROR, (void *) &sxe);            /* cleanup */            scod_free(sd);            s->plugin_data[p->index] = NULL;            nad_free(nad);            return 0;        }    }    /* invalid sasl command, quietly drop it */    _sx_debug(ZONE, "unknown sasl command '%.*s', ignoring", NAD_ENAME_L(nad, 0), NAD_ENAME(nad, 0));    nad_free(nad);    return 0;}/** cleanup */static void _sx_sasl_free(sx_t s, sx_plugin_t p) {    scod_t sd = (scod_t) s->plugin_data[p->index];    if(sd == NULL)        return;    _sx_debug(ZONE, "cleaning up conn state");    scod_free(sd);    s->plugin_data[p->index] = NULL;}static int _sx_sasl_scod_callback(scod_t sd, int cb, void *arg, void **res, void *cbarg) {    _sx_sasl_t ctx = (_sx_sasl_t) cbarg;    xht realms;    switch(cb) {        case sd_cb_DIGEST_MD5_CHOOSE_REALM:            realms = (xht) arg;            if(xhash_iter_first(realms))                xhash_iter_get(realms, (const char **) res, NULL);            else                *res = NULL;            break;        case sd_cb_GET_PASS:            assert((int) ctx->cb);            return (ctx->cb)(sx_sasl_cb_GET_PASS, arg, res, sd, ctx->cbarg);        case sd_cb_CHECK_PASS:            assert((int) ctx->cb);            return (ctx->cb)(sx_sasl_cb_CHECK_PASS, arg, res, sd, ctx->cbarg);        case sd_cb_CHECK_AUTHZID:            assert((int) ctx->cb);            return (ctx->cb)(sx_sasl_cb_CHECK_AUTHZID, arg, res, sd, ctx->cbarg);        case sd_cb_ANONYMOUS_GEN_AUTHZID:            assert((int) ctx->cb);            return (ctx->cb)(sx_sasl_cb_GEN_AUTHZID, arg, res, sd, ctx->cbarg);        default:            break;    }    return 0;}static void _sx_sasl_unload(sx_plugin_t p) {    free(p->private);}/** args: realm callback, cb arg, scod flags */int sx_sasl_init(sx_env_t env, sx_plugin_t p, va_list args) {    sx_sasl_callback_t cb;    void *cbarg;    int flags;    _sx_sasl_t ctx;    _sx_debug(ZONE, "initialising sasl plugin");    cb = va_arg(args, sx_sasl_callback_t);    cbarg = va_arg(args, void *);    flags = va_arg(args, int);    ctx = (_sx_sasl_t) malloc(sizeof(struct _sx_sasl_st));    memset(ctx, 0, sizeof(struct _sx_sasl_st));    ctx->cb = cb;    ctx->cbarg = cbarg;    ctx->flags = flags;    ctx->scod_ctx = scod_ctx_new(_sx_sasl_scod_callback, ctx);    if(ctx->scod_ctx == NULL) {        _sx_debug(ZONE, "couldn't create scod context, disabling");        free(ctx);        return 1;    }    _sx_debug(ZONE, "sasl context initialised");    p->private = (void *) ctx;    p->unload = _sx_sasl_unload;    p->stream = _sx_sasl_stream;    p->features = _sx_sasl_features;    p->process = _sx_sasl_process;    p->free = _sx_sasl_free;    return 0;}/** kick off the auth handshake */int sx_sasl_auth(sx_plugin_t p, sx_t s, char *mech, char *user, char *pass, char *authzid) {    _sx_sasl_t ctx = (_sx_sasl_t) p->private;    scod_t sd;    char *buf, *out;    int ret, buflen, outlen, ns;    nad_t nad;    assert((int) p);    assert((int) s);    assert((int) mech);    assert((int) user);    assert((int) pass);    if(s->type != type_CLIENT || s->state != state_STREAM) {        _sx_debug(ZONE, "need client in stream state for sasl auth");        return 1;     }        /* startup */    sd = scod_new(ctx->scod_ctx, sd_type_CLIENT);    if(sd == NULL) {        _sx_debug(ZONE, "couldn't create scod instance, not authing");        return 1;    }    /* handshake start */    ret = scod_client_start(sd, mech, authzid, user, pass, &out, &outlen);    if(ret != sd_SUCCESS && ret != sd_CONTINUE) {        _sx_debug(ZONE, "scod_client_start failed (%d), not authing", ret);        if(out != NULL) free(out);                scod_free(sd);        return 1;    }    /* save userdata */    s->plugin_data[p->index] = (void *) sd;    /* in progress */    _sx_debug(ZONE, "sending auth request to server, mech '%s': %.*s", mech, outlen, out);    /* encode the challenge */    _sx_sasl_encode(out, outlen, &buf, &buflen);    free(out);    /* build the nad */    nad = nad_new(s->nad_cache);    ns = nad_add_namespace(nad, uri_SASL, NULL);    nad_append_elem(nad, ns, "auth", 0);    nad_append_attr(nad, -1, "mechanism", mech);    if(buf != NULL) {        nad_append_cdata(nad, buf, buflen, 1);        free(buf);    }    /* its away */    sx_nad_write(s, nad);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -