Exemplo n.º 1
0
void ESP_MQTTLogger::_mqttSetup() {

  if (!_authenticate()){
    _server->send(401, "text/plain", "Unauthorised");
    return;
  }

  if(_server->hasArg("mqtt_url")) {

    if (!_parseMQTTUrl(_server->arg("mqtt_url"))){
      _server->send(400, "text/plain", "Invalid URL");
      return;
    }

    _mqttUrl = _server->arg("mqtt_url");

#ifdef MQTT_LOGGER_DEBUG
    DEBUG_OUTPUT.print("configuring mqttUrl: ");
    DEBUG_OUTPUT.println(_mqttUrl);
#endif

    if (!_saveMQTTUrl()) {
    _server->send(500, "text/plain", "Save configuration failed");
    }
    _server->send(200, "text/plain", "OK");

    return;
  }

  _server->send(400, "text/plain", "");
}
Exemplo n.º 2
0
void NetworkInterfaceASIO::_runIsMaster(AsyncOp* op) {
    // We use a legacy builder to create our ismaster request because we may
    // have to communicate with servers that do not support OP_COMMAND
    rpc::LegacyRequestBuilder requestBuilder{};
    requestBuilder.setDatabase("admin");
    requestBuilder.setCommandName("isMaster");
    requestBuilder.setMetadata(rpc::makeEmptyMetadata());
    requestBuilder.setCommandArgs(BSON("isMaster" << 1));

    // Set current command to ismaster request and run
    auto beginStatus = op->beginCommand(std::move(*(requestBuilder.done())));
    if (!beginStatus.isOK()) {
        return _completeOperation(op, beginStatus);
    }

    // Callback to parse protocol information out of received ismaster response
    auto parseIsMaster = [this, op]() {

        auto swCommandReply = op->command()->response(rpc::Protocol::kOpQuery, now());
        if (!swCommandReply.isOK()) {
            return _completeOperation(op, swCommandReply.getStatus());
        }

        auto commandReply = std::move(swCommandReply.getValue());

        if (_hook) {
            // Run the validation hook.
            auto validHost = callNoexcept(
                *_hook, &NetworkConnectionHook::validateHost, op->request().target, commandReply);
            if (!validHost.isOK()) {
                return _completeOperation(op, validHost);
            }
        }

        auto protocolSet = rpc::parseProtocolSetFromIsMasterReply(commandReply.data);
        if (!protocolSet.isOK())
            return _completeOperation(op, protocolSet.getStatus());

        op->connection().setServerProtocols(protocolSet.getValue());

        // Set the operation protocol
        auto negotiatedProtocol =
            rpc::negotiate(op->connection().serverProtocols(), op->connection().clientProtocols());

        if (!negotiatedProtocol.isOK()) {
            return _completeOperation(op, negotiatedProtocol.getStatus());
        }

        op->setOperationProtocol(negotiatedProtocol.getValue());

        return _authenticate(op);

    };

    _asyncRunCommand(op->command(),
                     [this, op, parseIsMaster](std::error_code ec, size_t bytes) {
                         _validateAndRun(op, ec, std::move(parseIsMaster));
                     });
}
void NetworkInterfaceASIO::_runIsMaster(AsyncOp* op) {
    // We use a legacy builder to create our ismaster request because we may
    // have to communicate with servers that do not support OP_COMMAND
    rpc::LegacyRequestBuilder requestBuilder{};
    requestBuilder.setDatabase("admin");
    requestBuilder.setCommandName("isMaster");
    requestBuilder.setMetadata(rpc::makeEmptyMetadata());
    requestBuilder.setCommandArgs(BSON("isMaster" << 1));

    // Set current command to ismaster request and run
    auto& cmd = op->beginCommand(std::move(*(requestBuilder.done())));

    // Callback to parse protocol information out of received ismaster response
    auto parseIsMaster = [this, op]() {
        try {
            auto commandReply = rpc::makeReply(&(op->command().toRecv()));
            BSONObj isMasterReply = commandReply->getCommandReply();

            auto protocolSet = rpc::parseProtocolSetFromIsMasterReply(isMasterReply);
            if (!protocolSet.isOK())
                return _completeOperation(op, protocolSet.getStatus());

            op->connection().setServerProtocols(protocolSet.getValue());

            // Set the operation protocol
            auto negotiatedProtocol = rpc::negotiate(op->connection().serverProtocols(),
                                                     op->connection().clientProtocols());

            if (!negotiatedProtocol.isOK()) {
                return _completeOperation(op, negotiatedProtocol.getStatus());
            }

            op->setOperationProtocol(negotiatedProtocol.getValue());

            // Advance the state machine
            return _authenticate(op);

        } catch (...) {
            // makeReply will throw if the reply was invalid.
            return _completeOperation(op, exceptionToStatus());
        }
    };

    _asyncRunCommand(&cmd,
                     [this, op, parseIsMaster](std::error_code ec, size_t bytes) {
                         _validateAndRun(op, ec, std::move(parseIsMaster));
                     });
}
    bool CmdAuthenticate::run(const string& dbname,
                              BSONObj& cmdObj,
                              int,
                              string& errmsg,
                              BSONObjBuilder& result,
                              bool fromRepl) {

        mutablebson::Document cmdToLog(cmdObj, mutablebson::Document::kInPlaceDisabled);
        redactForLogging(&cmdToLog);
        log() << " authenticate db: " << dbname << " " << cmdToLog << endl;

        UserName user(cmdObj.getStringField("user"), dbname);
        if (Command::testCommandsEnabled &&
                user.getDB() == "admin" &&
                user.getUser() == internalSecurity.user->getName().getUser()) {
            // Allows authenticating as the internal user against the admin database.  This is to
            // support the auth passthrough test framework on mongos (since you can't use the local
            // database on a mongos, so you can't auth as the internal user without this).
            user = internalSecurity.user->getName();
        }

        std::string mechanism = cmdObj.getStringField("mechanism");
        if (mechanism.empty()) {
            mechanism = "MONGODB-CR";
        }
        Status status = _authenticate(mechanism, user, cmdObj);
        audit::logAuthentication(ClientBasic::getCurrent(),
                                 mechanism,
                                 user,
                                 status.code());
        if (!status.isOK()) {
            log() << "Failed to authenticate " << user << " with mechanism " << mechanism << ": " <<
                status;
            if (status.code() == ErrorCodes::AuthenticationFailed) {
                // Statuses with code AuthenticationFailed may contain messages we do not wish to
                // reveal to the user, so we return a status with the message "auth failed".
                appendCommandStatus(result,
                                    Status(ErrorCodes::AuthenticationFailed, "auth failed"));
            }
            else {
                appendCommandStatus(result, status);
            }
            return false;
        }
        result.append("dbname", user.getDB());
        result.append("user", user.getUser());
        return true;
    }
