コード例 #1
0
ファイル: scs.c プロジェクト: babongo/libscs
/* Split SCS atoms.  Also save a copy of the base-64 encoded tag since 
 * create_tag() will overwrite ats->b64_tag with the newly computed one, 
 * and we still need it in tags_match() for comparison/validation. */
static int split_cookie (scs_t *ctx, const char *cookie, 
        char tag[BASE64_LENGTH(SCS_TAG_MAX) + 1])
{
    size_t n;
    char cp[SCS_COOKIE_MAX] = { '\0' }, *pcp = &cp[0];
    enum { DATA = 0, TSTAMP, TID, IV, TAG, NUM_ATOMS };
    char *atoms[NUM_ATOMS + 1], **ap;

    /* Make a copy that we can freely clobber with strsep(). */
    if (strlcpy(cp, cookie, sizeof cp) >= sizeof cp)
    {
        scs_set_error(ctx, SCS_ERR_FRAMING, "SCS_COOKIE_MAX exceeded");
        return -1;
    }

    /* Put the expected 5 atoms on corresponding atoms[] slots, also doing
     * trivial integrity check (i.e. correct number and non-empty atoms.) */
    for (n = 0, ap = atoms; (*ap = strsep(&pcp, "|")) != NULL; n++)
    {
        if (**ap == '\0' && n < NUM_ATOMS)
        {
            /* empty field */
            scs_set_error(ctx, SCS_ERR_FRAMING, "field %zu is empty", n);
            return -1;
        }

        if (++ap > &atoms[NUM_ATOMS])
        {
            scs_set_error(ctx, SCS_ERR_FRAMING, "too much atoms");
            return -1;
        }
    }

    if (n != NUM_ATOMS)
    {
        scs_set_error(ctx, SCS_ERR_FRAMING, "got %zu atom(s), need 5", n);
        return -1;
    }

    /* Make a copy of the supplied authtag that can be compared with the
     * re-computed authtag. */
    (void) strlcpy(tag, atoms[TAG], BASE64_LENGTH(SCS_TAG_MAX) + 1);

    /* Attach atoms to context. */
    return attach_atoms(ctx, atoms[DATA], atoms[TSTAMP], atoms[TID], 
                        atoms[IV], atoms[TAG]);
}
コード例 #2
0
ファイル: sec-mod-auth.c プロジェクト: a1ive/ocserv-fork
int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req)
{
	client_entry_st *e;
	stats_st totals;

	if (req->sid.len != SID_SIZE) {
		seclog(sec, LOG_ERR, "auth session stats but with illegal sid size (%d)!",
		       (int)req->sid.len);
		return -1;
	}

	e = find_client_entry(sec, req->sid.data);
	if (e == NULL) {
		char tmp[BASE64_LENGTH(SID_SIZE) + 1];
		base64_encode((char *)req->sid.data, req->sid.len, (char *)tmp, sizeof(tmp));
		seclog(sec, LOG_INFO, "session stats but with non-existing SID: %s", tmp);
		return -1;
	}

	if (e->status != PS_AUTH_COMPLETED) {
		seclog(sec, LOG_ERR, "session stats received in unauthenticated client %s "SESSION_STR"!", e->auth_info.username, e->auth_info.psid);
		return -1;
	}

	/* stats only increase */
	if (req->bytes_in > e->stats.bytes_in)
		e->stats.bytes_in = req->bytes_in;
	if (req->bytes_out > e->stats.bytes_out)
		e->stats.bytes_out = req->bytes_out;
	if (req->uptime > e->stats.uptime)
		e->stats.uptime = req->uptime;

	if (req->has_discon_reason && req->discon_reason != 0) {
		e->discon_reason = req->discon_reason;
	}

	if (sec->perm_config->acct.amod == NULL || sec->perm_config->acct.amod->session_stats == NULL)
		return 0;

	stats_add_to(&totals, &e->stats, &e->saved_stats);
	if (req->remote_ip)
		strlcpy(e->auth_info.remote_ip, req->remote_ip, sizeof(e->auth_info.remote_ip));
	if (req->ipv4)
		strlcpy(e->auth_info.ipv4, req->ipv4, sizeof(e->auth_info.ipv4));
	if (req->ipv6)
		strlcpy(e->auth_info.ipv6, req->ipv6, sizeof(e->auth_info.ipv6));

	sec->perm_config->acct.amod->session_stats(e->auth_type, e->auth_ctx, &e->auth_info, &totals);

	return 0;
}
コード例 #3
0
ファイル: scs.c プロジェクト: babongo/libscs
/**
 *  \brief  Decode the supplied SCS \p cookie-value.
 *
 *  Decode the supplied SCS \p cookie string.  If verification is successful, 
 *  the embedded state blob, whose length is found at \p *pstate_sz, is 
 *  returned to the caller.
 *
 *  \param  ctx         An already initialized SCS context.
 *  \param  cookie      The SCS cookie-value to be decoded.
 *  \param  pstate_sz   The size in bytes of the decoded state blob as a 
 *                      return argument.
 *
 *  \return The decoded state blob on success, \c NULL if an error occurred.
 */
