Exemple #1
0
static struct music_file *new_music_file(const char *spath, const char *lpath)
{
	struct music_file *p = calloc(1, sizeof(*p));

	if (p == NULL)
		return p;

	p->shortpath = buffer_init();

	if (p->shortpath == NULL) {
		free(p);
		return NULL;
	}

	p->longpath = buffer_init();

	if (p->longpath == NULL) {
		buffer_free(p->shortpath);
		free(p);
		return NULL;
	}

	buffer_copy_string(p->shortpath, spath);
	buffer_copy_string(p->longpath, lpath);

	p->next = NULL;

	return p;
}
Exemple #2
0
static void proxy_set_header(connection *con, const char *key, const char *value) {
    data_string *ds_dst;

    if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
          ds_dst = data_string_init();
    }

    buffer_copy_string(ds_dst->key, key);
    buffer_copy_string(ds_dst->value, value);
    array_insert_unique(con->request.headers, (data_unset *)ds_dst);
}
Exemple #3
0
static int ssi_env_add(array *env, const char *key, const char *val) {
	data_string *ds;

	if (NULL == (ds = (data_string *)array_get_unused_element(env, TYPE_STRING))) {
		ds = data_string_init();
	}
	buffer_copy_string(ds->key,   key);
	buffer_copy_string(ds->value, val);

	array_insert_unique(env, (data_unset *)ds);

	return 0;
}
static int magnet_env_set(lua_State *L) {
	server *srv;
	connection *con;

	const char *key = luaL_checkstring(L, 2);
	const char *val = luaL_checkstring(L, 3);
	buffer *dest = NULL;

	lua_pushstring(L, "lighty.srv");
	lua_gettable(L, LUA_REGISTRYINDEX);
	srv = lua_touserdata(L, -1);
	lua_pop(L, 1);

	lua_pushstring(L, "lighty.con");
	lua_gettable(L, LUA_REGISTRYINDEX);
	con = lua_touserdata(L, -1);
	lua_pop(L, 1);

	if (NULL != (dest = magnet_env_get_buffer(srv, con, key))) {
		buffer_copy_string(dest, val);
	} else {
		/* couldn't save */

		return luaL_error(L, "couldn't store '%s' in lighty.env[]", key);
	}

	return 0;
}
void query_one_hostname(){
	smb_srv_info_t *p;
	for (p = smb_srv_info_list; p; p = p->next) {

		if(strcmp(p->name->ptr, "")!=0){
			continue;
		}

		if(p->id==0){
			Cdbg(DBE, "query_one_hostname [%s]\n", p->ip->ptr);
			//continue;
		}

		char* hostname = smbc_nmblookup(p->ip->ptr);
		
		if(hostname==NULL){
			//Cdbg(DBE, "\t\tCan't query samba server name[%s]\n", p->ip->ptr);

			buffer_free(p->ip);
			buffer_free(p->mac);
			buffer_free(p->name);
			
			DLIST_REMOVE(smb_srv_info_list, p);
			free(p);
		}
		else{
			buffer_copy_string(p->name, hostname);
		}
	}
}
Exemple #6
0
buffer *buffer_init_string(const char *str) {
	buffer *b = buffer_init();

	buffer_copy_string(b, str);

	return b;
}
static void test_configfile_addrbuf_eq_remote_ip_mask (void) {
	int i, m;
	buffer * const s = buffer_init();
	sock_addr rmt;

	for (i = 0; i < (int)(sizeof(rmtmask)/sizeof(rmtmask[0])); ++i) {
	      #ifndef HAVE_INET_PTON
		rmt.ipv4.sin_family = AF_INET;
		rmt.ipv4.sin_addr.s_addr = inet_addr(rmtmask[i].rmtstr);
	      #else
		if (rmtmask[i].rmtfamily == AF_INET) {
			rmt.ipv4.sin_family = AF_INET;
			inet_pton(AF_INET, rmtmask[i].rmtstr, &rmt.ipv4.sin_addr);
		#ifdef HAVE_IPV6
		} else if (rmtmask[i].rmtfamily == AF_INET6) {
			rmt.ipv6.sin6_family = AF_INET6;
			inet_pton(AF_INET6, rmtmask[i].rmtstr, &rmt.ipv6.sin6_addr);
		#endif
		} else {
			continue;
		}
	      #endif
		buffer_copy_string(s, rmtmask[i].string);
		m = config_addrbuf_eq_remote_ip_mask(NULL,s,strchr(s->ptr,'/'),&rmt);
		if (m != rmtmask[i].expect) {
			fprintf(stderr, "failed assertion: %s %s %s\n",
				rmtmask[i].string,
				rmtmask[i].expect ? "==" : "!=",
				rmtmask[i].rmtstr);
			exit(-1);
		}
	}

	buffer_free(s);
}
Exemple #8
0
static int proxy_create_env(server *srv, handler_ctx *hctx) {
	size_t i;

	connection *con   = hctx->remote_conn;
	buffer *b;

	/* build header */

	b = buffer_init();

	/* request line */
	buffer_copy_string(b, get_http_method_name(con->request.http_method));
	buffer_append_string_len(b, CONST_STR_LEN(" "));

	buffer_append_string_buffer(b, con->request.uri);
	buffer_append_string_len(b, CONST_STR_LEN(" HTTP/1.0\r\n"));

	proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
	/* http_host is NOT is just a pointer to a buffer
	 * which is NULL if it is not set */
	if (!buffer_string_is_empty(con->request.http_host)) {
		proxy_set_header(con, "X-Host", con->request.http_host->ptr);
	}
	proxy_set_header(con, "X-Forwarded-Proto", con->uri.scheme->ptr);

	/* request header */
	for (i = 0; i < con->request.headers->used; i++) {
		data_string *ds;

		ds = (data_string *)con->request.headers->data[i];

		if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
			if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
			if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Proxy-Connection"))) continue;

			buffer_append_string_buffer(b, ds->key);
			buffer_append_string_len(b, CONST_STR_LEN(": "));
			buffer_append_string_buffer(b, ds->value);
			buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
		}
	}

	buffer_append_string_len(b, CONST_STR_LEN("\r\n"));

	hctx->wb->bytes_in += buffer_string_length(b);
	chunkqueue_append_buffer(hctx->wb, b);
	buffer_free(b);

	/* body */

	if (con->request.content_length) {
		chunkqueue *req_cq = con->request_content_queue;

		chunkqueue_steal(hctx->wb, req_cq, req_cq->bytes_in);
	}

	return 0;
}
static void aicloud_connection_smb_info_url_patch(server *srv, connection *con)
{
	char strr[2048]="\0";
	char uri[2048]="\0";
	
	UNUSED(srv);
	
	char* pch = strchr(con->request.uri->ptr,'?');
	if(pch){	
		buffer_copy_string_len(con->url_options, pch+1, strlen(pch)-1);
		int len = pch-con->request.uri->ptr;
		strncpy(uri,con->request.uri->ptr, len);
	}
	else{
		strcpy(uri,con->request.uri->ptr);
	}
	
	if(con->mode == DIRECT){
		sprintf(strr, "%s", uri);
	}
	else {
		if(con->smb_info&&con->smb_info->server->used) {
			if(con->mode == SMB_BASIC){
				if(con->smb_info->username->used&&con->smb_info->password->used){
					sprintf(strr, "smb://%s:%[email protected]%s", con->smb_info->username->ptr, con->smb_info->password->ptr, uri+1);
				}
				else
					sprintf(strr, "smb://%s", uri+1);
			}
			else if(con->mode == SMB_NTLM){
				sprintf(strr, "smb://%s", uri+1);		
			}
		} else {
			sprintf(strr, "smb://");
		}
	}

	buffer_copy_string(con->url.path, strr);
	buffer_copy_string(con->url.rel_path, uri);	

	buffer_urldecode_path(con->url.path);
	buffer_urldecode_path(con->url.rel_path);
	
}
Exemple #10
0
static int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) {
	const char *servername;
	connection *con = (connection *) SSL_get_app_data(ssl);
	UNUSED(al);

	buffer_copy_string(con->uri.scheme, "https");

	if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
#if 0
		/* this "error" just means the client didn't support it */
		log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
				"failed to get TLS server name");
