/*
* Copyright (c) 2007 Hypertriton, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "machctld.h"
#include "pathnames.h"
#include "protocol.h"
#include "prog.h"
#include
volatile int gothup = 0;
NS_Server *ns;
MC_User *mcUser;
int verbose = 0;
static void
sig_hup(int sigraised)
{
gothup++;
}
static int
HandleError(NS_Server *ns)
{
NS_Message(ns, 1, "%s", AG_GetError());
return (0);
}
static int
version(NS_Server *ns, NS_Command *cmd, void *p)
{
char hostname[128];
gethostname(hostname, sizeof(hostname));
NS_Message(ns, 0, "machctld:%s:%s", VERSION, hostname);
return (0);
}
static int
auth_password(NS_Server *ns, void *p)
{
char buf[65], *pBuf = &buf[0];
char *name, *pass;
MC_User *u;
size_t end;
if (fgets(buf, sizeof(buf), stdin) == NULL)
return (-1);
if ((name = strsep(&pBuf, ":")) == NULL ||
(pass = strsep(&pBuf, ":")) == NULL) {
return (-1);
}
end = strlen(pass)-1;
if (pass[end] == '\n')
pass[end] = '\0';
if ((u = MC_UserLookup(name)) == NULL) {
NS_Log(NS_INFO, "%s: no such user", name);
goto fail;
}
if (strcmp(pass, u->pass) == 0) {
mcUser = u;
NS_Log(NS_INFO, "%s: login successful", name);
return (1);
}
NS_Log(NS_INFO, "%s: password mismatch", name);
fail:
AG_SetError("Unknown username or password mismatch");
return (0);
}
static int
auth_pubkey(NS_Server *ns, void *p)
{
AG_SetError("Public key auth is not implemented");
return (0);
}
int
main(int argc, char *argv[])
{
char *host = NULL;
char *port = _PROTO_PORT;
char *dir = _PATH_DATA;
MC_User *u;
struct sigaction sa;
int i;
if (AG_InitCore("machctld", 0) == -1) {
fprintf(stderr, "%s\n", AG_GetError());
return (1);
}
while ((i = getopt(argc, argv, "b:p:d:Vv?")) != -1) {
extern char *__progname;
switch (i) {
case 'b':
host = optarg;
break;
case 'p':
port = optarg;
break;
case 'd':
dir = optarg;
break;
case 'v':
verbose = 1;
break;
case 'V':
printf("%s %s\n", __progname, VERSION);
exit(0);
case '?':
default:
printf("Usage: %s [-aVv] [-b host] [-p port] "
"[-d dir]\n", __progname);
exit(0);
}
}
/* Initialize the user manager. */
AG_RegisterClass(&mcUserClass);
AG_ObjectInitStatic(&mcUserMgr, &mcUserClass);
AG_ObjectSetName(&mcUserMgr, "UserMgr");
AG_ObjectLoad(&mcUserMgr);
AGOBJECT_FOREACH_CLASS(u, &mcUserMgr, mc_user, "MC_User:*") {
if (AG_ObjectPageIn(u) == -1)
fprintf(stderr, "%s\n", AG_GetError());
}
/* Move to the data directory. */
if (chdir(dir) == -1) {
fprintf(stderr, "%s: %s\n", dir, strerror(errno));
exit(1);
}
/* Initialize the server. */
NS_InitSubsystem(0);
ns = NS_ServerNew(NULL, 0, "_server", _PROTO_NAME, _PROTO_VER, port);
NS_ServerBind(ns, host, port);
sa.sa_flags = 0;
sa.sa_handler = sig_hup;
sigaction(SIGHUP, &sa, NULL);
/* Register our auth methods and error functions. */
NS_RegAuthMode(ns, "password", auth_password, NULL);
NS_RegAuthMode(ns, "public-key", auth_pubkey, NULL);
NS_RegErrorFn(ns, HandleError);
/* Register the daemon functions. */
NS_RegCmd(ns, "version", version, NULL);
NS_RegCmd(ns, "prog-commit", prog_commit, NULL);
NS_RegCmd(ns, "prog-fetch", prog_fetch, NULL);
NS_RegCmd(ns, "prog-list", prog_list, NULL);
if (verbose) {
printf("Listening on %s:%s (Protocol = %s %s)\n",
host, port, _PROTO_NAME, _PROTO_VER);
}
if (NS_Listen(ns) == -1) {
fprintf(stderr, "%s.%s: %s\n", host, port, strerror(errno));
exit(1);
}
AG_ObjectDetach(ns);
AG_ObjectDestroy(ns);
Free(ns);
AG_Destroy();
return (0);
}