void *scs_decode (scs_t *ctx, const char *cookie, size_t *pstate_sz)
{
    char tag[BASE64_LENGTH(SCS_TAG_MAX) + 1];

    /* Check current keyset status. */
    if (check_update_keyset(ctx))
        return NULL;

    /* Cleanup the context. */
    reset_atoms(&ctx->atoms);

    /* Get SCS atoms. */
    if (split_cookie(ctx, cookie, tag))
        return NULL;

    /* Handle the PDU validation process. */
    return verify(ctx, tag, pstate_sz); 
}
コード例 #4
0
static void tpl_init_base64(struct tpl *tpl)
{
	// The rest of OSCam expects images to be base64 encoded and contain mime type.
	if(!template_is_image(tpl->tpl_type))
		{ return; }
	size_t b64_buf_len = 32 + BASE64_LENGTH(tpl->tpl_data_len); // Enough for base64 and 32 for header (data:XXX;base64,)
	char *b64_buf;
	if(!cs_malloc(&b64_buf, b64_buf_len))
	{
		tpl->tpl_data = "";
		tpl->tpl_data_len = 0;
		return;
	}
	int hdr_len = snprintf(b64_buf, b64_buf_len, "data:%s;base64,", template_get_mimetype(tpl->tpl_type));
	base64_encode(tpl->tpl_data, tpl->tpl_data_len, b64_buf + hdr_len, b64_buf_len - hdr_len);
	tpl->tpl_data = tpl->extra_data = b64_buf;
	tpl->tpl_data_len = strlen(b64_buf);
}
コード例 #5
0
ファイル: websocket_info.cpp プロジェクト: croot/xiva
void
websocket_info::parse_sec_key(request_impl const &req) {

	std::string const &key = req.header(WS_STR_SEC_WEBSOCKET_KEY);
	if (key.empty()) {
		throw std::runtime_error("can not find key in websocket request");
	}

	enum { SHA_OUTPUT_SIZE = 20 };
	unsigned char obuf[SHA_OUTPUT_SIZE];

	std::string const key_data = key + WS_STR_SECRET_WORD;
	SHA1((const unsigned char*)key_data.c_str(), key_data.size(), obuf);

	BIO *b64 = BIO_new(BIO_f_base64());
	if (NULL == b64) {
		throw std::bad_alloc();
	}

	cleanup_bio cleaner(b64);
	BIO *bmem = BIO_new(BIO_s_mem());
	if (NULL == bmem) {
		throw std::bad_alloc();
	}

	cleaner.bio_ = b64 = BIO_push(b64, bmem);

	BIO_write(b64, obuf, sizeof(obuf));
	BIO_flush(b64);

	BUF_MEM *bptr = NULL;
        BIO_get_mem_ptr(b64, &bptr);

	if (NULL == bptr || NULL == bptr->data || bptr->length != (BASE64_LENGTH(SHA_OUTPUT_SIZE) + 1)) { 
		throw std::runtime_error("can not create accept data in websocket request");
	}
	sec_data_.assign((const char*)bptr->data, bptr->length - 1);
}
コード例 #6
0
ファイル: xmppipe.c プロジェクト: msantos/xmppipe
    int