Exemplo n.º 5
0
    bool CmdAuthenticate::run(const string& dbname,
                              BSONObj& cmdObj,
                              int,
                              string& errmsg,
                              BSONObjBuilder& result,
                              bool fromRepl) {

        mutablebson::Document cmdToLog(cmdObj, mutablebson::Document::kInPlaceDisabled);
        redactForLogging(&cmdToLog);
        log() << " authenticate db: " << dbname << " " << cmdToLog << endl;
        UserName user(cmdObj.getStringField("user"), dbname);
        std::string mechanism = cmdObj.getStringField("mechanism");
        if (mechanism.empty()) {
            mechanism = "MONGODB-CR";
        }
        Status status = _authenticate(mechanism, user, cmdObj);
        audit::logAuthentication(ClientBasic::getCurrent(),
                                 mechanism,
                                 user,
                                 status.code());
        if (!status.isOK()) {
            log() << "Failed to authenticate " << user << " with mechanism " << mechanism << ": " <<
                status;
            if (status.code() == ErrorCodes::AuthenticationFailed) {
                // Statuses with code AuthenticationFailed may contain messages we do not wish to
                // reveal to the user, so we return a status with the message "auth failed".
                appendCommandStatus(result,
                                    Status(ErrorCodes::AuthenticationFailed, "auth failed"));
            }
            else {
                appendCommandStatus(result, status);
            }
            return false;
        }
        result.append("dbname", user.getDB());
        result.append("user", user.getUser());
        return true;
    }