#endif
		return SSL_TLSEXT_ERR_NOACK;
	}
	buffer_copy_string(con->tlsext_server_name, servername);
	buffer_to_lower(con->tlsext_server_name);

	/* Sometimes this is still set, confusing COMP_HTTP_HOST */
	buffer_reset(con->uri.authority);

	config_cond_cache_reset(srv, con);
	config_setup_connection(srv, con);

	config_patch_connection(srv, con, COMP_SERVER_SOCKET);
	config_patch_connection(srv, con, COMP_HTTP_SCHEME);
	config_patch_connection(srv, con, COMP_HTTP_HOST);

	if (NULL == con->conf.ssl_ctx) {
		/* ssl_ctx <=> pemfile was set <=> ssl_ctx got patched: so this should never happen */
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
			"null SSL_CTX for TLS server name", con->tlsext_server_name);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	/* switch to new SSL_CTX in reaction to a client's server_name extension */
	if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) {
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
			"failed to set SSL_CTX for TLS server name", con->tlsext_server_name);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	return SSL_TLSEXT_ERR_OK;
}
Exemple #11
0
connection *connection_accepted(server *srv, server_socket *srv_socket, sock_addr *cnt_addr, int cnt) {
		connection *con;

		srv->cur_fds++;

		/* ok, we have the connection, register it */
#if 0
		log_error_write(srv, __FILE__, __LINE__, "sd",
				"appected()", cnt);
#endif
		srv->con_opened++;

		con = connections_get_new_connection(srv);

		con->fd = cnt;
		con->fde_ndx = -1;
		fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);

		connection_set_state(srv, con, CON_STATE_REQUEST_START);

		con->connection_start = srv->cur_ts;
		con->dst_addr = *cnt_addr;
		buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
		con->srv_socket = srv_socket;

		if (-1 == fdevent_fcntl_set_nb_cloexec_sock(srv->ev, con->fd)) {
			log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
			connection_close(srv, con);
			return NULL;
		}
#ifdef USE_OPENSSL
		/* connect FD to SSL */
		if (srv_socket->is_ssl) {
			if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
						ERR_error_string(ERR_get_error(), NULL));

				connection_close(srv, con);
				return NULL;
			}

			con->renegotiations = 0;
			SSL_set_app_data(con->ssl, con);
			SSL_set_accept_state(con->ssl);

			if (1 != (SSL_set_fd(con->ssl, cnt))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
						ERR_error_string(ERR_get_error(), NULL));
				connection_close(srv, con);
				return NULL;
			}
		}