main(int argc, char **argv)
{
    xmppipe_state_t *state = NULL;
    xmpp_log_t *log = NULL;
    char *jid = NULL;
    char *pass = NULL;
    char *addr = NULL;
    u_int16_t port = 0;
    int flags = 0;

    int ch = 0;

    if (setvbuf(stdout, NULL, _IOLBF, 0) < 0)
        err(EXIT_FAILURE, "setvbuf");

    state = xmppipe_calloc(1, sizeof(xmppipe_state_t));

    xmppipe_next_state(state, XMPPIPE_S_CONNECTING);
    state->bufsz = 2049;
    state->poll = 10;
    state->keepalive = 60 * 1000;
    state->keepalive_limit = 3;
    state->sm_request_interval = 1;
    state->sm_fc = 15;
    state->sm_unacked = 5;
    state->room = xmppipe_roomname("stdout");
    state->resource = xmppipe_strdup(XMPPIPE_RESOURCE);
    state->opt |= XMPPIPE_OPT_GROUPCHAT;

    jid = xmppipe_getenv("XMPPIPE_USERNAME");
    pass = xmppipe_getenv("XMPPIPE_PASSWORD");

    if (xmppipe_sandbox_init(state) < 0)
        err(EXIT_FAILURE, "sandbox failed");

    while ( (ch = getopt_long(argc, argv, "a:b:c:dDeF:hI:k:K:o:P:p:r:sS:u:U:vx",
                    long_options, NULL)) != -1) {
        switch (ch) {
            case 'u':
                /* username/jid */
                free(jid);
                jid = xmppipe_strdup(optarg);
                break;
            case 'p':
                /* password */
                free(pass);
                pass = xmppipe_strdup(optarg);
                break;
            case 'o':
                /* output/muc */
                free(state->room);
                state->room = xmppipe_strdup(optarg);
                break;
            case 'a': {
                    /* address:port */
                    char *p = NULL;
                    free(addr);
                    addr = xmppipe_strdup(optarg);
                    p = strchr(addr, ':');
                    if (p) {
                        *p++ = '\0';
                        port = xmppipe_strtonum(state, p, 0, 0xfffe);
                    }
                }
                break;
            case 'r':
                free(state->resource);
                state->resource = xmppipe_strdup(optarg);
                break;
            case 'S':
                free(state->subject);
                state->subject = xmppipe_strdup(optarg);
                break;
            case 'v':
                state->verbose++;
                break;
            case 'F':
                if (strcmp(optarg, "text") == 0)
                    state->format = XMPPIPE_FMT_TEXT;
                else if (strcmp(optarg, "csv") == 0)
                    state->format = XMPPIPE_FMT_CSV;
                else
                    usage(state);

                break;
            case 'x':
                state->encode = 1;
                break;

            case 'b':
                /* read buffer size */
                state->bufsz = xmppipe_strtonum(state, optarg, 3, 0xfffe);
                break;
            case 'c':
                /* XEP-0198: stream management flow control */
                state->sm_fc = xmppipe_strtonum(state, optarg, 0, 0xfffe);
                break;
            case 'I':
                /* XEP-0198: stream management request interval */
                state->sm_request_interval = xmppipe_strtonum(state, optarg, 0,
                        0xfffe);
                break;
            case 'k':
                /* XEP-0199: XMPP ping keepalives */
                state->sm_request_interval = xmppipe_strtonum(state, optarg, 0,
                        0xfffe) * 1000;
                break;
            case 'K':
                /* XEP-0199: number of keepalive without a reply */
                state->keepalive_limit = xmppipe_strtonum(state, optarg, 1,
                        0xfffe);
                break;
            case 'P':
                /* poll delay */
                state->poll = xmppipe_strtonum(state, optarg, 0, 0xfffe);
                break;
            case 'U':
                /* XEP-0198: stream management unacked requests */
                state->sm_unacked = xmppipe_strtonum(state, optarg, 0, 0xfffe);
                break;

            case 'd':
                state->opt |= XMPPIPE_OPT_DISCARD;
                break;
            case 'D':
                state->opt |= XMPPIPE_OPT_DISCARD;
                state->opt |= XMPPIPE_OPT_DISCARD_TO_STDOUT;
                break;
            case 'e':
                state->opt |= XMPPIPE_OPT_EOF;
                break;
            case 's':
                state->opt |= XMPPIPE_OPT_SIGPIPE;
                break;

            case OPT_NO_TLS_VERIFY:
                flags |= XMPP_CONN_FLAG_TRUST_TLS;
                break;
            case OPT_CHAT:
                state->opt &= ~XMPPIPE_OPT_GROUPCHAT;
                break;

            case OPT_CHAT_MARKER:
                state->opt |= XMPPIPE_OPT_CHAT_MARKER;
                break;

            case 'h':
            default:
                usage(state);
        }
    }

    argc -= optind;
    argv += optind;

    if (argc > 0) {
      free(state->room);
      state->room = xmppipe_strdup(argv[0]);
    }

    if (jid == NULL)
        usage(state);

    if (state->encode && BASE64_LENGTH(state->bufsz) + 1 > 0xffff)
        usage(state);

    state->server = xmppipe_servername(jid);

    if (strchr(state->room, '@')) {
        state->out = xmppipe_strdup(state->room);
        state->mucjid = xmppipe_mucjid(state->out, state->resource);
    }
    else if (!(state->opt & XMPPIPE_OPT_GROUPCHAT)) {
        state->out = xmppipe_strdup(jid);
    }

    if (xmppipe_fmt_init() < 0)
        errx(EXIT_FAILURE, "xmppipe_fmt_init");

    xmpp_initialize();

    log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);

    state->ctx = xmpp_ctx_new(NULL, (state->verbose > 1 ? log : NULL));
    if (state->ctx == NULL)
        errx(EXIT_FAILURE, "could not allocate context");

    state->conn = xmpp_conn_new(state->ctx);
    if (state->conn == NULL)
        errx(EXIT_FAILURE, "could not allocate connection");

    if (xmpp_conn_set_flags(state->conn, flags) < 0)
        errx(EXIT_FAILURE, "failed to set connection flags");

    xmpp_conn_set_jid(state->conn, jid);
    xmpp_conn_set_pass(state->conn, pass);

    if (xmpp_connect_client(state->conn, addr, port, handle_connection, state) < 0)
        errx(EXIT_FAILURE, "connection failed");

    if (xmppipe_connect_init(state) < 0)
        errx(EXIT_FAILURE, "XMPP handshake failed");

    if (state->verbose)
        (void)fprintf(stderr, "sandbox: stdin: %s\n", XMPPIPE_SANDBOX);

    if (xmppipe_sandbox_stdin(state) < 0)
        err(EXIT_FAILURE, "sandbox failed");

    if (xmppipe_stream_init(state) < 0)
        errx(EXIT_FAILURE, "enabling stream management failed");

    if ( (state->opt & XMPPIPE_OPT_GROUPCHAT) && xmppipe_muc_init(state) < 0)
        errx(EXIT_FAILURE, "failed to join MUC");

    if (xmppipe_presence_init(state) < 0)
        errx(EXIT_FAILURE, "publishing presence failed");

    if ( (state->opt & XMPPIPE_OPT_GROUPCHAT) && state->subject)
        xmppipe_muc_subject(state, state->subject);

    event_loop(state);

    xmppipe_stream_close(state);
    (void)xmpp_conn_release(state->conn);
    xmpp_ctx_free(state->ctx);
    xmpp_shutdown();

    return 0;
}
コード例 #7
0
ファイル: sec-mod-auth.c プロジェクト: a1ive/ocserv-fork
static
int handle_sec_auth_session_close(sec_mod_st *sec, int fd, const SecAuthSessionMsg *req)
{
	client_entry_st *e;
	int ret;
	CliStatsMsg rep = CLI_STATS_MSG__INIT;

	if (req->sid.len != SID_SIZE) {
		seclog(sec, LOG_ERR, "auth session close but with illegal sid size (%d)!",
		       (int)req->sid.len);
		return ERR_BAD_COMMAND;
	}

	e = find_client_entry(sec, req->sid.data);
	if (e == NULL) {
		char tmp[BASE64_LENGTH(SID_SIZE) + 1];
		base64_encode((char *)req->sid.data, req->sid.len, (char *)tmp, sizeof(tmp));
		seclog(sec, LOG_INFO, "session close but with non-existing SID: %s", tmp);
		return send_msg(e, fd, SM_CMD_AUTH_CLI_STATS, &rep,
		                (pack_size_func) cli_stats_msg__get_packed_size,
		                (pack_func) cli_stats_msg__pack);
	}

	if (e->status < PS_AUTH_COMPLETED) {
		seclog(sec, LOG_DEBUG, "session close received in unauthenticated client %s "SESSION_STR"!", e->auth_info.username, e->auth_info.psid);
		return send_msg(e, fd, SM_CMD_AUTH_CLI_STATS, &rep,
		                (pack_size_func) cli_stats_msg__get_packed_size,
		                (pack_func) cli_stats_msg__pack);
	}


	if (req->has_uptime && req->uptime > e->stats.uptime) {
			e->stats.uptime = req->uptime;
	}
	if (req->has_bytes_in && req->bytes_in > e->stats.bytes_in) {
			e->stats.bytes_in = req->bytes_in;
	}
	if (req->has_bytes_out && req->bytes_out > e->stats.bytes_out) {
			e->stats.bytes_out = req->bytes_out;
	}

	/* send reply */
	rep.bytes_in = e->stats.bytes_in;
	rep.bytes_out = e->stats.bytes_out;
	rep.has_secmod_client_entries = 1;
	rep.secmod_client_entries = sec_mod_client_db_elems(sec);

	ret = send_msg(e, fd, SM_CMD_AUTH_CLI_STATS, &rep,
			(pack_size_func) cli_stats_msg__get_packed_size,
			(pack_func) cli_stats_msg__pack);
	if (ret < 0) {
		seclog(sec, LOG_ERR, "error in sending session stats");
		return ERR_BAD_COMMAND;
	}

	/* save total stats */
	stats_add_to(&e->saved_stats, &e->saved_stats, &e->stats);
	memset(&e->stats, 0, sizeof(e->stats));
	expire_client_entry(sec, e);

	return 0;
}
コード例 #8
0
ファイル: sec-mod-auth.c プロジェクト: a1ive/ocserv-fork
static
int handle_sec_auth_session_open(sec_mod_st *sec, int fd, const SecAuthSessionMsg *req)
{
	client_entry_st *e;
	void *lpool;
	int ret;
	SecAuthSessionReplyMsg rep = SEC_AUTH_SESSION_REPLY_MSG__INIT;

	if (req->sid.len != SID_SIZE) {
		seclog(sec, LOG_ERR, "auth session open but with illegal sid size (%d)!",
		       (int)req->sid.len);
		return send_failed_session_open_reply(sec, fd);
	}

	e = find_client_entry(sec, req->sid.data);
	if (e == NULL) {
		char tmp[BASE64_LENGTH(SID_SIZE) + 1];
		base64_encode((char *)req->sid.data, req->sid.len, (char *)tmp, sizeof(tmp));
		seclog(sec, LOG_INFO, "session open but with non-existing SID: %s!", tmp);
		return send_failed_session_open_reply(sec, fd);
	}

	if (e->status != PS_AUTH_COMPLETED) {
		seclog(sec, LOG_ERR, "session open received in unauthenticated client %s "SESSION_STR"!", e->auth_info.username, e->auth_info.psid);
		return send_failed_session_open_reply(sec, fd);
	}

	if (e->time != -1 && time(0) > e->time + sec->config->cookie_timeout) {
		seclog(sec, LOG_ERR, "session expired; denied session for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid);
		e->status = PS_AUTH_FAILED;
		return send_failed_session_open_reply(sec, fd);
	}

	if (req->has_cookie == 0 || (req->cookie.len != e->cookie_size) ||
	    memcmp(req->cookie.data, e->cookie, e->cookie_size) != 0) {
		seclog(sec, LOG_ERR, "cookie error; denied session for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid);
		e->status = PS_AUTH_FAILED;
		return send_failed_session_open_reply(sec, fd);
	}

	if (req->ipv4)
		strlcpy(e->auth_info.ipv4, req->ipv4, sizeof(e->auth_info.ipv4));
	if (req->ipv6)
		strlcpy(e->auth_info.ipv6, req->ipv6, sizeof(e->auth_info.ipv6));

	if (sec->perm_config->acct.amod != NULL && sec->perm_config->acct.amod->open_session != NULL && e->session_is_open == 0) {
		ret = sec->perm_config->acct.amod->open_session(e->auth_type, e->auth_ctx, &e->auth_info, req->sid.data, req->sid.len);
		if (ret < 0) {
			e->status = PS_AUTH_FAILED;
			seclog(sec, LOG_INFO, "denied session for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid);
			return send_failed_session_open_reply(sec, fd);
		} else {
			e->session_is_open = 1;
		}
	}

	rep.reply = AUTH__REP__OK;

	lpool = talloc_new(e);
	if (lpool == NULL) {
		return ERR_BAD_COMMAND; /* we desync */
	}

	if (sec->config_module && sec->config_module->get_sup_config) {
		ret = sec->config_module->get_sup_config(sec->config, e, &rep, lpool);
		if (ret < 0) {
			seclog(sec, LOG_ERR, "error reading additional configuration for '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid);
			talloc_free(lpool);
			return send_failed_session_open_reply(sec, fd);
		}
	}

	ret = send_msg(lpool, fd, SM_CMD_AUTH_SESSION_REPLY, &rep,
			(pack_size_func) sec_auth_session_reply_msg__get_packed_size,
			(pack_func) sec_auth_session_reply_msg__pack);
	if (ret < 0) {
		seclog(sec, LOG_ERR, "error in sending session reply");
		return ERR_BAD_COMMAND; /* we desync */
	}
	talloc_free(lpool);

	seclog(sec, LOG_INFO, "initiating session for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid);
	e->time = -1;
	e->in_use++;

	return 0;
}
コード例 #9
0
int post_common_handler(worker_st * ws, unsigned http_ver, const char *imsg)
{
	int ret, size;
	char str_cookie[BASE64_LENGTH(ws->cookie_size)+1];
	size_t str_cookie_size = sizeof(str_cookie);
	char msg[MAX_BANNER_SIZE + 32];
	const char *success_msg_head;
	const char *success_msg_foot;
	unsigned success_msg_head_size;
	unsigned success_msg_foot_size;

	if (ws->req.user_agent_type == AGENT_OPENCONNECT_V3) {
		success_msg_head = ocv3_success_msg_head;
		success_msg_foot = ocv3_success_msg_foot;
		success_msg_head_size = sizeof(ocv3_success_msg_head)-1;
		success_msg_foot_size = sizeof(ocv3_success_msg_foot)-1;
	} else {
		success_msg_head = oc_success_msg_head;
		success_msg_foot = oc_success_msg_foot;
		success_msg_head_size = sizeof(oc_success_msg_head)-1;
		success_msg_foot_size = sizeof(oc_success_msg_foot)-1;
	}

	base64_encode((char *)ws->cookie, ws->cookie_size,
		      (char *)str_cookie, str_cookie_size);

	/* reply */
	oclog(ws, LOG_HTTP_DEBUG, "HTTP sending: 200 OK");

	cstp_cork(ws);
	ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
	if (ret < 0)
		return -1;

	ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
	if (ret < 0)
		return -1;

	if (ws->selected_auth->type & AUTH_TYPE_GSSAPI && imsg != NULL && imsg[0] != 0) {
		ret = cstp_printf(ws, "WWW-Authenticate: Negotiate %s\r\n", imsg);
		if (ret < 0)
			return -1;
	}

	ret = cstp_puts(ws, "Content-Type: text/xml\r\n");
	if (ret < 0)
		return -1;

	if (ws->config->banner) {
		size =
		    snprintf(msg, sizeof(msg), "<banner>%s</banner>",
			     ws->config->banner);
		if (size <= 0)
			return -1;
		/* snprintf() returns not a very useful value, so we need to recalculate */
		size = strlen(msg);
	} else {
		msg[0] = 0;
		size = 0;
	}

	size += success_msg_head_size + success_msg_foot_size;

	ret = cstp_printf(ws, "Content-Length: %u\r\n", (unsigned)size);
	if (ret < 0)
		return -1;

	ret = cstp_puts(ws, "X-Transcend-Version: 1\r\n");
	if (ret < 0)
		return -1;

	ret =
	    cstp_printf(ws,
		       "Set-Cookie: webvpn=%s; Secure\r\n",
		       str_cookie);
	if (ret < 0)
		return -1;

#ifdef ANYCONNECT_CLIENT_COMPAT
	ret =
	    cstp_puts(ws,
		     "Set-Cookie: webvpnc=; expires=Thu, 01 Jan 1970 22:00:00 GMT; path=/; Secure\r\n");
	if (ret < 0)
		return -1;

	if (ws->config->xml_config_file) {
		ret =
		    cstp_printf(ws,
			       "Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s&lu:/+CSCOT+/translation-table?textdomain%%3DAnyConnect%%26type%%3Dmanifest&fu:profiles%%2F%s&fh:%s; path=/; Secure\r\n",
			       ws->config->cert_hash,
			       ws->config->xml_config_file,
			       ws->config->xml_config_hash);
	} else {
		ret =
		    cstp_printf(ws,
			       "Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s; path=/; Secure\r\n",
			       ws->config->cert_hash);
	}

	if (ret < 0)
		return -1;
#endif

	ret =
	    cstp_printf(ws,
		       "\r\n%s%s%s", success_msg_head, msg, success_msg_foot);
	if (ret < 0)
		return -1;

	ret = cstp_uncork(ws);
	if (ret < 0)
		return -1;

	return 0;
}
コード例 #10
0
int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg)
{
	int ret;
	char context[BASE64_LENGTH(SID_SIZE) + 1];
	unsigned int i, j;
	str_st str;
	const char *login_msg_start;
	const char *login_msg_end;

	if (ws->req.user_agent_type == AGENT_OPENCONNECT_V3) {
		login_msg_start = OCV3_LOGIN_MSG_START;
		login_msg_end = ocv3_login_msg_end;
	} else {
		login_msg_start = OC_LOGIN_MSG_START;
		login_msg_end = oc_login_msg_end;
	}

	if (ws->selected_auth->type & AUTH_TYPE_GSSAPI && ws->auth_state < S_AUTH_COOKIE) {
		if (ws->req.authorization == NULL || ws->req.authorization_size == 0)
			return basic_auth_handler(ws, http_ver, NULL);
		else
			return post_auth_handler(ws, http_ver);
	}

	str_init(&str, ws);

	oclog(ws, LOG_HTTP_DEBUG, "HTTP sending: 200 OK");
	cstp_cork(ws);
	ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
	if (ret < 0)
		return -1;


	if (ws->sid_set != 0) {
		base64_encode((char *)ws->sid, sizeof(ws->sid), (char *)context,
			      sizeof(context));

		ret =
		    cstp_printf(ws,
			       "Set-Cookie: webvpncontext=%s; Max-Age=%u; Secure\r\n",
			       context, (unsigned)ws->config->cookie_timeout);
		if (ret < 0)
			return -1;

		oclog(ws, LOG_DEBUG, "sent sid: %s", context);
	} else {
		ret =
		    cstp_puts(ws,
			     "Set-Cookie: webvpncontext=; expires=Thu, 01 Jan 1970 22:00:00 GMT; path=/; Secure\r\n");
		if (ret < 0)
			return -1;
	}

	ret = cstp_puts(ws, "Content-Type: text/xml\r\n");
	if (ret < 0) {
		ret = -1;
		goto cleanup;
	}

	if (ws->auth_state == S_AUTH_REQ) {
		/* only ask password */
		if (pmsg == NULL)
			pmsg = "Please enter your password";

		ret = str_append_printf(&str, login_msg_start, pmsg);
		if (ret < 0) {
			ret = -1;
			goto cleanup;
		}

		ret = str_append_str(&str, login_msg_password);
		if (ret < 0) {
			ret = -1;
			goto cleanup;
		}

		ret = str_append_str(&str, login_msg_end);
		if (ret < 0) {
			ret = -1;
			goto cleanup;
		}

	} else {
		if (pmsg == NULL)
			pmsg = "Please enter your username";

		/* ask for username and groups */
		ret = str_append_printf(&str, login_msg_start, pmsg);
		if (ret < 0) {
			ret = -1;
			goto cleanup;
		}

		if (ws->selected_auth->type & AUTH_TYPE_USERNAME_PASS) {
			ret = str_append_str(&str, login_msg_user);
			if (ret < 0) {
				ret = -1;
				goto cleanup;
			}
		}

		if (ws->selected_auth->type & AUTH_TYPE_CERTIFICATE && ws->cert_auth_ok != 0) {
			ret = get_cert_info(ws);
			if (ret < 0) {
				ret = -1;
				oclog(ws, LOG_WARNING, "cannot obtain certificate information");
				goto cleanup;
			}
		}

		/* send groups */
		if (ws->config->group_list_size > 0 || ws->cert_groups_size > 0) {
			ret = str_append_str(&str, "<select name=\"group_list\" label=\"GROUP:\">\n");
			if (ret < 0) {
				ret = -1;
				goto cleanup;
			}

			/* Several anyconnect clients (and openconnect) submit the group name
			 * separately in that form. In that case they expect that we re-order
			 * the list and we place the group they selected first. WTF! No respect
			 * to server time.
			 */
			if (ws->groupname[0] != 0) {
				ret = append_group_str(ws, &str, ws->groupname);
				if (ret < 0) {
					ret = -1;
					goto cleanup;
				}
			}

			if (ws->config->default_select_group) {
				ret = str_append_printf(&str, "<option>%s</option>\n", ws->config->default_select_group);
				if (ret < 0) {
					ret = -1;
					goto cleanup;
				}
			}

			/* append any groups available in the certificate */
			if (ws->selected_auth->type & AUTH_TYPE_CERTIFICATE && ws->cert_auth_ok != 0) {
				unsigned dup;

				for (i=0;i<ws->cert_groups_size;i++) {
					dup = 0;
					for (j=0;j<ws->config->group_list_size;j++) {
						if (strcmp(ws->cert_groups[i], ws->config->group_list[j]) == 0) {
							dup = 1;
							break;
						}
					}

					if (dup == 0 && ws->groupname[0] != 0 && strcmp(ws->groupname, ws->cert_groups[i]) == 0)
						dup = 1;

					if (dup != 0)
						continue;

					ret = str_append_printf(&str, "<option>%s</option>\n", ws->cert_groups[i]);
					if (ret < 0) {
						ret = -1;
						goto cleanup;
					}
				}
			}


			for (i=0;i<ws->config->group_list_size;i++) {
				if (ws->groupname[0] != 0 && strcmp(ws->groupname, ws->config->group_list[i]) == 0)
					continue;

				ret = append_group_idx(ws, &str, i);
				if (ret < 0) {
					ret = -1;
					goto cleanup;
				}
			}
			ret = str_append_str(&str, "</select>\n");
			if (ret < 0) {
				ret = -1;
				goto cleanup;
			}
		}

		ret = str_append_str(&str, login_msg_end);
		if (ret < 0) {
			ret = -1;
			goto cleanup;
		}

	}

	ret =
	    cstp_printf(ws, "Content-Length: %u\r\n",
		       (unsigned int)str.length);
	if (ret < 0) {
		ret = -1;
		goto cleanup;
	}

	ret = cstp_puts(ws, "X-Transcend-Version: 1\r\n");
	if (ret < 0) {
		ret = -1;
		goto cleanup;
	}

	ret = cstp_puts(ws, "\r\n");
	if (ret < 0) {
		ret = -1;
		goto cleanup;
	}

	ret = cstp_send(ws, str.data, str.length);
	if (ret < 0) {
		ret = -1;
		goto cleanup;
	}


	ret = cstp_uncork(ws);
	if (ret < 0) {
		ret = -1;
		goto cleanup;
	}

	ret = 0;

 cleanup:
 	str_clear(&str);
	return ret;
}
コード例 #11
0
ファイル: flac.c プロジェクト: JhonlyB/opus-tools
/*Callback to process a metadata packet.*/
static void metadata_callback(const FLAC__StreamDecoder *decoder,
   const FLAC__StreamMetadata *metadata,void *client_data){
  flacfile *flac;
  oe_enc_opt *inopt;
  (void)decoder;
  flac=(flacfile *)client_data;
  inopt=flac->inopt;
  switch(metadata->type){
    case FLAC__METADATA_TYPE_STREAMINFO:
      flac->max_blocksize=metadata->data.stream_info.max_blocksize;
      inopt->rate=metadata->data.stream_info.sample_rate;
      inopt->channels=flac->channels=metadata->data.stream_info.channels;
      inopt->samplesize=metadata->data.stream_info.bits_per_sample;
      inopt->total_samples_per_channel=
         metadata->data.stream_info.total_samples;
      flac->block_buf=malloc(
         flac->max_blocksize*flac->channels*sizeof(*flac->block_buf));
      flac->block_buf_pos=0;
      flac->block_buf_len=0;
      break;
    case FLAC__METADATA_TYPE_VORBIS_COMMENT:
      {
        FLAC__StreamMetadata_VorbisComment_Entry *comments;
        FLAC__uint32 num_comments;
        FLAC__uint32 i;
        double reference_loudness;
        double album_gain;
        double track_gain;
        double gain;
        int saw_album_gain;
        int saw_track_gain;
        char *saved_locale;
        if(!inopt->copy_comments)break;
        num_comments=metadata->data.vorbis_comment.num_comments;
        comments=metadata->data.vorbis_comment.comments;
        saw_album_gain=saw_track_gain=0;
        album_gain=track_gain=0;
        /*The default reference loudness for ReplayGain is 89.0 dB*/
        reference_loudness=89;
        /*The code below uses strtod for the gain tags, so make sure the locale is C*/
        saved_locale=setlocale(LC_NUMERIC,"C");
        for(i=0;i<num_comments;i++){
          char *entry;
          char *end;
          entry=(char *)comments[i].entry;
          /*Check for ReplayGain tags.
            Parse the ones we have R128 equivalents for, and skip the others.*/
          if(oi_strncasecmp(entry,"REPLAYGAIN_REFERENCE_LOUDNESS=",30)==0){
            gain=strtod(entry+30,&end);
            if(end<=entry+30){
              fprintf(stderr,_("WARNING: Invalid ReplayGain tag: %s\n"),entry);
            }
            else reference_loudness=gain;
            continue;
          }
          if(oi_strncasecmp(entry,"REPLAYGAIN_ALBUM_GAIN=",22)==0){
            gain=strtod(entry+22,&end);
            if(end<=entry+22){
              fprintf(stderr,_("WARNING: Invalid ReplayGain tag: %s\n"),entry);
            }
            else{
              album_gain=gain;
              saw_album_gain=1;
            }
            continue;
          }
          if(oi_strncasecmp(entry,"REPLAYGAIN_TRACK_GAIN=",22)==0){
            gain=strtod(entry+22,&end);
            if(end<entry+22){
              fprintf(stderr,_("WARNING: Invalid ReplayGain tag: %s\n"),entry);
            }
            else{
              track_gain=gain;
              saw_track_gain=1;
            }
            continue;
          }
          if(oi_strncasecmp(entry,"REPLAYGAIN_ALBUM_PEAK=",22)==0
             ||oi_strncasecmp(entry,"REPLAYGAIN_TRACK_PEAK=",22)==0){
            continue;
          }
          if(!strchr(entry,'=')){
            fprintf(stderr,_("WARNING: Invalid comment: %s\n"),entry);
            fprintf(stderr,
               _("Discarding comment not in the form name=value\n"));
            continue;
          }
          comment_add(&inopt->comments,&inopt->comments_length,NULL,entry);
        }
        setlocale(LC_NUMERIC,saved_locale);
        /*Set the header gain to the album gain after converting to the R128
          reference level.*/
        if(saw_album_gain){
          gain=256*(album_gain+(84-reference_loudness))+0.5;
          inopt->gain=gain<-32768?-32768:gain<32767?(int)floor(gain):32767;
        }
        /*If there was a track gain, then add an equivalent R128 tag for that.*/
        if(saw_track_gain){
          char track_gain_buf[7];
          int track_gain_val;
          gain=256*(track_gain-album_gain)+0.5;
          track_gain_val=gain<-32768?-32768:gain<32767?(int)floor(gain):32767;
          sprintf(track_gain_buf,"%i",track_gain_val);
          comment_add(&inopt->comments,&inopt->comments_length,
             "R128_TRACK_GAIN",track_gain_buf);
        }
      }
      break;
    case FLAC__METADATA_TYPE_PICTURE:
      {
        char  *buf;
        char  *b64;
        size_t mime_type_length;
        size_t description_length;
        size_t buf_sz;
        size_t b64_sz;
        size_t offs;
        mime_type_length=strlen(metadata->data.picture.mime_type);
        description_length=strlen((char *)metadata->data.picture.description);
        buf_sz=32+mime_type_length+description_length
         +metadata->data.picture.data_length;
        buf=(char *)malloc(buf_sz);
        offs=0;
        WRITE_U32_BE(buf+offs,metadata->data.picture.type);
        offs+=4;
        WRITE_U32_BE(buf+offs,(FLAC__uint32)mime_type_length);
        offs+=4;
        memcpy(buf+offs,metadata->data.picture.mime_type,mime_type_length);
        offs+=mime_type_length;
        WRITE_U32_BE(buf+offs,(FLAC__uint32)description_length);
        offs+=4;
        memcpy(buf+offs,metadata->data.picture.description,description_length);
        offs+=description_length;
        WRITE_U32_BE(buf+offs,metadata->data.picture.width);
        offs+=4;
        WRITE_U32_BE(buf+offs,metadata->data.picture.height);
        offs+=4;
        WRITE_U32_BE(buf+offs,metadata->data.picture.depth);
        offs+=4;
        WRITE_U32_BE(buf+offs,metadata->data.picture.colors);
        offs+=4;
        WRITE_U32_BE(buf+offs,metadata->data.picture.data_length);
        offs+=4;
        memcpy(buf+offs,metadata->data.picture.data,
           metadata->data.picture.data_length);
        b64_sz=BASE64_LENGTH(buf_sz)+1;
        b64=(char *)malloc(b64_sz);
        base64_encode(b64,buf,buf_sz);
        free(buf);
        comment_add(&inopt->comments,&inopt->comments_length,
           "METADATA_BLOCK_PICTURE",b64);
        free(b64);
      }
      break;
    default:
      break;
  }
}
コード例 #12
0
ファイル: scs.c プロジェクト: babongo/libscs
static int create_tag (scs_t *ctx, scs_keyset_t *ks, int skip_encoding)
{
    size_t i;
    scs_atoms_t *ats = &ctx->atoms;
    enum { NUM_ATOMS = 4 };
    struct {
        const char *id;
        uint8_t *raw; 
        char *enc;
        size_t raw_sz, enc_sz;
    } A[NUM_ATOMS] = {
        { 
            "SCS DATA",
            ats->data,
            ats->b64_data,
            ats->data_sz,
            BASE64_LENGTH(ats->data_sz)
        },
        { 
            "SCS TSTAMP",
            (uint8_t *) ats->tstamp,
            ats->b64_tstamp,
            strlen(ats->tstamp),
            sizeof(ats->b64_tstamp)
        },
        {
            "SCS TID",
            (uint8_t *) ks->tid,
            ats->b64_tid,
            strlen(ks->tid),
            sizeof(ats->b64_tid)
        },
        {
            "SCS IV",
            ats->iv,
            ats->b64_iv,
            ks->block_sz,
            BASE64_LENGTH(ks->block_sz)
        }
    };    
    
    /* If requested, create Base-64 encoded versions of atoms. */
    if (!skip_encoding)
    {
        for (i = 0; i < NUM_ATOMS; ++i)
        {
            if (base64url_encode(A[i].raw, A[i].raw_sz,
                        A[i].enc, &A[i].enc_sz))
            {
                scs_set_error(ctx, SCS_ERR_ENCODE, "%s encode failed", A[i].id);
                return -1;
            }
        }
    }

    /* Create auth tag. */
    if (D.tag(ctx, ks))
        return -1;

    size_t b64_tag = sizeof ats->b64_tag;

    /* Base-64 encode the auth tag. */
    if (base64url_encode(ats->tag, ats->tag_sz, ats->b64_tag, &b64_tag))
    {
        scs_set_error(ctx, SCS_ERR_ENCODE, "tag encode failed");
        return -1;
    }

    return 0;
}
コード例 #13
0
ファイル: scs.c プロジェクト: babongo/libscs
static const char *do_cookie (scs_t *ctx, char cookie[SCS_COOKIE_MAX]);

/* Decode support. */
static scs_keyset_t *retr_keyset (scs_t *ctx);
static int attach_atoms (scs_t *ctx, const char *b64_data, 
        const char *b64_tstamp, const char *b64_tid, const char *b64_iv, 
        const char *b64_tag);
static int decode_atoms (scs_t *ctx, scs_keyset_t *ks);
static int tags_match (scs_t *ctx, const char *tag);
static int tstamp_ok (scs_t *ctx);
static int optional_inflate (scs_t *ctx, scs_keyset_t *ks);
static int decrypt_state (scs_t *ctx, scs_keyset_t *ks);
static int remove_pad (scs_t *ctx);
static int do_inflate (scs_t *ctx);
static int split_cookie (scs_t *ctx, const char *cookie, 
        char tag[BASE64_LENGTH(SCS_TAG_MAX) + 1]);
static void *verify (scs_t *ctx, const char *tag, size_t *pstate_sz);

/* Auto refresh support. */
static int check_update_keyset (scs_t *ctx);
static int update_last_refresh (scs_t *ctx, time_t now);

/**
 *  \defgroup scs SCS
 *  \{
 *      TODO
 *
 *      \section init   Initialization
 *      TODO
 *
 *      \section encode Encoding