Exemplo n.º 6
0
void NetworkInterfaceASIO::_runIsMaster(AsyncOp* op) {
    // We use a legacy builder to create our ismaster request because we may
    // have to communicate with servers that do not support OP_COMMAND
    rpc::LegacyRequestBuilder requestBuilder{};
    requestBuilder.setDatabase("admin");
    requestBuilder.setCommandName("isMaster");

    BSONObjBuilder bob;
    bob.append("isMaster", 1);
    bob.append("hangUpOnStepDown", false);

    const auto versionString = VersionInfoInterface::instance().version();
    ClientMetadata::serialize(_options.instanceName, versionString, &bob);

    if (Command::testCommandsEnabled) {
        // Only include the host:port of this process in the isMaster command request if test
        // commands are enabled. mongobridge uses this field to identify the process opening a
        // connection to it.
        StringBuilder sb;
        sb << getHostName() << ':' << serverGlobalParams.port;
        bob.append("hostInfo", sb.str());
    }

    op->connection().getCompressorManager().clientBegin(&bob);

    if (WireSpec::instance().isInternalClient) {
        WireSpec::appendInternalClientWireVersion(WireSpec::instance().outgoing, &bob);
    }

    requestBuilder.setCommandArgs(bob.done());
    requestBuilder.setMetadata(rpc::makeEmptyMetadata());

    // Set current command to ismaster request and run
    auto beginStatus = op->beginCommand(requestBuilder.done(), op->request().target);
    if (!beginStatus.isOK()) {
        return _completeOperation(op, beginStatus);
    }

    // Callback to parse protocol information out of received ismaster response
    auto parseIsMaster = [this, op]() {

        auto swCommandReply = op->command()->response(op, rpc::Protocol::kOpQuery, now());
        if (!swCommandReply.isOK()) {
            return _completeOperation(op, swCommandReply);
        }

        auto commandReply = std::move(swCommandReply);

        // Ensure that the isMaster response is "ok:1".
        auto commandStatus = getStatusFromCommandResult(commandReply.data);
        if (!commandStatus.isOK()) {
            return _completeOperation(op, commandStatus);
        }

        auto protocolSet = rpc::parseProtocolSetFromIsMasterReply(commandReply.data);
        if (!protocolSet.isOK())
            return _completeOperation(op, protocolSet.getStatus());

        auto validateStatus =
            rpc::validateWireVersion(WireSpec::instance().outgoing, protocolSet.getValue().version);
        if (!validateStatus.isOK()) {
            warning() << "remote host has incompatible wire version: " << validateStatus;

            return _completeOperation(op, validateStatus);
        }

        op->connection().setServerProtocols(protocolSet.getValue().protocolSet);

        invariant(op->connection().clientProtocols() != rpc::supports::kNone);
        // Set the operation protocol
        auto negotiatedProtocol =
            rpc::negotiate(op->connection().serverProtocols(), op->connection().clientProtocols());

        if (!negotiatedProtocol.isOK()) {
            // Add relatively verbose logging here, since this should not happen unless we are
            // mongos and we try to connect to a node that doesn't support OP_COMMAND.
            warning() << "failed to negotiate protocol with remote host: " << op->request().target;
            warning() << "request was: " << redact(op->request().cmdObj);
            warning() << "response was: " << redact(commandReply.data);

            auto clientProtos = rpc::toString(op->connection().clientProtocols());
            if (clientProtos.isOK()) {
                warning() << "our (client) supported protocols: " << clientProtos.getValue();
            }
            auto serverProtos = rpc::toString(op->connection().serverProtocols());
            if (serverProtos.isOK()) {
                warning() << "remote server's supported protocols:" << serverProtos.getValue();
            }
            return _completeOperation(op, negotiatedProtocol.getStatus());
        }

        op->setOperationProtocol(negotiatedProtocol.getValue());

        op->connection().getCompressorManager().clientFinish(commandReply.data);

        if (_hook) {
            // Run the validation hook.
            auto validHost = callNoexcept(
                *_hook, &NetworkConnectionHook::validateHost, op->request().target, commandReply);
            if (!validHost.isOK()) {
                return _completeOperation(op, validHost);
            }
        }

        return _authenticate(op);

    };

    _asyncRunCommand(op, [this, op, parseIsMaster](std::error_code ec, size_t bytes) {
        _validateAndRun(op, ec, std::move(parseIsMaster));
    });
}
Exemplo n.º 7
0
static char *
authdes_ezdecode(const char *inmsg, int len)
{
    struct rpc_msg msg;
    char cred_area[MAX_AUTH_BYTES];
    char verf_area[MAX_AUTH_BYTES];
    char *temp_inmsg;
    struct svc_req r;
    bool_t res0, res1;
    XDR xdr;
    SVCXPRT xprt;

    temp_inmsg = malloc(len);
    memmove(temp_inmsg, inmsg, len);

    memset((char *) &msg, 0, sizeof(msg));
    memset((char *) &r, 0, sizeof(r));
    memset(cred_area, 0, sizeof(cred_area));
    memset(verf_area, 0, sizeof(verf_area));

    msg.rm_call.cb_cred.oa_base = cred_area;
    msg.rm_call.cb_verf.oa_base = verf_area;
    why = AUTH_FAILED;
    xdrmem_create(&xdr, temp_inmsg, len, XDR_DECODE);

    if ((r.rq_clntcred = malloc(MAX_AUTH_BYTES)) == NULL)
        goto bad1;
    r.rq_xprt = &xprt;

    /* decode into msg */
    res0 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_cred));
    res1 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_verf));
    if (!(res0 && res1))
        goto bad2;

    /* do the authentication */

    r.rq_cred = msg.rm_call.cb_cred;    /* read by opaque stuff */
    if (r.rq_cred.oa_flavor != AUTH_DES) {
        why = AUTH_TOOWEAK;
        goto bad2;
    }
