Apache module - How to check existence of directive in httpd.conf - apache

I am trying to write a sample Apache module to read config file whose file path is specified in httpd.conf like that:
<Location ~ /(?!.*\.(png|jpeg|jpg|gif|bmp|tif)$)>
SetInputFilter SAMPLE_INPUT_FILTER
SetOutputFilter SAMPLE_OUTPUT_FILTER
ConfigFilePath "/etc/httpd/conf.d/sample/sample.config"
</Location>
At command record structure, I do:
static const command_rec config_check_cmds[] =
{
AP_INIT_TAKE1( "ConfigFilePath", read_config_file, NULL, OR_ALL, "sample config"),
{ NULL }
};
I also set:
module AP_MODULE_DECLARE_DATA SAMPLE_module = {
STANDARD20_MODULE_STUFF,
create_dir_config, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
config_check_cmds, /* table of config file commands */
sample_register_hooks /* register hooks */
};
I could read config file path successfully. And now I want to check that if "ConfigFilePath" is not specified in httpd.conf, It will show error at console when I use "service httpd restart"
How could I do that?

You'd register a ap_hook_post_config hook and do the verification of required settings there. Be aware that that hook is called twice as documented in the answer here: Init modules in apache2
See an example post config hook implementation here: http://svn.apache.org/repos/asf/httpd/httpd/tags/2.3.0/modules/examples/mod_example_hooks.c

Related

NGINX - Limit access to folder to a list of user from ldap authentication

A have an nginx reverse proxy behind ldap authentication.
I can read username in php from variable $_SERVER['PHP_AUTH_USER']. I think this means that username is passed from ldap to nginx and than to php.
Is it possible in nginx configuration to allow access to a folder only to a list of users?
UPDATE
In nginx the user is stored in $remote_user variable. Is it possible to compare $remote_user with a list of users stored in a file? And then deny or allow access to a folder?
UPDATE
Probably I have to use map directive, for example:
map $remote_user $allowed_user {
default 0;
user1 1;
user2 1;
}
and then test it in the appropriate location:
location /folder/ {
if($allowed_user != 1){
return 403;
}
proxy_pass http://site;
}
but when I do sudo nginx -t, I receive the following error:
nginx: [emerg] unknown directive "if($allowed_user" in /etc/nginx/nginx.conf:104
nginx: configuration file /etc/nginx/nginx.conf test failed
You can do it via map directive (please note that map translate definitions block should be placed in the http context outside the server block):
map $remote_user $deny
username1 0;
username2 0;
...
usernameN 0;
default 1;
}
server {
...
location /folder/ {
if ($deny) { return 403; }
...
}
}
You can pre-generate users list in the above form (username1 0; username 2 0; ...) and then include this list to the nginx configuration:
map $remote_user $deny {
include /path/userlist.txt;
default 1;
}
Whenever this user list file get changed you'd need to reload nginx configuration (nginx -s reload).

Get the original filename of symlinks in nginx

