--- src/plugins/Makefile.in | 3 src/plugins/zoneedit.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++ src/plugins/zoneedit.h | 82 ++++++++++++++ 3 files changed, 364 insertions(+), 1 deletion(-) Index: updatedd-2.5/src/plugins/zoneedit.c =================================================================== --- /dev/null +++ updatedd-2.5/src/plugins/zoneedit.c @@ -0,0 +1,280 @@ +/* -- updatedd: zoneedit.c -- + * + * Copyright (C) 2002, 2003, 2004, 2005 Philipp Benner + * + * This file is part of UpdateDD - http://updatedd.philipp-benner.de. + * + * UpdateDD is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * UpdateDD is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with UpdateDD; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "zoneedit.h" + +static void +print_usage(char *pname, FILE *fp) +{ + (void)fprintf(fp, + "\nUsage: %s [...] %s -- [OPTION]... [USERNAME:PASSWORD] HOSTNAME\n\n", + pname, COLORED("zoneedit")); + (void)fprintf(fp, + "For security reasons use the environment variable LOGIN instead of\n" + "passing the login information directly.\n\n" + "Options:\n" + " -4 --ipv4
ip address version 4\n" + " -o --offline host is currently offline\n" + " --help print help and exit\n" + " --version display version information and exit\n\n" + + "Report bugs to <"EMAIL">.\n\n"); + + return; +} + +static void +print_version(FILE *fp) +{ + + (void)fprintf(fp, + "\n" PNAME " plugin for zoneedit.com version " VERSION ",\n" + "Copyright (C) 2005 Philipp Benner.\n" + HOMEPAGE "\n\n" + + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n" + "FOR A PARTICULAR PURPOSE.\n\n"); + + return; + +} + +static void +ret_msg(int mode, const char *fmt, ...) +{ + + va_list az; + + va_start(az, fmt); + (void)vs_warn(ret_msg_buf, BUFSIZE, mode, fmt, az); + va_end(az); + + return; + +} + +int +dyndns(int argc, char *argv[]) +{ + + struct arguments args; + int s, ret; + const char *ptr; + + (void)memset(&args, 0, sizeof(struct arguments)); + + if(get_flags(&args, argc, argv) != RET_OK) { + return RET_WRONG_USAGE; + } + + s = get_connection(DYNDNSHOST, PORT, &ptr); + if(s == -1) { + ret_msg(HERR, "%s: %s", ptr, DYNDNSHOST); + ret = RET_WARNING; + } else { + ret = update_dyndns(s, &args); + if(ret == RET_OK) { + ret = check_server_msg(s, args.hostname); + } + (void)close(s); + } + + return ret; + +} + +static int +get_flags(struct arguments *args, int argc, char *argv[]) +{ + + int c; + + for(;;) { + + int option_index = 0; + static struct option long_options[] = { + { "ipv4", 1, 0, '4' }, + { "help", 0, 0, 'h' }, + { "offline", 0, 0, 'o' }, + { "version", 0, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "4:o", + long_options, &option_index); + + if(c == -1) break; + + switch(c) { + case '4': + args->ipv4 = optarg; + break; + case 'o': + args->offline = 1; + break; + case 'h': + print_usage(argv[ARGV_PNAME], stdout); + exit(EXIT_SUCCESS); + case 'v': + print_version(stdout); + exit(EXIT_SUCCESS); + } + } + + switch(argc-optind) { + default: + ret_msg(NONE, "wrong usage"); + return RET_WRONG_USAGE; + + case 2: + args->login = getenv("LOGIN"); + if(args->login == NULL) { + ret_msg(NONE, + "environment variable LOGIN is empty"); + return RET_WRONG_USAGE; + } + break; + case 3: + args->login = argv[ARGV_LOGIN]; + } + args->hostname = argv[ARGV_HOSTNAME]; + + return RET_OK; + +} + +#define BUFLEN 4096 +#define BUFFREE(name) BUFLEN - strlen(name) + +static int +update_dyndns(const int s, struct arguments *args) +{ + + char *b64user; + char message[BUFLEN]; + + if(strlen(args->login) > 128) { + ret_msg(NONE, "username is too long"); + return RET_ERROR; + } + b64user = (char *)malloc((2 * strlen(args->login) + 1)); + if(b64user == NULL) { + ret_msg(PERR, "malloc() failed"); + return RET_WARNING; + } + (void)memset(b64user, 0, 2 * strlen(args->login) + 1); + + base64encode(args->login, b64user); + (void)snprintf(message, BUFLEN, + "GET https://%s/auth/dynamic.html?host=%s", + DYNDNSHOST, args->hostname); + + if(args->offline) { + (void)strncat(message, "&dnsto=0.0.0.0", BUFFREE(message)); + } + else if(args->ipv4) { + (void)strncat(message, "&dnsto=", BUFFREE(message)); + (void)strncat(message, args->ipv4, BUFFREE(message)); + } + + { + char buffer[1024]; + + (void)snprintf(buffer, 1024, + " HTTP/1.1\r\n" + "Host: %s\r\n" + "Authorization: Basic %s\r\n" + "User-Agent: %s %s - %s\r\n" + "Connection: close\r\n" + "Pragma: no-cache\r\n\r\n", + DYNDNSHOST, b64user, PNAME, VERSION, HOMEPAGE); + (void)strncat(message, buffer, BUFLEN - 1 - strlen(message)); + } + print_debug("\n\nMessage:" + "\n--------------------------------------\n" + "%s--------------------------------------\n\n", + message); + + if(write(s, message, strlen(message)) == -1) { + ret_msg(PERR, "write() failed"); + return RET_WARNING; + } + + free(b64user); + return RET_OK; + +} + +static int +check_server_msg(int s, const char *hostname) +{ + + char server_msg[BUFSIZE]; + + /* get server_msg */ + (void)memset(server_msg, 0, sizeof(server_msg)); + if(read(s, server_msg, sizeof(server_msg) - 1) < 0) { + ret_msg(PERR, "read() failed"); + return RET_WARNING; + } + + print_debug("\n\nServer message:" + "\n--------------------------------------\n" + "%s--------------------------------------\n\n", + server_msg); + + if(strstr(server_msg, "HTTP/1.1 200 OK") || + strstr(server_msg, "HTTP/1.0 200 OK")) { + if(strstr(server_msg, "SUCCESS CODE=")) { + ret_msg(NONE, "%s: Successful Update!", hostname); + return RET_OK; + } else if(strstr(server_msg, "ERROR CODE=")) { + ret_msg(NONE, "%s: Error! - %s", hostname, server_msg); + return RET_OK; + } else { + ret_msg(NONE, "%s: Unknown fault - %s", hostname, server_msg); + } + } else if(strstr(server_msg, "401 Authorization Required")) { + ret_msg(NONE, "zoneedit.com: wrong username or password"); + } else { + ret_msg(NONE, "zoneedit.com: Internal Server Error - %s", server_msg); + } + + return RET_ERROR; +} Index: updatedd-2.5/src/plugins/Makefile.in =================================================================== --- updatedd-2.5.orig/src/plugins/Makefile.in +++ updatedd-2.5/src/plugins/Makefile.in @@ -35,7 +35,7 @@ CFLAGS = -I$(top_builddir) -I$(top_srcdir)/include @CFLAGS@ -fPIC LIBERROR = $(top_builddir)/libexception_handle/libexception_handle.a -OBJECTS := changeip.o dyndns.o eurodyndns.o hn.o noip.o ods.o ovh.o regfish.o tzo.o +OBJECTS := changeip.o dyndns.o eurodyndns.o hn.o noip.o ods.o ovh.o regfish.o tzo.o zoneedit.o PLUGINS_ROOT := $(OBJECTS:.o= ) UNAME:=$(shell uname -s) @@ -78,5 +78,6 @@ ovh.o: ovh.h regfish.o: regfish.h tzo.o: tzo.h +zoneedit.o: zoneedit.h .PHONY: all plugins install uninstall clean distclean Index: updatedd-2.5/src/plugins/zoneedit.h =================================================================== --- /dev/null +++ updatedd-2.5/src/plugins/zoneedit.h @@ -0,0 +1,82 @@ +/* -- updatedd: zoneedit.h -- + * + * Copyright (C) 2002, 2003, 2004, 2005 Philipp Benner + * + * This file is part of UpdateDD - http://updatedd.philipp-benner.de. + * + * UpdateDD is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * UpdateDD is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with UpdateDD; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#define DYNDNSHOST "www.zoneedit.com" +#define PORT 80 + +#define BUFSIZE 4096 + +#define ARGV_PNAME 0 +#define ARGV_LOGIN argc-2 +#define ARGV_HOSTNAME argc-1 + +#define COLORED(x) "\033[0;39;1m"x"\033[0m" + +static char ret_msg_buf[BUFSIZE]; + +struct arguments { + const char *hostname; + char *ipv4; + char *login; + int offline; +}; + +/* static struct dyndns_return_codes { */ +/* const char *code; */ +/* const char *message; */ +/* const int error; */ +/* } return_codes[] = { */ +/* { "badauth", "Bad authorization (username or password).", 1 }, */ +/* { "badsys", "The system parameter given was not valid.", 1 }, */ +/* { "badagent", "The useragent your client sent has been blocked " */ +/* "at the access level.", 1 */ +/* }, */ +/* { "good", "Update good and successful, IP updated.", 0 }, */ +/* { "nochg", "No changes, update considered abusive.", 0 }, */ +/* { "notfqdn", "A Fully-Qualified Domain Name was not provided.", 1 }, */ +/* { "nohost", "The hostname specified does not exist.", 1 }, */ +/* { "!donator", "The offline setting was set, when the user is " */ +/* "not a donator.", 1 */ +/* }, */ +/* { "!yours", "The hostname specified exists, but not under " */ +/* "the username currently being used.", 1 */ +/* }, */ +/* { "!active", "The hostname specified is in a Custom DNS " */ +/* "domain which has not yet been activated.", 1 */ +/* }, */ +/* { "abuse", "The hostname specified is blocked for abuse", 1 }, */ +/* { "notfqdn", "No hosts are given.", 1 }, */ +/* { "numhost", "Too many or too few hosts found.", 1 }, */ +/* { "dnserr", "DNS error encountered.", 1 }, */ +/* { NULL, NULL, 0 } */ +/* }; */ + +static int get_flags(struct arguments *args, int argc, char *argv[]); +static int update_dyndns(const int s, struct arguments *args); +static int check_server_msg(const int s, const char *hostnames); + +char * +get_retmsg(void) +{ + return ret_msg_buf; +}