/* Given a username and password, expected to return AUTH_GRANTED if we can validate this user/password combination. */
static authn_status authn_crowd_check_password(request_rec *r, const char *user, const char *password)
{
    authnz_crowd_dir_config *config = get_config(r);
    if (config == NULL) {
        return AUTH_GENERAL_ERROR;
    }

    apr_array_header_t *basic_auth_xlates = config->basic_auth_xlates;
    int i;
    for (i = 0; i < basic_auth_xlates->nelts; i++) {
        apr_xlate_t *xlate = APR_ARRAY_IDX(basic_auth_xlates, i, apr_xlate_t *);
        char xlated_user[XLATE_BUFFER_SIZE] = {};
        char xlated_password[XLATE_BUFFER_SIZE] = {};
        if (!xlate_string(xlate, user, xlated_user) || !xlate_string(xlate, password, xlated_password)) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "Failed to translate basic authentication credentials");
        } else {
            crowd_authenticate_result result = CROWD_AUTHENTICATE_NOT_ATTEMPTED;
            if (config->create_sso) {
                crowd_cookie_config_t *cookie_config = crowd_get_cookie_config(r, config->crowd_config);
                if (cookie_config != NULL && (!cookie_config->secure || is_https(r))) {
                    const char *token;
                    result = crowd_create_session(r, config->crowd_config, xlated_user, xlated_password, &token);
                    if (result == CROWD_AUTHENTICATE_SUCCESS && token != NULL) {
                        char *domain = "";
                        if (cookie_config->domain != NULL && cookie_config->domain[0] == '.') {
                            int domainlen = strlen(cookie_config->domain);
                            int hostlen = strlen(r->hostname);
                            if (hostlen > domainlen
                                && strcmp(cookie_config->domain, r->hostname + hostlen - domainlen) == 0) {
                                domain = apr_psprintf(r->pool, ";Domain=%s", cookie_config->domain);
                            }
                        }
                        char *cookie = log_ralloc(r,
                            apr_psprintf(r->pool, "%s=%s%s%s;Version=1", cookie_config->cookie_name, token, domain,
                            cookie_config->secure ? ";Secure" : ""));
                        if (cookie != NULL) {
                            apr_table_add(r->err_headers_out, "Set-Cookie", cookie);
                        }
                    }
                }
            }
            if (result == CROWD_AUTHENTICATE_NOT_ATTEMPTED) {
                result = crowd_authenticate(r, config->crowd_config, xlated_user, xlated_password);
            }
            switch (result) {
                case CROWD_AUTHENTICATE_SUCCESS:
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Authenticated '%s'.", xlated_user);
                    return AUTH_GRANTED;
                case CROWD_AUTHENTICATE_FAILURE:
                    break;
                default:
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "Crowd authentication failed due to system exception");
            }
        }
    }

    return AUTH_DENIED;
}
Exemplo n.º 2
0
static int open_socket(struct connection *conn, char *host)
{
	char *port, *p;

	if (proxy)
		return connect_socket(conn, proxy, proxy_port);

	p = strchr(host, ':');
	if (p) {
		/* port specified */
		*p++ = '\0';
		port = p;
	} else
		port = is_https(conn->url) ? "443" : "80";

	return connect_socket(conn, host, port);
}
Exemplo n.º 3
0
HttpRet is_http_conn_allowed(const char *url,
							  const char *proxy_addr, int proxy_port,
							  const char *proxy_login, const char *proxy_passwd,
							  NETLIB_BOOLEAN ssl, int timeout)
{
	char url_buf[1024];
	char auth_buf[1024];
	char proxy_buf[1024];
	CURL *mcurl;
	int ret;
	long http_resp_code;

	mcurl = curl_easy_init();

	curl_easy_setopt(mcurl, CURLOPT_VERBOSE, 1);
	curl_easy_setopt(mcurl, CURLOPT_WRITEFUNCTION, _curlsilentwritecbk);
	curl_easy_setopt(mcurl, CURLOPT_DEBUGFUNCTION, _curloutputcbk);

	if (ssl) 
	{
		snprintf(url_buf, sizeof(url_buf), "https://%s", url);
		curl_easy_setopt(mcurl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
		
		curl_easy_setopt(mcurl, CURLOPT_SSL_VERIFYPEER, 0);
		curl_easy_setopt(mcurl, CURLOPT_SSL_VERIFYHOST, 0);

		#ifdef OS_WIN32
			curl_easy_setopt(mcurl, CURLOPT_RANDOM_FILE, getRandomFileName() );	//VOXOX - JRT - 2009.09.30 - Improve OpenSSL initialization time.
		#endif
		
	}
	else 
	{
		snprintf(url_buf, sizeof(url_buf), "http://%s", url);
	}

	curl_easy_setopt(mcurl, CURLOPT_URL, url_buf);

	if (timeout > 0) {
		curl_easy_setopt(mcurl, CURLOPT_TIMEOUT, timeout);
	}

	/* FOLLOW REDIRECTION */
	curl_easy_setopt(mcurl, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(mcurl, CURLOPT_UNRESTRICTED_AUTH, 1);
	/* ****************** */

	if (proxy_addr && *proxy_addr != 0) {
		if (proxy_login && *proxy_login != 0) {
			if (!_LocalProxy.proxy_auth_type)
				_get_proxy_auth_type2(url, proxy_addr, proxy_port, timeout);

			snprintf(auth_buf, sizeof(auth_buf), "%s:%s", proxy_login, proxy_passwd);
			curl_easy_setopt(mcurl, CURLOPT_PROXYUSERPWD, auth_buf);

			if ((_LocalProxy.proxy_auth_type & CURLAUTH_BASIC) == CURLAUTH_BASIC) {
				curl_easy_setopt(mcurl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
			}
			else if ((_LocalProxy.proxy_auth_type & CURLAUTH_DIGEST) == CURLAUTH_DIGEST) {
				curl_easy_setopt(mcurl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
			}
			else if ((_LocalProxy.proxy_auth_type & CURLAUTH_NTLM) == CURLAUTH_NTLM) {
				curl_easy_setopt(mcurl, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
			}
		}
		snprintf(proxy_buf, sizeof(proxy_buf), "%s:%d", proxy_addr, proxy_port);
		curl_easy_setopt(mcurl, CURLOPT_PROXY, proxy_buf);
	}
	else {
		if (proxy_login && *proxy_login != 0) {
			if (!_LocalProxy.auth_type) {
				_get_auth_type(url, timeout);
			}

			snprintf(auth_buf, sizeof(auth_buf), "%s:%s", proxy_login, proxy_passwd);
			curl_easy_setopt(mcurl, CURLOPT_USERPWD, auth_buf);

			if ((_LocalProxy.proxy_auth_type & CURLAUTH_BASIC) == CURLAUTH_BASIC) {
				curl_easy_setopt(mcurl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
			}
			else if ((_LocalProxy.proxy_auth_type & CURLAUTH_DIGEST) == CURLAUTH_DIGEST) {
				curl_easy_setopt(mcurl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
			}
			else if ((_LocalProxy.proxy_auth_type & CURLAUTH_NTLM) == CURLAUTH_NTLM) {
				curl_easy_setopt(mcurl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
			}
		}

	}

	ret = curl_easy_perform(mcurl);
	curl_easy_getinfo(mcurl, CURLINFO_RESPONSE_CODE, &http_resp_code);
	if (!_LocalProxy.proxy_auth_type) {
		curl_easy_getinfo(mcurl, CURLINFO_PROXYAUTH_AVAIL, &(_LocalProxy.proxy_auth_type));
	}

	HttpRet http_ret;
	/* If this is a redirection */
	if ((http_resp_code / 100) == 3) {
		NETLIB_BOOLEAN is_ssl;
		char *redir_tmp = 0;
		char *redir_url = 0;
		char *tmp;

		curl_easy_getinfo(mcurl, CURLINFO_EFFECTIVE_URL, &redir_tmp);
		if (redir_tmp) {
			redir_url = strdup(redir_tmp);
			curl_easy_cleanup(mcurl);

			if ((is_ssl = is_https(redir_url)) == NETLIB_TRUE) {
				tmp = redir_url + 8;
			}
			else {
				tmp = redir_url + 7;
			}

			if (is_url_proxyless_exception(tmp)) {
				http_ret = is_http_conn_allowed(tmp, NULL, 0, proxy_login, proxy_passwd, is_ssl, timeout);
			}
			else {
				http_ret = is_http_conn_allowed(tmp, proxy_addr, proxy_port, proxy_login, proxy_passwd, is_ssl, timeout);
			}
			free(redir_url);
		}
		else {
			curl_easy_cleanup(mcurl);
			http_ret = HTTP_NOK;
		}
		return http_ret;
	}

	if (http_resp_code == 200) {
		http_ret = HTTP_OK;
	}
	else if (http_resp_code != 404 && http_resp_code != 200 && http_resp_code != 0) {
		http_ret = HTTP_AUTH;
	}
	else {
		http_ret = HTTP_NOK;
	}

	curl_easy_cleanup(mcurl);
	return http_ret;
}
Exemplo n.º 4
0
void handle_request(worker_type_t wtype) {
    const char *param, *p_method, *p_uri;
    char *argp;
    unsigned int plen;
    int cluster_readonly = 0, s2sreq = 0;

    if(sx_hashfs_cluster_get_mode(hashfs, &cluster_readonly)) {
        CRIT("Failed to get cluster operating mode");
        quit_errmsg(500, "Internal error: failed to check cluster operating mode");
    }

    if(sx_hashfs_distcheck(hashfs) < 0) {
	CRIT("Failed to reload distribution");
	quit_errmsg(503, "Internal error: failed to load distribution");
    }

    if(sx_hashfs_is_orphan(hashfs))
	quit_errmsg(410, "This node is no longer a cluster member");

    msg_new_id();
    verb = VERB_UNSUP;
    p_method = FCGX_GetParam("REQUEST_METHOD", envp);
    if(p_method) {
	plen = strlen(p_method);
	switch(plen) {
	case 3:
	    if(!memcmp(p_method, "GET", 4))
		verb = VERB_GET;
	    else if(!memcmp(p_method, "PUT", 4))
		verb = VERB_PUT;
	    break;
	case 4:
	    if(!memcmp(p_method, "HEAD", 5))
		verb = VERB_HEAD;
	    else if(!memcmp(p_method, "POST", 5))
		verb = VERB_POST;
	    break;
	case 6:
	    if(!memcmp(p_method, "DELETE", 7))
		verb = VERB_DELETE;
	    break;
	case 7:
	    if(!memcmp(p_method, "OPTIONS", 8)) {
		CGI_PUTS("Allow: GET,HEAD,OPTIONS,PUT,DELETE\r\nContent-Length: 0\r\n\r\n");
		return;
	    }
	    break;
	}
    }
    if(verb == VERB_UNSUP)
	quit_errmsg(405, "Method Not Allowed");

    if(content_len()<0 || (verb != VERB_PUT && content_len()))
	quit_errmsg(400, "Invalid Content-Length: must be positive and method must be PUT");

    p_uri = param = FCGX_GetParam("REQUEST_URI", envp);
    if(!p_uri)
	quit_errmsg(400, "No URI provided");
    plen = strlen(p_uri);
    if(*p_uri != '/')
	quit_errmsg(400, "URI must start with /");
    if(plen > sizeof(reqbuf) - 1)
	quit_errmsg(414, "URL too long: request line must be <8k");

    do {
	param++;
	plen--;
    } while(*param == '/');

    if(!strncmp(param, ".s2s/", lenof(".s2s/"))) {
	param += lenof(".s2s/");
	plen -= lenof(".s2s/");
	while(*param == '/') {
	    param++;
	    plen--;
	}
	s2sreq = 1;
    }
    if(wtype == WORKER_S2S && !s2sreq)
	WARN("Misconfiguration detected. Please make sure your restricted-socket config option is properly set.");
    /* FIXME: we could detect the opposite kind of mismatch
     * at the cost of extra complications in the wtype definition
     * I prefer to privilege simplicity at this point */

    memcpy(reqbuf, param, plen+1);
    argp = memchr(reqbuf, '?', plen);
    nargs = 0;
    if(argp) {
	unsigned int argslen = plen - (argp - reqbuf);
	plen = argp - reqbuf;
	do {
	    *argp = '\0';
	    argp++;
	    argslen--;
	} while(*argp == '?');
	if(!argslen)
	    argp = NULL;
	else {
	    do {
		char *nextarg;
		if(nargs >= MAX_ARGS)
		    quit_errmsg(414, "Too many parameters");
		nextarg = memchr(argp, '&', argslen);
		if(nextarg) {
		    do {
			*nextarg = '\0';
			nextarg++;
		    } while(*nextarg == '&');
		}
		if(*argp) {
		    if(!(args[nargs] = inplace_urldecode(argp, 0, 0, NULL, 1)))
			quit_errmsg(400, "Invalid URL encoding");
		    if(sxi_utf8_validate_len(args[nargs]) < 0)
			quit_errmsg(400, "Parameters with invalid utf-8 encoding");
		    nargs++;
		}
		argslen -= nextarg - argp;
		argp = nextarg;
	    } while (argp);
	}
    }

    while(plen && reqbuf[plen-1] == '/') {
	plen--;
	reqbuf[plen] = '\0';
    }

    path = memchr(reqbuf, '/', plen);
    if(path) {
	do {
	    *path = '\0';
	    path ++;
	} while(*path == '/');
	if(!*path)
	    path = NULL;
    }
    volume = *reqbuf ? reqbuf : NULL;

    int forbidden = 0;
    if((volume && !inplace_urldecode(volume, '/', 0, &forbidden, 0)) || (path && !inplace_urldecode(path, '/', '/', &forbidden, 0))) {
        if (forbidden)
            quit_errmsg(400, "Volume or path with forbidden %2f or %00");
        else
            quit_errmsg(400, "Invalid URL encoding");
    }

    int vlen = volume ? sxi_utf8_validate_len(volume) : 0;
    int flen = path ? strlen(path) : 0;

    if (vlen < 0 || flen < 0)
       quit_errmsg(400, "URL with invalid utf-8 encoding");

    if (is_reserved()) {
        /* No UTF8/url-encoding used on reserved volumes, allow higher limit.
         * Otherwise we hit the 1024 limit with batch requests already */
        if (path && strlen(path) > SXLIMIT_MAX_FILENAME_LEN * 3) {
            msg_set_reason("Path too long: filename must be <%d bytes (%ld)",
                           SXLIMIT_MAX_FILENAME_LEN*3+ 1, strlen(path));
            quit_errmsg(414, msg_get_reason());
        }
    } else {
        if (flen > SXLIMIT_MAX_FILENAME_LEN) {
            msg_set_reason("Path too long: filename must be <%d bytes (%d)",
                           SXLIMIT_MAX_FILENAME_LEN + 1, flen);
            quit_errmsg(414, msg_get_reason());
        }
    }

    if (volume && strlen(volume) > SXLIMIT_MAX_VOLNAME_LEN) {
        msg_set_reason("Volume name too long: must be <= %d bytes", SXLIMIT_MAX_VOLNAME_LEN);
        quit_errmsg(414, msg_get_reason());
    }

    body_ctx = sxi_md_init();
    if (!body_ctx || !sxi_sha1_init(body_ctx))
	quit_errmsg(500, "Failed to initialize crypto engine");
    hmac_ctx = sxi_hmac_sha1_init();
    if (!hmac_ctx)
        quit_errmsg(503, "Cannot initialize crypto library");

    authed = AUTH_NOTAUTH;
    role = PRIV_NONE;


    /* Begin auth check */
    uint8_t buf[AUTHTOK_BIN_LEN], key[AUTH_KEY_LEN];
    unsigned int blen = sizeof(buf);
    time_t reqdate, now;

    param = FCGX_GetParam("HTTP_AUTHORIZATION", envp);
    if(!param || strlen(param) != lenof("SKY ") + AUTHTOK_ASCII_LEN || strncmp(param, "SKY ", 4)) {
	if(volume) {
	    send_authreq();
	    return;
	}
	quit_home();
    }

    if(sxi_b64_dec_core(param+4, buf, &blen) || blen != sizeof(buf)) {
	send_authreq();
	return;
    }

    memcpy(user, buf, sizeof(user));
    memcpy(rhmac, buf+20, sizeof(rhmac));

    if(sx_hashfs_get_user_info(hashfs, user, &uid, key, &role, NULL, &user_quota) != OK) /* no such user */ {
	DEBUG("No such user: %s", param+4);
	send_authreq();
	return;
    }
    DEBUG("Request from uid %lld", (long long)uid);
    if(cluster_readonly && (verb == VERB_PUT || verb == VERB_DELETE) && !has_priv(PRIV_CLUSTER) && !has_priv(PRIV_ADMIN))
        quit_errmsg(503, "Cluster is in read-only mode");

    if(s2sreq && !has_priv(PRIV_CLUSTER)) {
	send_authreq();
	return;
    }

    if(!sxi_hmac_sha1_init_ex(hmac_ctx, key, sizeof(key))) {
	WARN("hmac_init failed");
	quit_errmsg(500, "Failed to initialize crypto engine");
    }

    if(!sxi_hmac_sha1_update_str(hmac_ctx, p_method))
	quit_errmsg(500, "Crypto error authenticating the request");

    if(!sxi_hmac_sha1_update_str(hmac_ctx, p_uri+1))
	quit_errmsg(500, "Crypto error authenticating the request");

    param = FCGX_GetParam("HTTP_DATE", envp);
    if(!param)
	quit_errmsg(400, "Missing Date: header");
    if(httpdate_to_time_t(param, &reqdate))
	quit_errmsg(400, "Date header in wrong format");
    now = time(NULL);
    if(reqdate < now - MAX_CLOCK_DRIFT * 60 || reqdate > now + MAX_CLOCK_DRIFT * 60) {
	CGI_PUTS("WWW-Authenticate: SKY realm=\"SXCLOCK\"\r\n");
	quit_errmsg(401, "Client clock drifted more than "STRIFY(MAX_CLOCK_DRIFT)" minutes");
    }
    if(!sxi_hmac_sha1_update_str(hmac_ctx, param))
	quit_errmsg(500, "Crypto error authenticating the request");

    if(!content_len()) {
	/* If no body is present, complete authentication now */
	uint8_t chmac[20];
	unsigned int chmac_len = 20;
	if(!sxi_hmac_sha1_update_str(hmac_ctx, "da39a3ee5e6b4b0d3255bfef95601890afd80709"))
	    quit_errmsg(500, "Crypto error authenticating the request");
	if(!sxi_hmac_sha1_final(hmac_ctx, chmac, &chmac_len))
	    quit_errmsg(500, "Crypto error authenticating the request");
	if(!hmac_compare(chmac, rhmac, sizeof(rhmac))) {
	    authed = AUTH_OK;
	} else {
	    /* WARN("auth mismatch"); */
	    send_authreq();
	    return;
	}
    } else /* Otherwise set it as pending */
	authed = AUTH_BODYCHECK;

    if(has_priv(PRIV_CLUSTER) && sx_hashfs_uses_secure_proto(hashfs) != is_https() &&
       !sx_storage_is_bare(hashfs)) {
        /* programmed nodes: must obey cluster SSL mode
         * unprogrammed nodes: can use SSL instead of non-SSL,
         *  it is the cluster's responsibility to initiate programming via SSL,
         *  as the unprogrammed node would accept both         *
         * */
        WARN("hashfs use-ssl: %d, https: %d, is_bare: %d",
              sx_hashfs_uses_secure_proto(hashfs), is_https(),
              sx_storage_is_bare(hashfs));
	quit_errmsg(403, sx_hashfs_uses_secure_proto(hashfs) ? "Cluster operations require SECURE mode" : "Cluster operations require INSECURE mode");
    }

    if(!volume)
	cluster_ops();
    else if(!path)
	volume_ops();
    else
	file_ops();

    if(authed == AUTH_BODYCHECKING)
	DEBUG("Bad request signature");

    sxi_hmac_sha1_cleanup(&hmac_ctx);
    sxi_md_cleanup(&body_ctx);
}
static int check_for_cookie(void *rec, const char *key, const char *value) {
    if (strcasecmp("Cookie", key) == 0) {
        check_for_cookie_data_t *data = rec;
        if (data->cookie_name == NULL) {
            crowd_cookie_config_t *cookie_config = crowd_get_cookie_config(data->r, data->config->crowd_config);
            if (cookie_config == NULL || cookie_config->cookie_name == NULL || (cookie_config->secure && !is_https(data->r))) {
                return 0;
            }
            data->cookie_name = log_ralloc(data->r, apr_pstrcat(data->r->pool, cookie_config->cookie_name, "=", NULL));
            if (data->cookie_name == NULL) {
                return 0;
            }
            data->cookie_name_len = strlen(data->cookie_name);
        }
        char *cookies = log_ralloc(data->r, apr_pstrdup(data->r->pool, value));
        if (cookies == NULL) {
            return 0;
        }
        apr_collapse_spaces(cookies, cookies);
        char *last;
        char *cookie = apr_strtok(cookies, ";,", &last);
        while (cookie != NULL) {
            if (strncasecmp(cookie, data->cookie_name, data->cookie_name_len) == 0) {
                data->token = log_ralloc(data->r, apr_pstrdup(data->r->pool, cookie + data->cookie_name_len));
                return 0;
            }
            cookie = apr_strtok(NULL, ";,", &last);
        }
    }
    return 1;
}
Exemplo n.º 6
0
void handle_request(void) {
    const char *param;
    char *argp;
    unsigned int plen;

    msg_new_id();
    verb = VERB_UNSUP;
    param = FCGX_GetParam("REQUEST_METHOD", envp);
    if(param) {
	plen = strlen(param);
	switch(plen) {
	case 3:
	    if(!memcmp(param, "GET", 4))
		verb = VERB_GET;
	    else if(!memcmp(param, "PUT", 4))
		verb = VERB_PUT;
	    break;
	case 4:
	    if(!memcmp(param, "HEAD", 5))
		verb = VERB_HEAD;
	    else if(!memcmp(param, "POST", 5))
		verb = VERB_POST;
	    break;
	case 6:
	    if(!memcmp(param, "DELETE", 7))
		verb = VERB_DELETE;
	    break;
	case 7:
	    if(!memcmp(param, "OPTIONS", 8)) {
		CGI_PUTS("Allow: GET,HEAD,OPTIONS,PUT,DELETE\r\nContent-Length: 0\r\n\r\n");
		return;
	    }
	    break;
	}
    }
    if(verb == VERB_UNSUP)
	quit_errmsg(405, "Method Not Allowed");

    if(content_len()<0 || (verb != VERB_PUT && content_len()))
	quit_errmsg(400, "Invalid Content-Length: must be positive and method must be PUT");

    param = FCGX_GetParam("REQUEST_URI", envp);
    if(!param)
	quit_errmsg(400, "No URI provided");
    plen = strlen(param);
    if(*param != '/')
	quit_errmsg(400, "URI must start with /");
    if(plen > sizeof(reqbuf) - 1)
	quit_errmsg(414, "URL too long: request line must be <8k");

    do {
	param++;
	plen--;
    } while(*param == '/');

    memcpy(reqbuf, param, plen+1);
    argp = memchr(reqbuf, '?', plen);
    nargs = 0;
    if(argp) {
	unsigned int argslen = plen - (argp - reqbuf);
	plen = argp - reqbuf;
	do {
	    *argp = '\0';
	    argp++;
	    argslen--;
	} while(*argp == '?');
	if(!argslen)
	    argp = NULL;
	else {
	    do {
		char *nextarg;
		if(nargs >= MAX_ARGS)
		    quit_errmsg(414, "Too many parameters");
		nextarg = memchr(argp, '&', argslen);
		if(nextarg) {
		    do {
			*nextarg = '\0';
			nextarg++;
		    } while(*nextarg == '&');
		}
		if(*argp) {
		    if(!(args[nargs] = inplace_urldecode(argp, 0, 0, NULL)))
			quit_errmsg(400, "Invalid URL encoding");
		    if(utf8_validate_len(args[nargs]) < 0)
			quit_errmsg(400, "Parameters with invalid utf-8 encoding");
		    nargs++;
		}
		argslen -= nextarg - argp;
		argp = nextarg;
	    } while (argp);
	}
    }

    while(plen && reqbuf[plen-1] == '/') {
	plen--;
	reqbuf[plen] = '\0';
    }

    path = memchr(reqbuf, '/', plen);
    if(path) {
	do {
	    *path = '\0';
	    path ++;
	} while(*path == '/');
	if(!*path)
	    path = NULL;
    }
    volume = *reqbuf ? reqbuf : NULL;

    int forbidden = 0;
    if((volume && !inplace_urldecode(volume, '/', 0, &forbidden)) || (path && !inplace_urldecode(path, '/', '/', &forbidden))) {
        if (forbidden)
            quit_errmsg(400, "Volume or path with forbidden %2f or %00");
        else
            quit_errmsg(400, "Invalid URL encoding");
    }

    int vlen = volume ? utf8_validate_len(volume) : 0;
    int flen = path ? utf8_validate_len(path) : 0;

    if (vlen < 0 || flen < 0)
       quit_errmsg(400, "URL with invalid utf-8 encoding");

    if (is_reserved()) {
        /* No UTF8 used on reserved volumes, allow higher limit.
         * Otherwise we hit the 512 limit with batch requests already */
        if (path && strlen(path) > SXLIMIT_MAX_FILENAME_LEN * 12) {
            msg_set_reason("Path too long: filename must be <%d characters (%ld)",
                           SXLIMIT_MAX_FILENAME_LEN*12+ 1, strlen(path));
            quit_errmsg(414, msg_get_reason());
        }
    } else {
        if (flen > SXLIMIT_MAX_FILENAME_LEN) {
            msg_set_reason("Path too long: filename must be <%d UTF8 characters (%d)",
                           SXLIMIT_MAX_FILENAME_LEN + 1, flen);
            quit_errmsg(414, msg_get_reason());
        }
    }

    if (volume && strlen(volume) > SXLIMIT_MAX_VOLNAME_LEN) {
        msg_set_reason("Volume name too long: must be <= %d bytes", SXLIMIT_MAX_VOLNAME_LEN);
        quit_errmsg(414, msg_get_reason());
    }

    if(!EVP_DigestInit(&body_ctx, EVP_sha1()))
	quit_errmsg(500, "Failed to initialize crypto engine");
    HMAC_CTX_init(&hmac_ctx);

    authed = AUTH_NOTAUTH;
    role = PRIV_NONE;
    auth_begin();

    if(has_priv(PRIV_CLUSTER) && sx_hashfs_uses_secure_proto(hashfs) != is_https() &&
       !sx_storage_is_bare(hashfs)) {
        /* programmed nodes: must obey cluster SSL mode
         * unprogrammed nodes: can use SSL instead of non-SSL,
         *  it is the cluster's responsibility to initiate programming via SSL,
         *  as the unprogrammed node would accept both         *
         * */
        WARN("hashfs use-ssl: %d, https: %d, is_bare: %d",
              sx_hashfs_uses_secure_proto(hashfs), is_https(),
              sx_storage_is_bare(hashfs));
	quit_errmsg(403, sx_hashfs_uses_secure_proto(hashfs) ? "Cluster operations require SECURE mode" : "Cluster operations require INSECURE mode");
    }

    int dc = sx_hashfs_distcheck(hashfs);
    if(dc < 0) {
	CRIT("Failed to reload distribution");
	/* MODHDIST: should die here */
    }

    if(!volume)
	cluster_ops();
    else if(!path)
	volume_ops();
    else
	file_ops();

    if(authed == AUTH_BODYCHECKING)
	WARN("FIXME: Security fail");

    HMAC_CTX_cleanup(&hmac_ctx);
    EVP_MD_CTX_cleanup(&body_ctx);
}
Exemplo n.º 7
0
glite_delegation_ctx *glite_delegation_new(const char *endpoint)
{
    int ret;
    glite_delegation_ctx *ctx;

    ctx = calloc(sizeof(*ctx), 1);
    if(!ctx)
        return NULL;


    if( (! is_http(endpoint)) && (! is_https(endpoint)) && (! is_httpg(endpoint)) ) 
    {
        char *error;
        
        char *sd_type = getenv(GLITE_DELEGATION_SD_ENV);
        if(!sd_type)
            sd_type = GLITE_DELEGATION_SD_TYPE;
        
        ctx->endpoint = glite_discover_endpoint(sd_type, endpoint, &error);

        if (!ctx->endpoint)
        {
            glite_delegation_set_error(ctx, "glite_delegation: service discovery error %s", error);
            free(error);
            return ctx;
        }
    }
    else 
    {
        ctx->endpoint = strdup(endpoint);
        if (!ctx->endpoint)
        {
            glite_delegation_set_error(ctx, "glite_delegation: out of memory");
            return ctx;
        }
    }
    
    ctx->soap = soap_new();
    /* Register the CGSI plugin if secure communication is requested */
    if (is_https(ctx->endpoint))
        ret = soap_cgsi_init(ctx->soap,
            CGSI_OPT_DISABLE_NAME_CHECK |
            CGSI_OPT_SSL_COMPATIBLE);
    else if (is_httpg(ctx->endpoint))
        ret = soap_cgsi_init(ctx->soap,
            CGSI_OPT_DISABLE_NAME_CHECK);
    else
        ret = 0;

    if (ret)
    {
        glite_delegation_set_error(ctx, "Failed to initialize the GSI plugin");
        return ctx;
    }

    /* Namespace setup should happen after CGSI plugin initialization */
    if ( soap_set_namespaces(ctx->soap, delegation_namespaces) )
    {
        _fault_to_error(ctx, "Setting SOAP namespaces");
        return ctx;
    }

    return ctx;
}