.. _AppProps: Application Properties ====================== Here you can find the reference of all the settings that you can apply to Wrench by editing your Wowza application’s ``Application.xml`` file. You can create and edit these properties using the Wowza Streaming Engine Manager's user interface as well. These properties have to go into the ```` section of your file as follows: .. code-block:: xml live wrench.db.url jdbc:mysql://localhost:3306/wtbexampledb Database Connection Settings ============================ When using Wrench in a setup that requires interaction with a relational database, you need to configure the below properties to establish a link between Wrench and the DB. A single database is used for all SQL operations, there is no way (currently) to hit different databases for the different queries. Wrench uses standard JDBC connection, so you can set a number of connection properties by putting them into the connection URL. The database driver class has to be on Wowza Streaming Engine’s classpath, typically you can achieve this by copying the JDBC driver jar file to the ``lib`` directory of your Wowza installation (see Installing Wrench chapter) If you don't need a database, because you configure Wrench to use REST API calls for integration, you should not include ``wrench.db.url`` in your configuration or set it to an empty string. In this case the webservice based features are still available. ``wrench.db.url`` ----------------- The JDBC url to your database that is used to establish the database connection. ``wrench.db.user`` ------------------ The username used to connect to the db. **Default:** ``root`` ``wrench.db.pass`` ------------------ The password used to connect to the db. **Default:** empty string Database Connection Pool Settings ================================= Due to the heavy usage of the backing database, Wrench uses `Tomcat Pool`_ to pool database connections. The current release lets you set some of the most typical settings of Tomcat Pool.\` ``wrench.dbcp.initial.size`` ---------------------------- Initial number of DB connections opened in the connection pool. **Default:** 1 ``wrench.dbcp.max.size`` ------------------------ The maximum size of the connection pool. **Default:** 1 ``wrench.dbcp.max.wait`` ------------------------ The maximum number of milliseconds that the pool will wait (when there are no connections available) for a connection to be returned before throwing an exception, or -1 to wait indefinitely. **Default:** -1 ``wrench.dbcp.test.on.borrow`` ------------------------------ Set to ``true`` if you want DBCP to test connections before giving them to Wrench. This prevents client errors that occur if the DB closes a connection in the pool. The drawback is the increased DB load. **Default:** ``false`` ``wrench.dbcp.test.sql`` ------------------------ The SQL query executed to validate connections borrowed from the pool before using them. Use something simple, like ``select 1`` .. _Tomcat Pool: http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html If the databasea connection pool is depleted, Wrench falls back to allowing users in, bypassing the SQL queries. This is by design to prevent any database overloading / blocking to be surfaced to end user experience problems. ``wrench.dbcp.validation.interval`` ----------------------------------- The DBCP connection validation interval in milliseconds. **Default:** ``3000`` Token Settings ============== The token in this context is the one-time-password that is generated by your website/webapplication and is placed into the database together with the information about the user who got the token. This records enables Wowza Wrench to verify player connections and associate Wowza stream players (client in their terminology) with your users. ``wrench.encoder.token`` ------------------------ The hardcoded token that can be used by your encoders, e.g. your OBS/vMix or ffmpeg to push the stream. Specifying this token in the connection allows clients (both players and publishers) to pass through Wrench’s authentication and authorization layers. If you don’t set this property, Wrench will require all connections, including the encoder to present a valid token in the connection url. The recommended setting is not having an encoder token specified. ``wrench.token.url.parameter`` ------------------------------ The query parameter in the connection URLs that carry the tokens. E.g. ``http://myserver/myapp/mystream?t=abc123`` **Default:** ``t`` ``wrench.token.resolver.sql`` ------------------------------ The SQL query which should return the resolution details for a given token. You can skip setting this if you are using webservice for token resolution, in that case set ``wrench.token.resolver.url`` or ``wrench.token.jwt.secret`` instead, depending on whether you want external API based token checking or JWT token authentication. The substituted parameter in the query is: ``:hashedtoken`` which contains the token from the connection URL passed through the hashing algorithm specified by ``wrench.token.hashing`` The query is expected to return the username in column ``username`` (this is mandatory), the IP address in column ``ip`` (optional), the token’s generation timestamp in column ``timestamp`` (needed only if token expiration check is enabled, the type of the client (i.e. encoder or player) in column ``encoder`` with boolean datatype or string ``true`` / ``false`` You can optionally return a numeric column ``bitratelimit`` which is the maximum allowed bitrate for the client. **Example query:** ``select user as username, ip, timestamp from wtb_tokens where token=:hashedtoken`` ``wrench.token.resolver.url`` ----------------------------- The URL of the webservice responsible for determining the username, token generation timestamp, and associated IP address for a given token. This config parameter excludes the usage of ``wrench.token.resolver.sql`` mutually. The message sent to the webservice is: .. code-block:: javascript {"applicationName": "live", "applicationInstance":"_default_", "token":"foobar"} The expected response format is: .. code-block:: javascript { "username":"john", "timestamp (optional)": 1430484962, "encoder (optional)": true, "ip (optional)": "192.168.1.1", "bitrateLimit (optional)": 100000 } Only the username field is mandatory from the above example response. ``wrench.token.hashing`` ------------------------ The hashing algorithm that is used for storing the generated tokens in the database. For security reasons it is not wise to store raw tokens, you should only store their hashes. Possible values are: ``md5``, ``sha512`` and ``plain`` (at your own risk) **Default:** ``md5`` ``wrench.token.invalidate.sql`` ------------------------------- A SQL query that is executed right after the token has been resolved. This can be used to flag a row in the table as already used, to prevent re-using the token later. In that case you need to filter used tokens out in the ``where`` condition of your token resolver query. Substituted parameters are: ``:hashedtoken`` and ``:username``. **Example** that physically removes used tokens: ``delete from wtb_tokens where token=:hashedtoken`` ``wrench.token.ip.check`` ------------------------- If set to ``true``, the connection is only accepted if the client’s IP address matches the one bound to the token. The expected IP address has to be returned in the ``ip`` column from the token resolver query or the ``ip`` attribute in the token resolver webservice JSON response object. **Default:** ``false`` IP address can be taken from a configured HTTP header ``wrench.ip.override.http.header`` if the server sits behind a proxy. ``wrench.token.expiry.sec`` --------------------------- The number of seconds in which a token expires. Expired tokens are not accepted. The token's generation timestamp has to be returned by the token resolver query in the ``timestamp`` column or in the ``timestamp`` attribute in the token resolver webservice JSON response object, or the ``iat`` claim in the JWT token. When retrieving via SQL, this column can be of any numeric type, in this case it is assumed to be a Unix timestamp. If it is a date-like datatype, it is converted to Unix timestamp internally assuming the timezone of the JVM. The ``default value`` is ``0`` which is interpreted as no expiry checking. ``wrench.token.jwt.secret`` --------------------------- The secret string used to validate incoming JWT tokens. When using JWT token authentication, you should not specify ``wrench.token.resolver.sql`` or ``wrench.token.resolver.url``. The incoming JWT token is parsed for the below claims: - ``sub``: the username, mandatory - ``ip``: optional, the IP address of the subject of the token, who originally received it. When ``wrench.token.ip.check`` is enabled, the IP is checked against the IP who presents the JWT token. - ``encoder``: optional, boolean flag indicating if the token was issued for publishing or playback - ``bitrateLimit``: optional, the bitrate limit associated with the owner - ``iat``: issued-at-timestamp, the JWT token creation timestamp. Can be used in conjuction with ``wrench.token.expiry.sec`` value if the expiration is to be controlled by the backend. Alternatively the client side can specify the ``exp`` claim in the token too. - ``exp``: optional, JWT expiration timestamp. Expired tokens are rejected immediately. Duplicate Checking Settings =========================== ``wrench.duplicate.check`` -------------------------- If set to true, all connections are only accepted if there is no active player with the same username (or token if configured so). You can also set up a tolerated concurrent session number by specifying ``wrench.duplicate.limit``. Please note that upon ungraceful disconnection of the players, it might take a while for Wowza to notice the disconnection. This is controlled by the VHost's ``idleDisconnectTimeout`` setting. **Default:** ``false`` ``wrench.duplicate.limit`` -------------------------- Controls the maximum allowed concurrent sessions per user. Works only if duplicate checking is enabled by ``wrench.duplicate.check``. **Default:** 1 ``wrench.duplicate.drop.other`` ------------------------------- If enabled, given you have a limit of n concurrent players set by ``wrench.duplicate.limit``, when the n+1-th player connects, the connection is accepted, but a randomly picked other user is going to be dropped. **Default:** ``false`` ``wrench.duplicate.check.sql`` ------------------------------ When specified Wrench will use this SQL query to check concurrent players instead of using the in-memory list of current players. This feature comes handy when you want to check concurrent players across a set of edge servers in a cluster. The query must return a single number telling Wrench the number of current players. You can use the ``wrench.connect.accept.sql`` query to populate the list of players in the database, and use the ``wrench.disconnect.log.time.sql`` to remove entries. The ``wrench.duplicate.drop.other`` feature is not working if the checking mode is SQL based. Parameters: ``:username`` ``wrench.duplicate.check.mode`` ------------------------------- Controls the attribute which is checked when duplicates are searched. The default value is ``username``, that means two sessions with the same resolved username are assumed the same. This is the most natural, however in some cases people want the ``token`` to be the base of the checking, not the username. Additional Token Checks ======================= ``wrench.user.agent.blacklist`` ------------------------------- Specifies the HTTP ``User-Agent`` header (or Flashver in case of RTMP clients) blacklist regular expression. **Example:** ``.*VLC.*`` ``wrench.user.agent.whitelist`` ------------------------------- Specifies the HTTP ``User-Agent`` header (or Flashver in case of RTMP clients) whitelist regular expression. ``wrench.http.referrer.blacklist`` ---------------------------------- Specifies the ``Http-Referer`` header blacklist regular expression ``wrench.http.referrer.whitelist`` ---------------------------------- Specifies the ``Http-Referer`` header whitelist regular expression ``wrench.http.autoaccept.ticket.count`` --------------------------------------- The number of subsequent connections made from the same IP with the same token that are automaticall accepted. This is needed when the website contains a direct link to the stream and the browser and the media player application both connect, but we don't want to count them as separate connections. **Default:** 3 ``wrench.http.autoaccept.ticket.timeout`` ----------------------------------------- The timeout value in seconds that belongs to the ``wrench.http.autoaccept.ticket.count`` feature. Subsequent connections from the same IP and with the same token are treated as a single connection. **Default:** 15 ``wrench.rtp.check.enable`` --------------------------- If disabled Wrech won't react to RTP session creation and destroy events (``onRTPSessionCreate`` and ``onRTPSessionDestroy``). This feature can be used for RTSP IP camera sources, where the camera is not able to pass even a hardcoded token for Wrench. You'll still have all features for RTMP and HTTP based players. **Default:** ``true`` ``wrench.http.streamer.request.check.enable`` --------------------------------------------- Enables an extra check on all incoming HTTP queries, not just the initial one that is fetching the m3u8 file. This is effective against direct chunklist access attempts and is recommended to be turned on. **Default:** ``false`` ``wrench.bypass.ip`` -------------------- You can define a comma separated list of IP addresses (or subnets with CIDR notation), which go to a whitelist. Any connection, encoder or client is accepted from these addresses. This can be used in case of hardware encoders that don't support query parameter sending in the URL. ``wrench.bypass.publish.allowed`` --------------------------------- If enabled, then connections from the configured bypass IP addresses are always allowed to publish, no authorization is made via webservice or SQL. This is a convenience property for these cases. **Default:** ``false`` ``wrench.bypass.play.allowed`` ------------------------------ If enabled, then connections from the configured bypass IP addresses are always allowed to play a stream, no authorization is made via webservice or SQL. This is a convenience property for these cases. **Default:** ``false`` ``wrench.force.secure.transport`` --------------------------------- When enabled, only HTTPS and RTMPS connections will be accepted, non-secure transports will be refused. **Default:** ``false`` ``wrench.publish.encoder.flag.check`` ------------------------------------- When enabled, this makes Wrench more strict about which clients are allowed to publish a stream. The token resolution SQL/webservice can optionally return an ``encoder`` flag information, that tells Wrench the role of the client. If this checking is on, then only those clients are allowed to publish, who have this flag set to true. By default Wrench is unaware of this role and allows publishing for all clients. **Default:** ``false`` ``wrench.ip.override.http.header`` ---------------------------------- The case insensitive name of the HTTP header which Wrench can assume to contain the IP address if the server is behind a proxy, e.g. ``X-Forwarded-For``. When using Chrome's Lite mode, the Google servers might fetch the m3u8 data from a different IP address before the mobile device would start playback. In this scenario this setting can be used to correlate the two events. ``wrench.auth.failed.video.http.url`` ------------------------------------- The URL of the video where the HTTP based players are redirected to if authorization fails. ``wrench.auth.failed.video.rtmp.url`` ------------------------------------- The URL of the video where the RTMP based players are redirected to if authorization fails Client Lifecycle Hooks ====================== These SQL and webservice hooks allow you to precisely log user events in your system. If ``wrench.publish.http.url`` is set, the lifecycle events are published as HTTP POST messages with JSON payload to your webservice. 1. Token resolution takes place first (via SQL or webservice call) (unless the connection comes from bypassed IP or using special token for encoders) 2. Connection authorization (``wrench.connect.authorization.sql``) 3. Connection accepted (``wrench.connect.accept.sql``) 4. Duplicate player dropped (``wrench.duplicate.drop.sql``) if duplicate checking is on and a drop happens 5. Publish authorization (``wrench.publish.authorization.sql``) if the connected user wants to publish something 6. Disconnect (``wrench.disconnect.log.time.sql``) when the client disconnects. This happens immediately in case of RTMP protocol, and with a certain delay in case of HTTP protocol. ``wrench.connect.authorization.sql`` ------------------------------------ Optional. If set, it is executed whenever a user successfully passed the token check. If the query returns at least one row, the authorization is successful, otherwise the connection is refused. Parameters: ``:username``, ``:stream``, ``:encoder``. The ``encoder`` value is either ``true`` or ``false`` depending on the role determined by the token resolver query or the webservice response. ``wrench.connect.authorization.url`` ------------------------------------ If set, this enables an external webservice HTTP POST upon each incoming connection. The body of the message is in JSON format: .. code-block:: javascript {"streamName": "mystream", "userName":"john", "token":"54ddec75e2294", "applicationName":"live", "applicationInstance":"_definst_"}. The expected response is HTTP 200 with a JSON content: ``{"result": "allow/deny"}``. The connection is processed depending on the response. If any communication error occurs, or non HTTP 200 response is received, the result is defined by the ``wrench.connect.authorization.url.default.result`` property as a fallback value. It is usually better optimistically allowing access to streaming in case of a service outage rather than blocking customers. ``wrench.connect.authorization.url.default.result`` --------------------------------------------------- The assumed authorization outcome result in case of any communication error, non-parseable JSON response or any HTTP response other than 200. It might be better optimistically allowing access to streaming in case of a service outage rather than blocking customers. By default it is ``false`` ``wrench.connect.accept.sql`` ----------------------------- Optional. If set, it is executed whenever a client successfully connected. Parameter: ``:username``, ``:token``, ``:hashedtoken``, ``:ip`` ``wrench.disconnect.log.time.sql`` ---------------------------------- SQL query that is executed when any client disconnects. Can be used for simple audit purposes. Parameters are: ``:username``, ``:session``, ``:stream`` and ``:elapsedtime`` this one contains the seconds elapsed since the player connected. For HTTP based players there is no permanent connections, so this is executed after a certain idle period. For RTMP clients this is executed immediately when the connection is closed. ``wrench.publish.authorization.sql`` ------------------------------------ Optional. If set, it is executed whenever an RTMP or RTP client starts publishing a stream. If it returns zero rows, the publishing is denied, otherwise publishing is allowed. Parameter: ``:username``, ``:stream`` ``wrench.publish.http.url`` --------------------------- An arbitrary URL where Wrench sends HTTP POST messages in JSON format when stream events occur. Events are: ``Publish``, ``Unpublish``, ``Pause``, ``Start``, ``Play``, ``Stop``, ``PauseRaw``, ``Disconnect``. The format of the JSON message is: ``{stream: "streamname", user: "username", event: "eventname"}``. This feature can be used to notify an external system about these events. The username is the username of the connecting encoder, which assumes that in this scenario encoders won't use the encodersecret hardcoded token, but will connect as regular users with dynamic token. Disconnect events are only published if ``wrench.disconnect.publish`` is turned on. ``wrench.duplicate.drop.sql`` ----------------------------- If set, it is executed for audit purposes whenever a client is dropped due to the duplicate checking mechanism kicking in, which of course needs to be enabled the same time. Parameter: ``:username`` ``wrench.disconnect.publish`` ----------------------------- Controls whether disconnect events are published to the ``wrench.publish.http.url`` or not. **Default:** ``false`` Pay-per-minute and pay-per-view configuration ============================================= Wrench enables you to accurately measure stream consumption for accounting or statistical purposes. The pay-per-view feature allows you to count how many times each user started watching your stream (allowing a small non-counted grace period). The pay-per-minute SQL and webservice hooks make allow you to measure the time spent watching the stream for stream monetization. The following SQL queries all have to be tailored to your DB schema and the syntax of your RDBMS. The potential properties that you can use in the queries are: - ``:username`` - the username, resolved by Wrench based on the passed token - ``:application`` - the name of the Wowza application - ``:elapsedtime`` - the number of elapsed seconds (also fractions, as returned by ``client.getElapsedTime().getTimeSeconds()``) - ``:session`` - a unique identifier of the user’s session generated by hashing the username and the connection time ``wrench.monitor.period`` ------------------------- The period time of the monitor job in seconds which performs all PPV and PPM data capture. This determines the minimum resolution in time of your captured data. **Default:** 60 ``wrench.ppv.grace.period`` --------------------------- Clients disconnecting before this period (in seconds) are not captured by the pay-per-view monitor, so effectively their connection does not count. **Default:** 5 ``wrench.ppv.insert.sql`` ------------------------- This query is executed whenever the ``wrench.ppv.update.sql`` did not update any rows in the database. This can be used to populate the database with a new row that captures that the user started first watching a stream. Example: :code:``insert into wtb_views (user, count) values (:username, 1)`` ``wrench.ppv.update.sql`` ------------------------- This is executed whenever a new user's connection time exceeds the grace period. Example: ``update wtb_views set count = count + 1 where user=:username`` ``wrench.ppm.insert.sql`` ------------------------- This query is executed whenever the ``wrench.ppm.update.sql`` does not affect any row in the database. Use it to insert new records into your table which will be updated later on normally. Example: ``insert into wtb_minutes (user, application, total, session) values (:username, :application, 0,:session)`` ``wrench.ppm.update.sql`` ------------------------- This query is executed for all users each time the monitor job is running. This should be used to update the playing time for each client. The session parameter is a hash generated from the username and the connect time to allow you storing total times of consequtive sessions in the same table. Example: ``update wtb_minutes set total=:elapsedtime where user=:username and application=:application and session=:session`` ``wrench.ppm.disconnect.sql`` ----------------------------- If set, this query is executed periodically on each monitor run. If the query returns 0 rows, the client is immediately dropped. This can be used to dynamically check its virtual balance (paid minutes left) and drop users if their balance goes down. ``wrench.ppm.update.publish`` ----------------------------- If set to ``true``, the PPM engine will POST JSON messages to the configured ``wrench.publish.http.url``. The message format is as follows: ..code-block:: { "event":"PpmUpdate", "timestamp":"2015-03-16 21:40:28.259" "users": [ {"username": "john", "duration":360.578, "session":""} ] } Dynamic public mode switching ============================= Wrench can temporarily disable its authorization and authentication process and allow access to your streams publicly. This mode can be useful if you are broadcasting a live event and want to make a part of it public, such as the opening ceremony of a football match. Wrench knows which clients came for free and which ones were **verified** and **unverified**. While in public mode, users with proper token will be verified and not dropped when you switch back to secured mode. The switching mechanism can be as simple as creating and deleting a particular file on your file system, or returning or not returning rows from an arbitrary SQL query. ``wrench.switchable.public`` ---------------------------- Set to true to enable dynamically switchable public mode feature. **Default:** ``false`` ``wrench.switchable.public.check.period`` ----------------------------------------- The period time of mode checking in seconds. **Default:** 10 ``wrench.switchable.public.check.mode`` --------------------------------------- The switch mechanism you want to use. Can be ``file`` or ``sql`` (case insensitive) ``wrench.switchable.public.check.file`` --------------------------------------- The name of the file used to determine current mode if check mode is set to file. If the file exists, the mode is assumed to be public, secured otherwise ``wrench.switchable.public.check.sql`` -------------------------------------- The SQL query used to determine current mode if check mode is set to sql. If the query returns empty result set, the mode is assumed to be secured, if any rows are returned, then public. You can use the following parameters in the query: ``:vhost``, ``:application``, ``:appinstance`` User Interface and REST API =========================== ``wrench.ui.enabled`` --------------------- Set to true to enable the web user interface and the REST API of Wrench that allows on-the-fly re-configuration of Wrench as well as certain management functions via API. The user interface and the API becomes online when the Wowza application in which Wrench is set up is actually started. This happens when a stream is published into that application or when the first player connects. This is what you should see in the logs if the UI is configured properly: .. code-block:: 15:22:01 WMSLogger wrenchexample1 INFO - Started Wrench UI on http://localhost:4567/wrench/login 15:22:01 WMSLogger wrenchexample1 INFO - wrenchexample1/_definst_ 15:22:01 WMSLogger wrenchexample1 INFO - 15:22:01 SparkServer wrenchexample1 INFO - == Spark has ignited ... 15:22:01 SparkServer wrenchexample1 INFO - >> Listening on 0.0.0.0:4567 15:22:01 AbstractConnector wrenchexample1 INFO - Started ServerConnector@31a44027{HTTP/1.1}{0.0.0.0:4567} The username and password for the login screen are those of the Wowza Streaming Engine Manager that can be found in the ``admin.password`` file under Wowza ``config`` directory. ``wrench.ui.port`` ------------------ The TCP port used by the web user interface. **Default:** 4567 ``wrench.rest.api.authentication`` ---------------------------------- Set to false if you want to allow talking to the API without any authentication. Currently Wrench comes with a session based authentication mechanism that is used by the UI's login form and an optionally configurable HTTP Basic authentication that has to be switched on. **Default:** true ``wrench.ui.ssl.enabled`` ------------------------- Set to true to enable SSL support in Wrench. When SSL is enabled, Wrench makes an attempt to find the keystore path and password from the VHost configuration in which the application is running. This means that if you have SSL set up in Wowza for streaming, Wrench should be able to pick up the same configuration automatically. **Default:** false The logs should show clearly if SSL is used or not: .. code-block:: Started Wrench UI on https://localhost:4567/wrench/login with SSL enabled or .. code-block:: Started Wrench UI on http://localhost:4567/wrench/login without SSL enabled ``wrench.ui.auth.basic`` ------------------------ Enables HTTP Basic authentication on the API. Please note that this is only secure if used in conjuction with SSL. **Default:** false ``wrench.ui.auth.basic.user`` ----------------------------- This gives you the ability to define a single user that can use the UI or the REST API additionally to the normal Wowza admin users ``wrench.ui.auth.basic.password`` --------------------------------- This gives you the ability to define a single user password that can use the UI or the REST API additionally to the normal Wowza admin users Logging ======= ``wrench.logging.verbose`` -------------------------- By default Wrench emits detailed logs about every decision it makes, which might not be appropriate for production systems. You can reduce the amount of logging by turning verbose logging to ``false``. When using Wrench in multiple applications on the same server, you might want to inject the Wowza application name into the log messages, so you can separate the interleaved events. (You can also achieve this by configuring different logfile for each application). Wrench puts the ``applicationName`` and ``applicationInstanceName`` into the so called `MDC context of log4j `__. This allows you to specify these in the log output pattern this way: .. code-block:: # Console appender log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %C{1} %X{applicationName} %-5p - %m%n This will result in the following output on stdout: .. code-block:: 15:22:01 WMSLogger wrenchexample1 INFO - Client connecting with id 307819994 and query string ... 15:22:01 WMSLogger wrenchexample1 INFO - Accepted encoder connection from IP 127.0.0.1 15:23:02 WMSLogger wrenchexample1 INFO - Performing monitor activity over 1 connected clients (rtmp: 1, http: 0, rtp: 0) 15:23:02 WMSLogger wrenchexample1 INFO - Wrench Monitor finished successfully in 2ms Licensing ========= ``wrench.license.file`` ----------------------- The license filename (or path + filename). If not specified, Wrench looks for the license file under the ``conf`` directory of the Wowza installation searching for any file matching the ``wrench-*.license`` pattern.