#endif
		return con;
}
Exemple #12
0
static int chmEnum(struct chmFile *h, struct chmUnitInfo *ui, void *context)
{
	t_win_menuitem item;
	t_fs_filetype ft;
	char fname[PATH_MAX] = "";
	char t[20];

	int size = strlen(ui->path);

	if (size == 0 || ui->path[size - 1] == '/')
		return CHM_ENUMERATOR_CONTINUE;

	ft = fs_file_get_type(ui->path);

	if (ft == fs_filetype_chm || ft == fs_filetype_zip || ft == fs_filetype_rar || ft == fs_filetype_umd || ft == fs_filetype_pdb)
		return CHM_ENUMERATOR_CONTINUE;

	win_menuitem_new(&item);
	buffer_copy_string(item.compname, ui->path);
	SPRINTF_S(t, "%u", (unsigned int) ui->length);
	buffer_copy_string(item.shortname, t);
	if (ui->path[0] == '/') {
		strncpy_s(fname, NELEMS(fname), ui->path + 1, 256);
	} else {
		strncpy_s(fname, NELEMS(fname), ui->path, 256);
	}

	charsets_utf8_conv((unsigned char *) fname, sizeof(fname), (unsigned char *) fname, sizeof(fname));

	item.data = (void *) ft;
	filename_to_itemname(&item, fname);
	item.selected = false;
	item.icolor = ((p_fs_chm_enum) context)->icolor;
	item.selicolor = ((p_fs_chm_enum) context)->selicolor;
	item.selrcolor = ((p_fs_chm_enum) context)->selrcolor;
	item.selbcolor = ((p_fs_chm_enum) context)->selbcolor;
	item.data3 = ui->length;
	win_menu_add(g_menu, &item);

	return CHM_ENUMERATOR_CONTINUE;
}
Exemple #13
0
void query_one_hostname(void)
{
	smb_srv_info_t *p;
	int bchange = 0;
	
	for (p = smb_srv_info_list; p; p = p->next) {
		if(is_shutdown || g_kill_list)
			break;

		Cdbg(DBE, "Query samba server name, ip=[%s]", p->ip->ptr);
		const char *hostname = smbc_nmblookup(p->ip->ptr);
		
		if( strcmp(p->name->ptr, "")!=0&&
		    hostname!=NULL && 
		    strcmp(p->name->ptr, hostname)==0 &&
		    p->online ==1 ){	

			if(hostname){
				free((char*) hostname);
				hostname=NULL;
			}
			
			continue;
		}
		
		if(hostname==NULL){
			if(p->online==1){
				p->online = 0;
				bchange = 1;
				Cdbg(DBE, "Can't query samba server name, set ip=[%s] offline", p->ip->ptr);
			}
		}
		else{			
			p->online = 1;
			buffer_reset(p->name);
			buffer_copy_string(p->name, hostname);
			bchange = 1;
			Cdbg(DBE, "query samba server name[%s], set ip=[%s] online", hostname, p->ip->ptr );			
		}	

		if(bchange==1)
			save_arpping_list();

		if(hostname){
			free((char*) hostname);
			hostname=NULL;
		}
	}

	//if(bchange==1)
	//	save_arpping_list();
	
}
Exemple #14
0
static buffer *magnet_env_get_buffer_by_id(server *srv, connection *con, int id) {
	buffer *dest = NULL;

	UNUSED(srv);

	/**
	 * map all internal variables to lua
	 *
	 */

	switch (id) {
	case MAGNET_ENV_PHYICAL_PATH: dest = con->physical.path; break;
	case MAGNET_ENV_PHYICAL_REL_PATH: dest = con->physical.rel_path; break;
	case MAGNET_ENV_PHYICAL_DOC_ROOT: dest = con->physical.doc_root; break;
	case MAGNET_ENV_PHYICAL_BASEDIR: dest = con->physical.basedir; break;

	case MAGNET_ENV_URI_PATH: dest = con->uri.path; break;
	case MAGNET_ENV_URI_PATH_RAW: dest = con->uri.path_raw; break;
	case MAGNET_ENV_URI_SCHEME: dest = con->uri.scheme; break;
	case MAGNET_ENV_URI_AUTHORITY: dest = con->uri.authority; break;
	case MAGNET_ENV_URI_QUERY: dest = con->uri.query; break;

	case MAGNET_ENV_REQUEST_METHOD:
		buffer_copy_string(srv->tmp_buf, get_http_method_name(con->request.http_method));
		dest = srv->tmp_buf;
		break;
	case MAGNET_ENV_REQUEST_URI:      dest = con->request.uri; break;
	case MAGNET_ENV_REQUEST_ORIG_URI: dest = con->request.orig_uri; break;
	case MAGNET_ENV_REQUEST_PATH_INFO: dest = con->request.pathinfo; break;
	case MAGNET_ENV_REQUEST_REMOTE_IP: dest = con->dst_addr_buf; break;
	case MAGNET_ENV_REQUEST_PROTOCOL:
		buffer_copy_string(srv->tmp_buf, get_http_version_name(con->request.http_version));
		dest = srv->tmp_buf;
		break;

	case MAGNET_ENV_UNSET: break;
	}

	return dest;
}
int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
	data_string *ds;

	UNUSED(srv);

	/* if there already is a key by this name overwrite the value */
	if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) {
		buffer_copy_string(ds->value, value);

		return 0;
	}

	return response_header_insert(srv, con, key, keylen, value, vallen);
}
Exemple #16
0
void print_help()
{
	buffer * b=buffer_init();
	buffer_copy_string(b,
    "minihttpd is a simple,high-performance webserver\n" \
    "usage:\n" \
	"-f  configuration_file     specify the configuration file you want to load for minihttpd\n" \
	"-D  specify the minihttpd do not run as a deamon process\n"  \
	"-v  print the minihttpd version information\n"  \
    "-h  show help\n");

	fprintf(stdout,"%s",(const char*)b->ptr);
	buffer_free(b);
}
Exemple #17
0
static int add_parent_to_menu(p_win_menu menu, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor)
{
	t_win_menuitem item;

	if (menu == NULL) {
		return -1;
	}

	win_menuitem_new(&item);
	STRCPY_S(item.name, "<..>");
	buffer_copy_string(item.compname, "..");
	buffer_copy_string(item.shortname, "..");
	item.data = (void *) fs_filetype_dir;
	item.width = 4;
	item.selected = false;
	item.icolor = icolor;
	item.selicolor = selicolor;
	item.selrcolor = selrcolor;
	item.selbcolor = selbcolor;
	win_menu_add(menu, &item);

	return 0;
}
Exemple #18
0
void save_arpping_list(void)
{

#if EMBEDDED_EANBLE

	smb_srv_info_t* c;
	
	buffer* smbdav_list = buffer_init();
	buffer_copy_string(smbdav_list, "");

	for (c = smb_srv_info_list; c; c = c->next) {
		if(c->name->used == 0 || strcmp(c->name->ptr,"")==0)
			continue;

		char temp[50]="\0";
		sprintf(temp, "%s<%s<%s<%d>", c->name->ptr, c->ip->ptr, c->mac->ptr, c->online);
		buffer_append_string(smbdav_list, temp);
	}
	
	Cdbg(DBE, "nvram_set_smbdav_str %s", smbdav_list->ptr);
	nvram_set_smbdav_str(smbdav_list->ptr);

	buffer_free(smbdav_list);
#else
	unlink(g_temp_file);

	smb_srv_info_t* c;
	
	char mybuffer[100];
	FILE* fp = fopen(g_temp_file, "w");

	Cdbg(DBE, "save_arpping_list %s", g_temp_file);
	
	if(fp!=NULL){
		smb_srv_info_t* c;
	
		for (c = smb_srv_info_list; c; c = c->next) {
			if(c->name->used == 0 || strcmp(c->name->ptr,"")==0)
				continue;
			
			fprintf(fp, "%s<%s<%s<%d\n", c->name->ptr, c->ip->ptr, c->mac->ptr, c->online);
		}
		
		fclose(fp);
	}
#endif
}
Exemple #19
0
static int lua_to_c_get_string(lua_State *L, const char *varname, buffer *b) {
	int curelem = lua_gettop(L);
	int result;

	lua_getglobal(L, varname);

	if (lua_isstring(L, curelem)) {
		buffer_copy_string(b, lua_tostring(L, curelem));
		result = 0;
	} else {
		result = -1;
	}

	lua_pop(L, 1);
	force_assert(curelem == lua_gettop(L));
	return result;
}
Exemple #20
0
static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
	size_t i;

	for (i = 0; i < con->request.headers->used; i++) {
		data_string *ds;

		ds = (data_string *)con->request.headers->data[i];

		if (ds->value->used && ds->key->used) {
			size_t j;
			buffer_reset(srv->tmp_buf);

			/* don't forward the Authorization: Header */
			if (0 == strcasecmp(ds->key->ptr, "AUTHORIZATION")) {
				continue;
			}

			if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
				buffer_copy_string(srv->tmp_buf, "HTTP_");
				srv->tmp_buf->used--;
			}

			buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
			for (j = 0; j < ds->key->used - 1; j++) {
				char c = '_';
				if (light_isalpha(ds->key->ptr[j])) {
					/* upper-case */
					c = ds->key->ptr[j] & ~32;
				} else if (light_isdigit(ds->key->ptr[j])) {
					/* copy */
					c = ds->key->ptr[j];
				}
				srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
			}
			srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0';

			ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
		}
	}

	return 0;
}
Exemple #21
0
void smbc_wrapper_response_401(server *srv, connection *con)
{
	data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent");

	//- Browser response
	if( ds && (strstr( ds->value->ptr, "Mozilla" )||strstr( ds->value->ptr, "Opera" )) ){
		if(con->mode == SMB_BASIC||con->mode == DIRECT){
			Cdbg(DBE, "con->mode == SMB_BASIC -> return 401");
			con->http_status = 401;
			return;
		}
	}
	
	Cdbg(DBE, "smbc_wrapper_response_401 -> return 401");
	
	char str[50];

	UNUSED(srv);

	buffer* tmp_buf = buffer_init();	
	if(con->mode == SMB_BASIC){
		//sprintf(str, "Basic realm=\"%s\"", "smbdav");
		
		if(con->smb_info&&con->smb_info->server->used)
			sprintf(str, "Basic realm=\"smb://%s\"", con->smb_info->server->ptr);
		else
			sprintf(str, "Basic realm=\"%s\"", "webdav");
	}
	else if(con->mode == SMB_NTLM)
		sprintf(str, "NTLM");
	else
		sprintf(str, "Basic realm=\"%s\"", "webdav");
	
	buffer_copy_string(tmp_buf, str);
	
	response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tmp_buf));
	con->http_status = 401;
		
	buffer_free(tmp_buf);
}
Exemple #22
0
static int lua_to_c_get_string(lua_State *L, const char *varname, buffer *b) {
	int curelem;

	lua_pushstring(L, varname);

	curelem = lua_gettop(L);
	lua_gettable(L, LUA_GLOBALSINDEX);

	/* it should be a table */
	if (!lua_isstring(L, curelem)) {
		lua_settop(L, curelem - 1);

		return -1;
	}

	buffer_copy_string(b, lua_tostring(L, curelem));

	lua_pop(L, 1);

	assert(curelem - 1 == lua_gettop(L));

	return 0;
}
Exemple #23
0
void smbc_wrapper_response_realm_401(server *srv, connection *con)
{
/*
	if(con->mode == SMB_BASIC){
		if(con->smb_info&&con->smb_info->server->used){
			Cdbg(DBE, "sssssssss");
			con->http_status = 401;
		}
		return;
	}
	*/
	char str[50];

	UNUSED(srv);

	buffer* tmp_buf = buffer_init();	
	if(con->mode == SMB_BASIC){
		//sprintf(str, "Basic realm=\"%s\"", "smbdav");
		
		if(con->smb_info&&con->smb_info->server->used)
			sprintf(str, "Basic realm=\"smb://%s\"", con->smb_info->server->ptr);
		else
			sprintf(str, "Basic realm=\"%s\"", "webdav");
		
	}
	else if(con->mode == SMB_NTLM)
		sprintf(str, "NTLM");
	else
		sprintf(str, "Basic realm=\"%s\"", "webdav");
	
	buffer_copy_string(tmp_buf, str);
	
	response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tmp_buf));
	con->http_status = 401;
		
	buffer_free(tmp_buf);
}
int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) {
    size_t i;
    data_unset *du;

    for (i = 0; cv[i].key; i++) {
        data_string *touched;

        if (NULL == (du = array_get_element(ca, cv[i].key))) {
            /* no found */

            continue;
        }

        /* touched */
        touched = data_string_init();

        buffer_copy_string(touched->value, "");
        buffer_copy_string_buffer(touched->key, du->key);

        array_insert_unique(srv->config_touched, (data_unset *)touched);
    }

    return config_insert_values_internal(srv, ca, cv);
}
Exemple #25
0
static cond_result_t config_check_cond_nocache(server *srv, connection *con, data_config *dc) {
	buffer *l;
	server_socket *srv_sock = con->srv_socket;

	/* check parent first */
	if (dc->parent && dc->parent->context_ndx) {
		/**
		 * a nested conditional 
		 *
		 * if the parent is not decided yet or false, we can't be true either 
		 */
		if (con->conf.log_condition_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "sb", "go parent", dc->parent->key);
		}

		switch (config_check_cond_cached(srv, con, dc->parent)) {
		case COND_RESULT_FALSE:
			return COND_RESULT_FALSE;
		case COND_RESULT_UNSET:
			return COND_RESULT_UNSET;
		default:
			break;
		}
	}

	if (dc->prev) {
		/**
		 * a else branch
		 *
		 * we can only be executed, if all of our previous brothers 
		 * are false
		 */
		if (con->conf.log_condition_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "sb", "go prev", dc->prev->key);
		}

		/* make sure prev is checked first */
		config_check_cond_cached(srv, con, dc->prev);

		/* one of prev set me to FALSE */
		switch (con->cond_cache[dc->context_ndx].result) {
		case COND_RESULT_FALSE:
			return con->cond_cache[dc->context_ndx].result;
		default:
			break;
		}
	}

	if (!con->conditional_is_valid[dc->comp]) {
		if (con->conf.log_condition_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "dss", 
				dc->comp,
				dc->key->ptr,
				con->conditional_is_valid[dc->comp] ? "yeah" : "nej");
		}

		return COND_RESULT_UNSET;
	}

	/* pass the rules */

	switch (dc->comp) {
	case COMP_HTTP_HOST: {
		char *ck_colon = NULL, *val_colon = NULL;

		if (!buffer_string_is_empty(con->uri.authority)) {

			/*
			 * append server-port to the HTTP_POST if necessary
			 */

			l = con->uri.authority;

			switch(dc->cond) {
			case CONFIG_COND_NE:
			case CONFIG_COND_EQ:
				ck_colon = strchr(dc->string->ptr, ':');
				val_colon = strchr(l->ptr, ':');

				if (NULL != ck_colon && NULL == val_colon) {
					/* condition "host:port" but client send "host" */
					buffer_copy_buffer(srv->cond_check_buf, l);
					buffer_append_string_len(srv->cond_check_buf, CONST_STR_LEN(":"));
					buffer_append_int(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr)));
					l = srv->cond_check_buf;
				} else if (NULL != val_colon && NULL == ck_colon) {
					/* condition "host" but client send "host:port" */
					buffer_copy_string_len(srv->cond_check_buf, l->ptr, val_colon - l->ptr);
					l = srv->cond_check_buf;
				}
				break;
			default:
				break;
			}
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
		} else if (!buffer_string_is_empty(con->tlsext_server_name)) {
			l = con->tlsext_server_name;
#endif
		} else {
			l = srv->empty_string;
		}
		break;
	}
	case COMP_HTTP_REMOTE_IP: {
		char *nm_slash;
		/* handle remoteip limitations
		 *
		 * "10.0.0.1" is provided for all comparisions
		 *
		 * only for == and != we support
		 *
		 * "10.0.0.1/24"
		 */

		if ((dc->cond == CONFIG_COND_EQ ||
		     dc->cond == CONFIG_COND_NE) &&
		    (con->dst_addr.plain.sa_family == AF_INET) &&
		    (NULL != (nm_slash = strchr(dc->string->ptr, '/')))) {
			int nm_bits;
			long nm;
			char *err;
			struct in_addr val_inp;

			if (*(nm_slash+1) == '\0') {
				log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string);

				return COND_RESULT_FALSE;
			}

			nm_bits = strtol(nm_slash + 1, &err, 10);

			if (*err) {
				log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: non-digit found in netmask:", dc->string, err);

				return COND_RESULT_FALSE;
			}

			if (nm_bits > 32 || nm_bits < 0) {
				log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: invalid netmask:", dc->string, err);

				return COND_RESULT_FALSE;
			}

			/* take IP convert to the native */
			buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr);