#ifdef SVR4
    if ((why = __authenticate(&r, &msg)) != AUTH_OK) {
#else
    if ((why = _authenticate(&r, &msg)) != AUTH_OK) {
#endif
        goto bad2;
    }
    return (((struct authdes_cred *) r.rq_clntcred)->adc_fullname.name);

bad2:
    free(r.rq_clntcred);
bad1:
    return ((char *) 0);        /* ((struct authdes_cred *) NULL); */
}

static XID rpc_id = (XID) ~0L;

static Bool
CheckNetName(unsigned char *addr, short len, pointer closure)
{
    return (len == strlen((char *) closure) &&
            strncmp((char *) addr, (char *) closure, len) == 0);
}

static char rpc_error[MAXNETNAMELEN + 50];

_X_HIDDEN XID
SecureRPCCheck(unsigned short data_length, const char *data,
               ClientPtr client, const char **reason)
{
    char *fullname;

    if (rpc_id == (XID) ~0L) {
        *reason = "Secure RPC authorization not initialized";
    }
    else {
        fullname = authdes_ezdecode(data, data_length);
        if (fullname == (char *) 0) {
            snprintf(rpc_error, sizeof(rpc_error),
                     "Unable to authenticate secure RPC client (why=%d)", why);
            *reason = rpc_error;
        }
        else {
            if (ForEachHostInFamily(FamilyNetname, CheckNetName, fullname))
                return rpc_id;
            snprintf(rpc_error, sizeof(rpc_error),
                     "Principal \"%s\" is not authorized to connect", fullname);
            *reason = rpc_error;
        }
    }
    return (XID) ~0L;
}
Exemplo n.º 8
0
void
svc_getreq_common (const int fd)
{
  enum xprt_stat stat;
  struct rpc_msg msg;
  register SVCXPRT *xprt;
  char cred_area[2 * MAX_AUTH_BYTES + RQCRED_SIZE];
  msg.rm_call.cb_cred.oa_base = cred_area;
  msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);

  xprt = xports[fd];
  /* Do we control fd? */
  if (xprt == NULL)
     return;

  /* now receive msgs from xprtprt (support batch calls) */
  do
    {
      if (SVC_RECV (xprt, &msg))
	{
	  /* now find the exported program and call it */
	  struct svc_callout *s;
	  struct svc_req r;
	  enum auth_stat why;
	  rpcvers_t low_vers;
	  rpcvers_t high_vers;
	  int prog_found;

	  r.rq_clntcred = &(cred_area[2 * MAX_AUTH_BYTES]);
	  r.rq_xprt = xprt;
	  r.rq_prog = msg.rm_call.cb_prog;
	  r.rq_vers = msg.rm_call.cb_vers;
	  r.rq_proc = msg.rm_call.cb_proc;
	  r.rq_cred = msg.rm_call.cb_cred;

	  /* first authenticate the message */
	  /* Check for null flavor and bypass these calls if possible */

	  if (msg.rm_call.cb_cred.oa_flavor == AUTH_NULL)
	    {
	      r.rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
	      r.rq_xprt->xp_verf.oa_length = 0;
	    }
	  else if ((why = _authenticate (&r, &msg)) != AUTH_OK)
	    {
	      svcerr_auth (xprt, why);
	      goto call_done;
	    }

	  /* now match message with a registered service */
	  prog_found = FALSE;
	  low_vers = 0 - 1;
	  high_vers = 0;

	  for (s = svc_head; s != NULL_SVC; s = s->sc_next)
	    {
	      if (s->sc_prog == r.rq_prog)
		{
		  if (s->sc_vers == r.rq_vers)
		    {
		      (*s->sc_dispatch) (&r, xprt);
		      goto call_done;
		    }
		  /* found correct version */
		  prog_found = TRUE;
		  if (s->sc_vers < low_vers)
		    low_vers = s->sc_vers;
		  if (s->sc_vers > high_vers)
		    high_vers = s->sc_vers;
		}
	      /* found correct program */
	    }
	  /* if we got here, the program or version
	     is not served ... */
	  if (prog_found)
	    svcerr_progvers (xprt, low_vers, high_vers);
	  else
	    svcerr_noprog (xprt);
	  /* Fall through to ... */
	}
    call_done:
      if ((stat = SVC_STAT (xprt)) == XPRT_DIED)
	{
	  SVC_DESTROY (xprt);
	  break;
	}
    }
  while (stat == XPRT_MOREREQS);
}
Exemplo n.º 9
0
void NetworkInterfaceASIO::_sslHandshake(AsyncOp* op) {
    // TODO: Implement asynchronous SSL, SERVER-19221
    _authenticate(op);
}
Exemplo n.º 10
0
void
svc_getreq_common(int fd)
{
	enum xprt_stat stat;
	struct rpc_msg msg;
	int prog_found;
	u_long low_vers;
	u_long high_vers;
	struct svc_req r;
	SVCXPRT *xprt;
	char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];

	msg.rm_call.cb_cred.oa_base = cred_area;
	msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
	r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);

	/* sock has input waiting */
	xprt = xports[fd];
	if (xprt == NULL)
		/* But do we control the fd? */
		return;
	/* now receive msgs from xprtprt (support batch calls) */
	do {
		if (SVC_RECV(xprt, &msg)) {
			/* find the exported program and call it */
			struct svc_callout *s;
			enum auth_stat why;

			r.rq_xprt = xprt;
			r.rq_prog = msg.rm_call.cb_prog;
			r.rq_vers = msg.rm_call.cb_vers;
			r.rq_proc = msg.rm_call.cb_proc;
			r.rq_cred = msg.rm_call.cb_cred;
			/* first authenticate the message */
			if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
				svcerr_auth(xprt, why);
				goto call_done;
			}
			/* now match message with a registered service*/
			prog_found = FALSE;
			low_vers = (u_long) -1;
			high_vers = 0;
			for (s = svc_head; s != NULL; s = s->sc_next) {
				if (s->sc_prog == r.rq_prog) {
					if (s->sc_vers == r.rq_vers) {
						(*s->sc_dispatch)(&r, xprt);
						goto call_done;
					}  /* found correct version */
					prog_found = TRUE;
					if (s->sc_vers < low_vers)
						low_vers = s->sc_vers;
					if (s->sc_vers > high_vers)
						high_vers = s->sc_vers;
				}   /* found correct program */
			}
			/*
			 * if we got here, the program or version
			 * is not served ...
			 */
			if (prog_found)
				svcerr_progvers(xprt, low_vers, high_vers);
			else
				 svcerr_noprog(xprt);
			/* Fall through to ... */
		}
	call_done:
		if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
			SVC_DESTROY(xprt);
			break;
		}
	} while (stat == XPRT_MOREREQS);
}
Exemplo n.º 11
0
int
main(int argc, char *argv[])
{
	const char *program_name;
	char	*service, *user;
	int	fd;
	uid_t	uid;

	uid = getuid();

	/*
	 * Make sure standard file descriptors are connected.
	 */
	while ((fd = open("/dev/null", O_RDWR)) <= 2)
		;
	close(fd);

	/*
	 * Get the program name
	 */
	if (argc == 0)
		program_name = "hawk_chkpwd";
	else if ((program_name = strrchr(argv[0], '/')) != NULL)
		program_name++;
	else
		program_name = argv[0];

	/*
	 * Catch or ignore as many signal as possible.
	 */
	setup_signals();

	/*
	 * Check argument list
	 */
	if (argc != 3) {
		_log_err(LOG_NOTICE, "Bad number of arguments (%d)", argc);
		return UNIX_FAILED;
	}

	/*
	 * Get the service name and do some sanity checks on it
	 */
	service = argv[1];
	if (!sane_pam_service(service)) {
		_log_err(LOG_ERR, "Illegal service name '%s'", service);
		return UNIX_FAILED;
	}

	/*
	 * Discourage users messing around (fat chance)
	 */
	if (isatty(STDIN_FILENO) && uid != 0) {
		_log_err(LOG_NOTICE,
			"Inappropriate use of Unix helper binary [UID=%d]",
			 uid);
		fprintf(stderr,
			"This binary is not designed for running in this way\n"
			"-- the system administrator has been informed\n");
		sleep(10);	/* this should discourage/annoy the user */
		return UNIX_FAILED;
	}

	/*
	 * determine the caller's user name
	 */
	user = getuidname(uid);
	if (strcmp(user, argv[2])) {
		/* Discourage use of this program as a
		 * password cracker */
		if (uid != 0 && strcmp(user, HACLUSTER))
			sleep(5);
		user = argv[2];
	}
	if (!in_haclient_grp(user)) {
		_log_err(LOG_NOTICE,
			"Failed to authenticate user '%s' (not in group '%s')",
			user, HACLIENT);
		return UNIX_FAILED;
	}
	return _authenticate(service, user);
}