From another script i got some generated symlinks.
2QGPCKVNG1R -> /anotherdir/movie1.mp4
HJS7J9ND2L5 -> /anotherdir/movie2.mp4
LKA6A9LA7SK -> /anotherdir/movie3.mp4
Displaying these files in NGINX works fine, but I'd like to rename the files at download via content disposition.
Question is how do i get the original filename in nginx variable?
I'm not sure it is possible at all. Is that another script yours or under your control? You can generate an additional nginx config file with a map block with the same script where you can describe a ruleset for mapping an URI value to the Content-Disposition header value (or you can write an additional script to do it with readlink -f <symlink> command:
map $uri $content_disposition {
~/2QGPCKVNG1R$ movie1.mp4;
~/HJS7J9ND2L5$ movie2.mp4;
~/LKA6A9LA7SK$ movie3.mp4;
}
And then include that file to the main nginx config:
include /path/to/content-disposition-map.conf;
server {
...
add_header Content-Disposition $content_disposition;
Another way I see is to use lua-nginx-module and a LUA script like
map $symlink_target $content_disposition {
~/([^/]*)$ $1;
}
server {
...
set_by_lua_block $symlink_target {
local result = io.popen("/bin/readlink -n -f " .. ngx.var.request_filename)
return result:read()
}
add_header Content-Disposition $content_disposition;

How to get path to nextcloud app path in javascript

Structure of my nextcloud instance
/apps
/apps2
/myapp
/img
icon.svg
I'm looking for a solution to generate a full URL to the icon from a path relative to myapp.
I've injected initial state but should be a better solution
https://docs.nextcloud.com/server/18/developer_manual/app/view/js.html#loading-initial-state
$eventDispatcher->addListener(
'OCA\Files::loadAdditionalScripts', function () {
script('projects', 'filelist_plugin');
style('projects', 'filelist');
/* #var IInitialStateService $state */
$state = $this->getContainer()->query(IInitialStateService::class);
$state->provideInitialState('projects', 'project-icon', image_path('projects', 'folder.svg'));
}
);

deepstream error listen EADDRINUSE 127.0.0.1:6020

i try to run my first deepstream.io server from this link but i get this error :
error:
CONNECTION_ERROR | Error: listen EADDRINUSE 127.0.0.1:3003
PLUGIN_ERROR | connectionEndpoint wasn't initialised in time
f:\try\deep\node_modules\deepstream.io\src\utils\dependency-
initialiser.js:96
throw error
^
Error: connectionEndpoint wasn't initialised in time
at DependencyInitialiser._onTimeout
(f:\try\deep\node_modules\deepstream.io\src\utils\dependency-
initialiser.js:94:17)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
and this is my code:
const DeepStreamServer = require("deepstream.io")
const C = DeepStreamServer.constants;
const server = new DeepStreamServer({
host:'localhost',
port:3003
})
server.start();
In deepstream 3.0 we released our HTTP endpoint, by default this runs alongside our websocket endpoint.
Because of this, passing the port option at the root level of the config no longer works (it overrides both the HTTP and websocket port options, as you can see in the screen capture provided, both endpoints are trying to start on the same port).
You can override each of these ports as follows:
const deepstream = require('deepstream.io')
const server = new deepstream({
connectionEndpoints: {
http: {
options: {
port: ...
}
},
websocket: {
options: {
port: ...
}
}
}
})
server.start()
Or you can define your config in a file and point to that while initialising deepstream[1].
[1] deepstream server configuration
One solution that i find is passing empty config object so inseted of :
const server = new DeepStreamServer({
host:'localhost',
port:3003
})
i'm just using this :
const server = new DeepStreamServer({})
and now everything work's well.
All the bellow is for Version 4.2.2 (last version by now)
I was having the same Port in use or config file not found errors. And i was using typescript and i didn't pay attention too to the output dir and build (which can be a problem when one use typescript and build). I was able to run the server in the end. And i had a lot of analysis.
I checked up the code source and i have seen how the config is loaded
const SUPPORTED_EXTENSIONS = ['.yml', '.yaml', '.json', '.js']
const DEFAULT_CONFIG_DIRS = [
path.join('.', 'conf', 'config'), path.join('..', 'conf', 'config'),
'/etc/deepstream/config', '/usr/local/etc/deepstream/config',
'/usr/local/etc/deepstream/conf/config',
]
DEFAULT_CONFIG_DIRS.push(path.join(process.argv[1], '..', 'conf', 'config'))
DEFAULT_CONFIG_DIRS.push(path.join(process.argv[1], '..', '..', 'conf', 'config'))
Also i tested different things and all. Here what i came up with:
First of all if we don't precise any parameter in the constructor. A config from the default directories will get to load. If there isn't then the server fail to run.
And one of the places where we can put a config is ./conf in the same folder as the server node script.
Secondly we can precise a config as a string path (parameter in the constructor). config.yml or one of the supported extensions. That will allow the server to load the server config + the permission.yml and users.yml configs. Which too are supposed to be in the same folder. If not in the same folder there load will fail, and therefor the permission plugin will not load. And so does the users config. And no fall back to default will happen.
Thirdly the supported extensions for the config files are: yml, yaml, json, js.
In nodejs context. If nothing precised. There is no fallback to some default config. The config need to be provided in one of the default folders, or by precising a path to it. Or by passing a config object. And all the optional options will default to some values if not provided ( a bit bellow there is an example that can show that ). Know however that precising an end point is very important and required.
To precise the path, we need to precise the path to the config.yml file (the server config) [example: path.join(__dirname, './conf/config.yml')]. Then from the same dir permission.yml and users.yml will be retrieved (the extension can be any of the supported one). We can not precise a path to a directory, it will fail.
We can precise the path to permission config or user config separatly within config.yaml as shown bellow:
# Permissioning example with default values for config-based permissioning
permission:
type: config
options:
path: ./permissions.yml
maxRuleIterations: 3
cacheEvacuationInterval: 60000
Finally we can pass an object to configure the server, or by passing null as a parameter and use .set methods (i didn't test the second method). For configuring the server we need to follow the same structure as the yml file. With sometimes a bit different naming. The typescript declaration files or types show us the way. With an editor like vscode. Even if we are not using typescript we can keep get the auto completion and type definitions.
And the simplest for equivalent to the previous version is :
const webSocketServer = new Deepstream({
connectionEndpoints: [
{
type: 'ws-websocket',
options: {
port: 6020,
host: '127.0.0.1',
urlPath: '/deepstream'
}
}
]
});
webSocketServer.start();
the above is the new syntax and way.
const server = new DeepStreamServer({
host:'localhost',
port:3003
})
^^^^^^^ is completely deprecated and not supported in version 4 (the doc is not updated).

Apache Ignoring Custom Module

So I am working on trying to make my own apache module. Right now I trying to get it to return a 403 just to test it out, but it seems that apache just ignores the module entirely and returns the default page. Here is the relevant parts of my code:
static int request_hook(request_rec* r){
return HTTP_FORBIDDEN;
}
/* ********************************************
Register module to Apache
******************************************** */
static void register_hooks(apr_pool_t *p)
{
// We want to hook first so we can issue a deny ASAP if needed
ap_hook_log_transaction( request_hook, NULL, NULL, APR_HOOK_REALLY_FIRST);
}
module AP_MODULE_DECLARE_DATA my_module = {
STANDARD20_MODULE_STUFF,
NULL, /* dir config creater */
NULL, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server configs */
NULL, /* command apr_table_t */
register_hooks /* register hooks */
};
And my apache configuration file looks like this:
<VirtualHost *:80>
DocumentRoot /var/www/html
SetHandler my_module
</VirtualHost>
It was compiled by doing
sudo apxs -i -a -c my_module.c && sudo service apache2 restart
Fixed. The problem was the function:
ap_hook_log_transaction( request_hook, NULL, NULL, APR_HOOK_REALLY_FIRST);
should have been:
ap_hook_handler( request_hook, NULL, NULL, APR_HOOK_REALLY_FIRST);