#ifdef __WIN32
			if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) {
				log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);

				return COND_RESULT_FALSE;
			}

#else
			if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) {
				log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);

				return COND_RESULT_FALSE;
			}
#endif

			/* build netmask */
			nm = nm_bits ? htonl(~((1 << (32 - nm_bits)) - 1)) : 0;

			if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) {
				return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
			} else {
				return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_FALSE : COND_RESULT_TRUE;
			}
		} else {
			l = con->dst_addr_buf;
		}
		break;
	}
	case COMP_HTTP_SCHEME:
		l = con->uri.scheme;
		break;

	case COMP_HTTP_URL:
		l = con->uri.path;
		break;

	case COMP_HTTP_QUERY_STRING:
		l = con->uri.query;
		break;

	case COMP_SERVER_SOCKET:
		l = srv_sock->srv_token;
		break;

	case COMP_HTTP_REFERER: {
		data_string *ds;

		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) {
			l = ds->value;
		} else {
			l = srv->empty_string;
		}
		break;
	}
	case COMP_HTTP_COOKIE: {
		data_string *ds;
		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) {
			l = ds->value;
		} else {
			l = srv->empty_string;
		}
		break;
	}
	case COMP_HTTP_USER_AGENT: {
		data_string *ds;
		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "User-Agent"))) {
			l = ds->value;
		} else {
			l = srv->empty_string;
		}
		break;
	}
	case COMP_HTTP_REQUEST_METHOD: {
		const char *method = get_http_method_name(con->request.http_method);

		/* we only have the request method as const char but we need a buffer for comparing */

		buffer_copy_string(srv->tmp_buf, method);

		l = srv->tmp_buf;

		break;
	}
	case COMP_HTTP_LANGUAGE: {
		data_string *ds;
		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Language"))) {
			l = ds->value;
		} else {
			l = srv->empty_string;
		}
		break;
	}
	default:
		return COND_RESULT_FALSE;
	}

	if (NULL == l) {
		if (con->conf.log_condition_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "bsbs", dc->comp_key,
					"(", l, ") compare to NULL");
		}
		return COND_RESULT_FALSE;
	}

	if (con->conf.log_condition_handling) {
		log_error_write(srv, __FILE__, __LINE__,  "bsbsb", dc->comp_key,
				"(", l, ") compare to ", dc->string);
	}
	switch(dc->cond) {
	case CONFIG_COND_NE:
	case CONFIG_COND_EQ:
		if (buffer_is_equal(l, dc->string)) {
			return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
		} else {
			return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_FALSE : COND_RESULT_TRUE;
		}
		break;
#ifdef HAVE_PCRE_H
	case CONFIG_COND_NOMATCH:
	case CONFIG_COND_MATCH: {
		cond_cache_t *cache = &con->cond_cache[dc->context_ndx];
		int n;

#ifndef elementsof
#define elementsof(x) (sizeof(x) / sizeof(x[0]))
#endif
		n = pcre_exec(dc->regex, dc->regex_study, CONST_BUF_LEN(l), 0, 0,
				cache->matches, elementsof(cache->matches));

		cache->patterncount = n;
		if (n > 0) {
			cache->comp_value = l;
			cache->comp_type  = dc->comp;
			return (dc->cond == CONFIG_COND_MATCH) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
		} else {
			/* cache is already cleared */
			return (dc->cond == CONFIG_COND_MATCH) ? COND_RESULT_FALSE : COND_RESULT_TRUE;
		}
		break;
	}
#endif
	default:
		/* no way */
		break;
	}

	return COND_RESULT_FALSE;
}
Exemple #26
0
handler_t http_response_prepare(server *srv, connection *con) {
	handler_t r;
Cdbg(DBE, "enter http_response_prepare..mode=[%d], status=[%d][%s]", con->mode, con->http_status, connection_get_state(con->http_status));
	/* looks like someone has already done a decision */
	if ( (con->mode == DIRECT || con->mode == SMB_BASIC || con->mode == SMB_NTLM) &&
	    (con->http_status != 0 && con->http_status != 200)) {
		/* remove a packets in the queue */
		if (con->file_finished == 0) {
			chunkqueue_reset(con->write_queue);
		}

		return HANDLER_FINISHED;
	}

	/* no decision yet, build conf->filename */
	if ( (con->mode == DIRECT || con->mode == SMB_BASIC || con->mode == SMB_NTLM) && con->physical.path->used == 0) {
		char *qstr;

		/* we only come here when we have the parse the full request again
		 *
		 * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a
		 * problem here as mod_setenv might get called multiple times
		 *
		 * fastcgi-auth might lead to a COMEBACK too
		 * fastcgi again dead server too
		 *
		 * mod_compress might add headers twice too
		 *
		 *  */

		config_cond_cache_reset(srv, con);
		config_setup_connection(srv, con); /* Perhaps this could be removed at other places. */
		
		if (con->conf.log_condition_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "s",  "run condition");
		}

		config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */
		
		/**
		 * prepare strings
		 *
		 * - uri.path_raw
		 * - uri.path (secure)
		 * - uri.query
		 *
		 */

		/**
		 * Name according to RFC 2396
		 *
		 * - scheme
		 * - authority
		 * - path
		 * - query
		 *
		 * (scheme)://(authority)(path)?(query)#fragment
		 *
		 *
		 */

		if (con->conf.is_ssl) {
			buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("https"));
		} else {
			buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http"));
		}
		buffer_copy_string_buffer(con->uri.authority, con->request.http_host);
		buffer_to_lower(con->uri.authority);
		
		config_patch_connection(srv, con, COMP_HTTP_SCHEME);    /* Scheme:      */
		config_patch_connection(srv, con, COMP_HTTP_HOST);      /* Host:        */
		config_patch_connection(srv, con, COMP_HTTP_REMOTE_IP); /* Client-IP */
		config_patch_connection(srv, con, COMP_HTTP_REFERER);   /* Referer:     */
		config_patch_connection(srv, con, COMP_HTTP_USER_AGENT);/* User-Agent:  */
		config_patch_connection(srv, con, COMP_HTTP_LANGUAGE);  /* Accept-Language:  */
		config_patch_connection(srv, con, COMP_HTTP_COOKIE);    /* Cookie:  */
		config_patch_connection(srv, con, COMP_HTTP_REQUEST_METHOD); /* REQUEST_METHOD */

		/** their might be a fragment which has to be cut away */
		if (NULL != (qstr = strchr(con->request.uri->ptr, '#'))) {
			con->request.uri->used = qstr - con->request.uri->ptr;
			con->request.uri->ptr[con->request.uri->used++] = '\0';
		}

		/** extract query string from request.uri */
		if (NULL != (qstr = strchr(con->request.uri->ptr, '?'))) {
			buffer_copy_string(con->uri.query, qstr + 1);
			buffer_copy_string_len(con->uri.path_raw, con->request.uri->ptr, qstr - con->request.uri->ptr);
		} else {
			buffer_reset(con->uri.query);
			buffer_copy_string_buffer(con->uri.path_raw, con->request.uri);
		}

		if (con->conf.log_request_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "s",  "-- splitting Request-URI");
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Request-URI  : ", con->request.uri);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-scheme   : ", con->uri.scheme);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-authority: ", con->uri.authority);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-path     : ", con->uri.path_raw);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-query    : ", con->uri.query);
		}


		/**
		 *
		 * call plugins
		 *
		 * - based on the raw URL
		 *
		 */		
		switch(r = plugins_call_handle_uri_raw(srv, con)) {
		case HANDLER_GO_ON:
			break;
		case HANDLER_FINISHED:
		case HANDLER_COMEBACK:
		case HANDLER_WAIT_FOR_EVENT:
		case HANDLER_ERROR:
			return r;
		default:
			log_error_write(srv, __FILE__, __LINE__, "sd", "handle_uri_raw: unknown return value", r);
			break;
		}

		/* build filename
		 *
		 * - decode url-encodings  (e.g. %20 -> ' ')
		 * - remove path-modifiers (e.g. /../)
		 */
		if (con->request.http_method == HTTP_METHOD_OPTIONS &&
		    con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
			/* OPTIONS * ... */
			buffer_copy_string_buffer(con->uri.path, con->uri.path_raw);
		} else {
			buffer_copy_string_buffer(srv->tmp_buf, con->uri.path_raw);
			buffer_urldecode_path(srv->tmp_buf);			
			buffer_path_simplify(con->uri.path, srv->tmp_buf);			
		}

		if (con->conf.log_request_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "s",  "-- sanatising URI");
			log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-path     : ", con->uri.path);
		}

#ifdef USE_OPENSSL
		if (con->conf.is_ssl && con->conf.ssl_verifyclient) {
			https_add_ssl_entries(con);
		}
#endif

		/**
		 *
		 * call plugins
		 *
		 * - based on the clean URL
		 *
		 */
		config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */
		config_patch_connection(srv, con, COMP_HTTP_QUERY_STRING); /* HTTPqs */

		/* do we have to downgrade to 1.0 ? */
		if (!con->conf.allow_http11) {
			con->request.http_version = HTTP_VERSION_1_0;
		}
		
		switch(r = plugins_call_handle_uri_clean(srv, con)) {
		case HANDLER_GO_ON:
			break;
		case HANDLER_FINISHED:
		case HANDLER_COMEBACK:
		case HANDLER_WAIT_FOR_EVENT:
		case HANDLER_ERROR:
			return r;
		default:
			log_error_write(srv, __FILE__, __LINE__, "");
			break;
		}
		
		if (con->request.http_method == HTTP_METHOD_OPTIONS &&
		    con->uri.path->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
			/* option requests are handled directly without checking of the path */

			response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));

			con->http_status = 200;
			con->file_finished = 1;

			return HANDLER_FINISHED;
		}

		/***
		 *
		 * border
		 *
		 * logical filename (URI) becomes a physical filename here
		 *
		 *
		 *
		 */




		/* 1. stat()
		 * ... ISREG() -> ok, go on
		 * ... ISDIR() -> index-file -> redirect
		 *
		 * 2. pathinfo()
		 * ... ISREG()
		 *
		 * 3. -> 404
		 *
		 */

		/*
		 * SEARCH DOCUMENT ROOT
		 */

		/* set a default */
		buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root);
		buffer_copy_string_buffer(con->physical.rel_path, con->uri.path);
		
#if defined(__WIN32) || defined(__CYGWIN__)
		/* strip dots from the end and spaces
		 *
		 * windows/dos handle those filenames as the same file
		 *
		 * foo == foo. == foo..... == "foo...   " == "foo..  ./"
		 *
		 * This will affect in some cases PATHINFO
		 *
		 * on native windows we could prepend the filename with \\?\ to circumvent
		 * this behaviour. I have no idea how to push this through cygwin
		 *
		 * */

		if (con->physical.rel_path->used > 1) {
			buffer *b = con->physical.rel_path;
			size_t i;

			if (b->used > 2 &&
			    b->ptr[b->used-2] == '/' &&
			    (b->ptr[b->used-3] == ' ' ||
			     b->ptr[b->used-3] == '.')) {
				b->ptr[b->used--] = '\0';
			}

			for (i = b->used - 2; b->used > 1; i--) {
				if (b->ptr[i] == ' ' ||
				    b->ptr[i] == '.') {
					b->ptr[b->used--] = '\0';
				} else {
					break;
				}
			}
		}
#endif

		if (con->conf.log_request_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "s",  "-- before doc_root");
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Doc-Root     :", con->physical.doc_root);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Rel-Path     :", con->physical.rel_path);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
		}
		/* the docroot plugin should set the doc_root and might also set the physical.path
		 * for us (all vhost-plugins are supposed to set the doc_root)
		 * */
		switch(r = plugins_call_handle_docroot(srv, con)) {
		case HANDLER_GO_ON:
			break;
		case HANDLER_FINISHED:
		case HANDLER_COMEBACK:
		case HANDLER_WAIT_FOR_EVENT:
		case HANDLER_ERROR:
			return r;
		default:
			log_error_write(srv, __FILE__, __LINE__, "");
			break;
		}
		
		/* MacOS X and Windows can't distiguish between upper and lower-case
		 *
		 * convert to lower-case
		 */
		if (con->conf.force_lowercase_filenames) {
			buffer_to_lower(con->physical.rel_path);
		}
		
		/* the docroot plugins might set the servername, if they don't we take http-host */
		if (buffer_is_empty(con->server_name)) {
			buffer_copy_string_buffer(con->server_name, con->uri.authority);
		}
		
		/**
		 * create physical filename
		 * -> physical.path = docroot + rel_path
		 *
		 */		
		buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
		BUFFER_APPEND_SLASH(con->physical.path);
		buffer_copy_string_buffer(con->physical.basedir, con->physical.path);
		if (con->physical.rel_path->used &&
		    con->physical.rel_path->ptr[0] == '/') {
		    
			buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
			
			//buffer_append_string_encoded(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2, ENCODING_REL_URI);
			//Cdbg(1,"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa %s", con->physical.path->ptr);
		} else {		
			buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
		}
		
		if (con->conf.log_request_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "s",  "-- after doc_root");
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Doc-Root     :", con->physical.doc_root);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Rel-Path     :", con->physical.rel_path);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
		}
		
		switch(r = plugins_call_handle_physical(srv, con)) {
			case HANDLER_GO_ON:
				break;
			case HANDLER_FINISHED:
			case HANDLER_COMEBACK:
			case HANDLER_WAIT_FOR_EVENT:
			case HANDLER_ERROR:
				return r;
			default:
				log_error_write(srv, __FILE__, __LINE__, "");
				break;
		}
		
		if (con->conf.log_request_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "s",  "-- logical -> physical");
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Doc-Root     :", con->physical.doc_root);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Rel-Path     :", con->physical.rel_path);
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
		}
	}
	
	/*
	 * Noone catched away the file from normal path of execution yet (like mod_access)
	 *
	 * Go on and check of the file exists at all
	 */
	if (con->mode == DIRECT || con->mode == SMB_BASIC || con->mode == SMB_NTLM) {
		char *slash = NULL;
		char *pathinfo = NULL;
		int found = 0;
		stat_cache_entry *sce = NULL;
		
		if (con->conf.log_request_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling physical path");
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
		}
		
		if ( HANDLER_ERROR != stat_cache_get_entry(srv, con, smbc_wrapper_physical_url_path(srv, con), &sce)) {
			/* file exists */

			if (con->conf.log_request_handling) {
				log_error_write(srv, __FILE__, __LINE__,  "s",  "-- file found");
				log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
			}
#ifdef HAVE_LSTAT
			if ((sce->is_symlink != 0) && !con->conf.follow_symlink) {
				con->http_status = 403;

				if (con->conf.log_request_handling) {
					log_error_write(srv, __FILE__, __LINE__,  "s",  "-- access denied due symlink restriction");
					log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
				}
				
				buffer_reset(con->physical.path);
				return HANDLER_FINISHED;
			};
#endif
			if (S_ISDIR(sce->st.st_mode)) {
				if (con->uri.path->ptr[con->uri.path->used - 2] != '/') {
					/* redirect to .../ */

					http_response_redirect_to_directory(srv, con);

					return HANDLER_FINISHED;
				}
#ifdef HAVE_LSTAT
			} else if (!S_ISREG(sce->st.st_mode) && !sce->is_symlink) {
#else
			} else if (!S_ISREG(sce->st.st_mode)) {
#endif
				/* any special handling of non-reg files ?*/


			}
		} 
		else {		
			switch (errno) {
			case EACCES:
				con->http_status = 403;

				if (con->conf.log_request_handling) {
					log_error_write(srv, __FILE__, __LINE__,  "s",  "-- access denied");
					log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
				}
				
				buffer_reset(con->physical.path);
				return HANDLER_FINISHED;
			case ENOENT:
				con->http_status = 404;
				
				if (con->conf.log_request_handling) {
					log_error_write(srv, __FILE__, __LINE__,  "s",  "-- file not found");
					log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
				}

				buffer_reset(con->physical.path);
				return HANDLER_FINISHED;
			case ENOTDIR:
				/* PATH_INFO ! :) */
				break;
			default:
				/* we have no idea what happend. let's tell the user so. */
				con->http_status = 500;
				buffer_reset(con->physical.path);
				
				log_error_write(srv, __FILE__, __LINE__, "ssbsb",
						"file not found ... or so: ", strerror(errno),
						con->uri.path,
						"->", con->physical.path);

				return HANDLER_FINISHED;
			}

			/* not found, perhaps PATHINFO */

			buffer_copy_string_buffer(srv->tmp_buf, con->physical.path);
			
			do {
				if (slash) {
					buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
				} else {
					buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
				}

				if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {				
					found = S_ISREG(sce->st.st_mode);
					break;
				}

				if (pathinfo != NULL) {
					*pathinfo = '\0';
				}
				slash = strrchr(srv->tmp_buf->ptr, '/');

				if (pathinfo != NULL) {
					/* restore '/' */
					*pathinfo = '/';
				}

				if (slash) pathinfo = slash;
			} while ((found == 0) && (slash != NULL) && ((size_t)(slash - srv->tmp_buf->ptr) > (con->physical.basedir->used - 2)));

			if (found == 0) {
				/* no it really doesn't exists */
				con->http_status = 404;

				if (con->conf.log_file_not_found) {
					log_error_write(srv, __FILE__, __LINE__, "sbsb",
							"file not found:", con->uri.path,
							"->", con->physical.path);
				}

				buffer_reset(con->physical.path);

				return HANDLER_FINISHED;
			}

#ifdef HAVE_LSTAT
			if ((sce->is_symlink != 0) && !con->conf.follow_symlink) {
				con->http_status = 403;

				if (con->conf.log_request_handling) {
					log_error_write(srv, __FILE__, __LINE__,  "s",  "-- access denied due symlink restriction");
					log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
				}

				buffer_reset(con->physical.path);
				return HANDLER_FINISHED;
			};
#endif

			/* we have a PATHINFO */
			if (pathinfo) {
				buffer_copy_string(con->request.pathinfo, pathinfo);

				/*
				 * shorten uri.path
				 */

				con->uri.path->used -= strlen(pathinfo);
				con->uri.path->ptr[con->uri.path->used - 1] = '\0';
			}

			if (con->conf.log_request_handling) {
				log_error_write(srv, __FILE__, __LINE__,  "s",  "-- after pathinfo check");
				log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
				log_error_write(srv, __FILE__, __LINE__,  "sb", "URI          :", con->uri.path);
				log_error_write(srv, __FILE__, __LINE__,  "sb", "Pathinfo     :", con->request.pathinfo);
			}
		}

		if (con->conf.log_request_handling) {
			log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling subrequest");
			log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
		}
		
		/* call the handlers */
		switch(r = plugins_call_handle_subrequest_start(srv, con)) {
		case HANDLER_GO_ON:
			/* request was not handled */
			break;
		case HANDLER_FINISHED:
		default:
			if (con->conf.log_request_handling) {
				log_error_write(srv, __FILE__, __LINE__,  "s",  "-- subrequest finished");
			}

			/* something strange happend */
			return r;
		}

		/* if we are still here, no one wanted the file, status 403 is ok I think */

		if ((con->mode == DIRECT || con->mode == SMB_BASIC || con->mode == SMB_NTLM) && con->http_status == 0) {
			switch (con->request.http_method) {
			case HTTP_METHOD_OPTIONS:
				con->http_status = 200;
				break;
			default:
				con->http_status = 403;
			}

			return HANDLER_FINISHED;
		}

	}

	switch(r = plugins_call_handle_subrequest(srv, con)) {
	case HANDLER_GO_ON:
		/* request was not handled, looks like we are done */
		return HANDLER_FINISHED;
	case HANDLER_FINISHED:
		/* request is finished */
	default:
		/* something strange happend */
		return r;
	}

	/* can't happen */
	return HANDLER_COMEBACK;
}
handler_t basic_authentication_handler(server *srv, connection *con, plugin_data *p)
{
	data_string *ds_auth = (data_string *)array_get_element(con->request.headers, "Authorization");
	
	buffer *user = buffer_init();
	buffer *pass = buffer_init();
	buffer_copy_string(user, " ");
	buffer_copy_string(pass, " ");
	
	//Cdbg(DBE, "*********** con->request.uri..%s", con->request.uri->ptr);
	
	char *auth_username = NULL;
	char *auth_password = NULL;
	if( smbc_parser_basic_authentication(srv, con, &auth_username, &auth_password) != 1 ){
			
		if(con->smb_info==NULL)
			goto error_401;

		//Cdbg(DBE, "1111111, %s, %s", con->smb_info->username->ptr, con->smb_info->password->ptr);

		if( con->smb_info->username->used && con->smb_info->password->used ){
			buffer_copy_string_buffer(user, con->smb_info->username);			
			buffer_copy_string_buffer(pass, con->smb_info->password);
		}
		
		Cdbg(DBE, "fail smbc_parser_basic_authentication-> %s, %s", user->ptr, pass->ptr);
	}
	else{
		buffer_copy_string(user, auth_username);
		buffer_copy_string(pass, auth_password);
		free(auth_username);
		free(auth_password);
	}

	time_t cur_time = time(NULL);
	
	double result = difftime(cur_time, con->smb_info->auth_time);
	Cdbg(DBE, "difftime=[%1f]", result);
	
	if(con->smb_info->qflag == SMB_HOST_QUERY) {
		data_string *ds2 = (data_string *)array_get_element(con->request.headers, "user-Agent");	
		
		//- MUST login again more than 30 minutes
		if(result>1800){
			goto error_401;
		}
		
		if( con->smb_info && buffer_is_equal_string(con->smb_info->username, "RELOGIN", 7) ){
			buffer_reset(con->smb_info->username);
			buffer_reset(con->smb_info->password);
			goto error_401;
		}
		
		if(con->smb_info->username->used && con->smb_info->password->used){
			buffer_copy_string_buffer(user, con->smb_info->username);			
			buffer_copy_string_buffer(pass, con->smb_info->password);
			Cdbg(DBE, "SMB_HOST_QUERY-->copy from smb_info user=[%s], pass=[%s]", user->ptr, pass->ptr);
		}

		#if EMBEDDED_EANBLE
		if( strcmp(user->ptr, nvram_get_http_username())!=0 || 
		     strcmp(pass->ptr, nvram_get_http_passwd())!=0 ){
			Cdbg(DBE, "smbc_host_account_authentication fail user=[%s], pass=[%s]", user->ptr, pass->ptr);
			goto error_401;
		}
		#else
		if(  strcmp(user->ptr, "admin")!=0 || 
		     strcmp(pass->ptr, "admin")!=0 ){
			Cdbg(DBE, "smbc_host_account_authentication fail user=[%s], pass=[%s]", user->ptr, pass->ptr);
			goto error_401;
		}
		#endif
	}
	else {
		//- check user / password
		struct stat st;
		
		if( con->smb_info && buffer_is_equal_string(con->smb_info->username, "RELOGIN", 7) ){
			buffer_reset(con->smb_info->username);
			buffer_reset(con->smb_info->password);

			goto error_401;
		}
		
		int res = smbc_server_check_creds( con->smb_info->server->ptr, 
									     con->smb_info->share->ptr, 
									     con->smb_info->workgroup->ptr, 
									     user->ptr, 
									     pass->ptr );

		//if( res == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED)) {
		if( res == 0xc00000bb ){
			buffer_free(user);
			buffer_free(pass);
			con->http_status = 406;
			
			return HANDLER_FINISHED;
		}
		else if(res != 0) { //the username/password for smb_server is not correct				
			if(con->smb_info->username->used && con->smb_info->password->used){
				buffer_copy_string_buffer(user, con->smb_info->username);			
				buffer_copy_string_buffer(pass, con->smb_info->password);
				Cdbg(DBE, "Try to login again, server=%s, share=%s, user=%s, pass=%s", 
						con->smb_info->server->ptr,
						con->smb_info->share->ptr,
						user->ptr, pass->ptr);

				//- MUST login again more than 30 minutes
				if(result>1800){
					buffer_copy_string(pass, "");
				}
				
				//sprintf(strr, "smb://%s:%[email protected]%s", user->ptr, pass->ptr, con->request.uri->ptr+1);
				int res = smbc_server_check_creds(con->smb_info->server->ptr, 
											    con->smb_info->share->ptr, 
											    con->smb_info->workgroup->ptr, 
											    user->ptr, 
											    pass->ptr);
				if(res != 0) 
					goto error_401;
			}
			else		
				goto error_401;
		}			
	}
	
	con->smb_info->auth_time = time(NULL);

	if( !buffer_is_equal_string(user, "no", 2) && !buffer_is_equal_string(pass, "no", 2)){
		buffer_copy_string_buffer(con->smb_info->username, user);
		buffer_copy_string_buffer(con->smb_info->password, pass);
		Cdbg(DBE, "save username=[%s], password=[%s], time=[%d] to con->smb_info", con->smb_info->username->ptr, con->smb_info->password->ptr, con->smb_info->auth_time);
	}
	
	buffer_free(user);
	buffer_free(pass);
	
	return HANDLER_UNSET;

error_401:
	buffer_free(user);
	buffer_free(pass);
	
	if(con->smb_info)
		con->smb_info->auth_time = time(NULL);
	
	smbc_wrapper_response_401(srv, con);
	
	return HANDLER_FINISHED;
}
Exemple #28
0
int smbc_host_account_authentication(connection* con, const char *username, const char *password){

	char *nvram_acc_list, *nvram_acc_webdavproxy;	
	int st_samba_mode = 1;
	if (con->mode != SMB_BASIC&&con->mode != DIRECT) return -1;
#if EMBEDDED_EANBLE
	char *a = nvram_get_acc_list();
	if(a==NULL) return -1;
	int l = strlen(a);
	nvram_acc_list = (char*)malloc(l+1);
	strncpy(nvram_acc_list, a, l);
	nvram_acc_list[l] = '\0';

	char *b = nvram_get_acc_webdavproxy();
	if(b==NULL) return -1;
	l = strlen(b);
	nvram_acc_webdavproxy = (char*)malloc(l+1);
	strncpy(nvram_acc_webdavproxy, b, l);
	nvram_acc_webdavproxy[l] = '\0';

	st_samba_mode = nvram_get_st_samba_mode();
#else
	int i = 100;
	nvram_acc_list = (char*)malloc(100);
	strcpy(nvram_acc_list, "admin<admin>jerry<jerry");

	nvram_acc_webdavproxy = (char*)malloc(100);
	strcpy(nvram_acc_webdavproxy, "admin<1>jerry<0");
#endif

	int found_account = 0, account_right = -1;

	//- Share All, use guest account
	if(st_samba_mode==0){
		buffer_copy_string(con->router_user, "guest");
		account_right = 1;
		return account_right;
	}
		

	char * pch;
	pch = strtok(nvram_acc_list, "<>");	

	while(pch!=NULL){
		char *name;
		char *pass;
		int len;
		
		//- User Name
		len = strlen(pch);
		name = (char*)malloc(len+1);
		strncpy(name, pch, len);
		name[len] = '\0';
				
		//- User Password
		pch = strtok(NULL,"<>");
		len = strlen(pch);
		pass = (char*)malloc(len+1);
		strncpy(pass, pch, len);
		pass[len] = '\0';
		
		if( strcmp(username, name) == 0 &&
		    strcmp(password, pass) == 0 ){
			
			//Cdbg(1, "22222222222 name = %s, pass=%s, right=%d", username, password, right);
			
			int len2;
			char  *pch2, *name2;
			pch2 = strtok(nvram_acc_webdavproxy, "<>");	

			while(pch2!=NULL){
				//- User Name
				len2 = strlen(pch2);
				name2 = (char*)malloc(len2+1);
				strncpy(name2, pch2, len2);
				name2[len2] = '\0';

				//- User Right
				pch2 = strtok(NULL,"<>");
				account_right = atoi(pch2);
		
				if( strcmp(username, name2) == 0 ){
					free(name2);
					
					if(con->smb_info)
						con->smb_info->auth_right = account_right;
					
					//- Copy user name to router_user
					buffer_copy_string(con->router_user, username);

					found_account = 1;
					
					break;
				}

				free(name2);
				pch2 = strtok(NULL,"<>");
			}

			free(name);
			free(pass);
			
			if(found_account==1)
				break;
		}
		
		free(name);
		free(pass);

		pch = strtok(NULL,"<>");
	}
	
	free(nvram_acc_list);
	free(nvram_acc_webdavproxy);
	
	return account_right;
}
Exemple #29
0
void save_sharelink_list(){

#if EMBEDDED_EANBLE

	share_link_info_t* c;
	
	buffer* sharelink_list = buffer_init();
	buffer_copy_string(sharelink_list, "");

	for (c = share_link_info_list; c; c = c->next) {

		if(c->toshare == 0)
			continue;
		
		buffer* temp = buffer_init();

		buffer_copy_string_buffer(temp, c->shortpath);
		buffer_append_string(temp, "<");
		buffer_append_string_buffer(temp, c->realpath);
		buffer_append_string(temp, "<");
		buffer_append_string_buffer(temp, c->filename);
		buffer_append_string(temp, "<");
		buffer_append_string_buffer(temp, c->auth);
		buffer_append_string(temp, "<");

		char strTime[25] = {0};
		sprintf(strTime, "%lu", c->expiretime);		
		buffer_append_string(temp, strTime);

		buffer_append_string(temp, "<");
		
		char strTime2[25] = {0};
		sprintf(strTime2, "%lu", c->createtime);		
		buffer_append_string(temp, strTime2);
		
		buffer_append_string(temp, ">");
			
		buffer_append_string_buffer(sharelink_list, temp);
		
		buffer_free(temp);
	}
	
	nvram_set_sharelink_str(sharelink_list->ptr);		
	buffer_free(sharelink_list);
#else
	unlink(g_temp_sharelink_file);

	smb_srv_info_t* c;
	
	char mybuffer[100];
	FILE* fp = fopen(g_temp_sharelink_file, "w");

	if(fp!=NULL){
		share_link_info_t* c;
	
		for (c = share_link_info_list; c; c = c->next) {
			if(c->toshare == 0)
				continue;
			
			fprintf(fp, "%s<%s<%s<%s<%lu<%lu\n", c->shortpath->ptr, c->realpath->ptr, c->filename->ptr, c->auth->ptr, c->expiretime, c->createtime);
		}
		
		fclose(fp);
	}
#endif
}
Exemple #30
0
int smbc_aidisk_account_authentication(connection* con, const char *username, const char *password){

	char *nvram_acc_list;
	int st_samba_mode = 1;
	
	if (con->mode != SMB_BASIC&&con->mode != DIRECT) return -1;
#if EMBEDDED_EANBLE
	char *a = nvram_get_acc_list();
	if(a==NULL) return -1;
	int l = strlen(a);
	nvram_acc_list = (char*)malloc(l+1);
	strncpy(nvram_acc_list, a, l);
	nvram_acc_list[l] = '\0';

	st_samba_mode = nvram_get_st_samba_mode();
#else
	int i = 100;
	nvram_acc_list = (char*)malloc(100);
	strcpy(nvram_acc_list, "admin<admin>jerry<jerry");
#endif

	int account_right = -1;

	//- Share All, use guest account
	if(st_samba_mode==1){
		buffer_copy_string(con->aidisk_username, "guest");
		buffer_copy_string(con->aidisk_passwd, "");
		return 1;
	}
	
	char * pch;
	pch = strtok(nvram_acc_list, "<>");	

	while(pch!=NULL){
		char *name;
		char *pass;
		int len;
		
		//- User Name
		len = strlen(pch);
		name = (char*)malloc(len+1);
		strncpy(name, pch, len);
		name[len] = '\0';
				
		//- User Password
		pch = strtok(NULL,"<>");
		len = strlen(pch);
		pass = (char*)malloc(len+1);
		strncpy(pass, pch, len);
		pass[len] = '\0';
		
		if( strcmp(username, name) == 0 &&
		    strcmp(password, pass) == 0 ){
			
			buffer_copy_string(con->aidisk_username, username);
			buffer_copy_string(con->aidisk_passwd, password);
				
			account_right = 1;
				
			free(name);
			free(pass);
			
			break;
		}
		
		free(name);
		free(pass);

		pch = strtok(NULL,"<>");
	}
	
	free(nvram_acc_list);
		
	return account_right;
}