Esempio n. 1
0
  /** @see net.sf.kraken.session.TransportSession#logIn(net.sf.kraken.type.PresenceType, String) */
  @Override
  public void logIn(PresenceType presenceType, String verboseStatus) {
    final org.jivesoftware.smack.packet.Presence presence =
        new org.jivesoftware.smack.packet.Presence(
            org.jivesoftware.smack.packet.Presence.Type.available);
    if (JiveGlobals.getBooleanProperty(
            "plugin.gateway." + getTransport().getType() + ".avatars", true)
        && getAvatar() != null) {
      Avatar avatar = getAvatar();
      // Same thing in this case, so lets go ahead and set them.
      avatar.setLegacyIdentifier(avatar.getXmppHash());
      VCardUpdateExtension ext = new VCardUpdateExtension();
      ext.setPhotoHash(avatar.getLegacyIdentifier());
      presence.addExtension(ext);
    }
    final Presence.Mode pMode =
        ((XMPPTransport) getTransport()).convertGatewayStatusToXMPP(presenceType);
    if (pMode != null) {
      presence.setMode(pMode);
    }
    if (verboseStatus != null && verboseStatus.trim().length() > 0) {
      presence.setStatus(verboseStatus);
    }
    setPendingPresenceAndStatus(presenceType, verboseStatus);

    if (!this.isLoggedIn()) {
      listener = new XMPPListener(this);
      presenceHandler = new XMPPPresenceHandler(this);
      runThread =
          new Thread() {
            @Override
            public void run() {
              String userName = generateUsername(registration.getUsername());
              conn = new XMPPConnection(config);
              try {
                conn.getSASLAuthentication()
                    .registerSASLMechanism("DIGEST-MD5", MySASLDigestMD5Mechanism.class);
                if (getTransport().getType().equals(TransportType.facebook)
                    && registration.getUsername().equals("{PLATFORM}")) {
                  conn.getSASLAuthentication()
                      .registerSASLMechanism(
                          "X-FACEBOOK-PLATFORM", FacebookConnectSASLMechanism.class);
                  conn.getSASLAuthentication().supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
                }

                Roster.setDefaultSubscriptionMode(SubscriptionMode.manual);
                conn.connect();
                conn.addConnectionListener(listener);
                try {
                  conn.addPacketListener(
                      presenceHandler,
                      new PacketTypeFilter(org.jivesoftware.smack.packet.Presence.class));
                  // Use this to filter out anything we don't care about
                  conn.addPacketListener(
                      listener,
                      new OrFilter(
                          new PacketTypeFilter(GoogleMailBoxPacket.class),
                          new PacketExtensionFilter(
                              GoogleNewMailExtension.ELEMENT_NAME,
                              GoogleNewMailExtension.NAMESPACE)));
                  conn.login(userName, registration.getPassword(), xmppResource);
                  conn.sendPacket(presence); // send initial presence.
                  conn.getChatManager().addChatListener(listener);
                  conn.getRoster().addRosterListener(listener);

                  if (JiveGlobals.getBooleanProperty(
                          "plugin.gateway." + getTransport().getType() + ".avatars",
                          !TransportType.facebook.equals(getTransport().getType()))
                      && getAvatar() != null) {
                    new Thread() {
                      @Override
                      public void run() {
                        Avatar avatar = getAvatar();

                        VCard vCard = new VCard();
                        try {
                          vCard.load(conn);
                          vCard.setAvatar(
                              Base64.decode(avatar.getImageData()), avatar.getMimeType());
                          vCard.save(conn);
                        } catch (XMPPException e) {
                          Log.debug("XMPP: Error while updating vcard for avatar change.", e);
                        } catch (NotFoundException e) {
                          Log.debug("XMPP: Unable to find avatar while setting initial.", e);
                        }
                      }
                    }.start();
                  }

                  setLoginStatus(TransportLoginStatus.LOGGED_IN);
                  syncUsers();

                  if (getTransport().getType().equals(TransportType.gtalk)
                      && JiveGlobals.getBooleanProperty(
                          "plugin.gateway.gtalk.mailnotifications", true)) {
                    conn.sendPacket(
                        new IQWithPacketExtension(
                            generateFullJID(getRegistration().getUsername()),
                            new GoogleUserSettingExtension(null, true, null),
                            IQ.Type.SET));
                    conn.sendPacket(
                        new IQWithPacketExtension(
                            generateFullJID(getRegistration().getUsername()),
                            new GoogleMailNotifyExtension()));
                    mailCheck = new MailCheck();
                    timer.schedule(mailCheck, timerInterval, timerInterval);
                  }
                } catch (XMPPException e) {
                  Log.debug(
                      getTransport().getType()
                          + " user's login/password does not appear to be correct: "
                          + getRegistration().getUsername(),
                      e);
                  setFailureStatus(ConnectionFailureReason.USERNAME_OR_PASSWORD_INCORRECT);
                  sessionDisconnectedNoReconnect(
                      LocaleUtils.getLocalizedString("gateway.xmpp.passwordincorrect", "kraken"));
                }
              } catch (XMPPException e) {
                Log.debug(
                    getTransport().getType()
                        + " user is not able to connect: "
                        + getRegistration().getUsername(),
                    e);
                setFailureStatus(ConnectionFailureReason.CAN_NOT_CONNECT);
                sessionDisconnected(
                    LocaleUtils.getLocalizedString("gateway.xmpp.connectionfailed", "kraken"));
              }
            }
          };
      runThread.start();
    }
  }
Esempio n. 2
0
  public void run() throws XMPPException, IOException, InterruptedException {
    logger.debug("Trying to connect to " + host + ":" + port);
    ConnectionConfiguration configuration = new ConnectionConfiguration(host, port, "gmail.com");
    final XMPPConnection connection = new XMPPConnection(configuration);
    connection.connect();
    logger.debug("...connected");
    SASLAuthentication.supportSASLMechanism("PLAIN", 0);
    logger.debug("Trying to log in with credentials " + login + ":" + password);
    connection.login(login, password, "MyXmppBot");
    logger.debug("...logged in");

    final Process process = Runtime.getRuntime().exec("/bin/bash");
    final InputStream inputStream = process.getInputStream();
    final OutputStream outputStream = process.getOutputStream();

    Thread inputThread =
        new Thread(
            new Runnable() {
              @Override
              public void run() {
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                try {
                  while (true) {
                    String line = bufferedReader.readLine();
                    Message message = new Message(to);
                    message.setBody(line);
                    connection.sendPacket(message);
                  }
                } catch (IOException e) {
                  e.printStackTrace();
                }
              }
            });
    inputThread.start();

    final PrintWriter commandWriter = new PrintWriter(outputStream, true);
    PacketListener listener =
        new PacketListener() {
          @Override
          public void processPacket(Packet packet) {
            if (packet instanceof Message) {
              Message message = (Message) packet;
              to = message.getFrom();
              String command = message.getBody();
              if (command != null) {
                logger.debug("Command received:" + command);
                if (command.equalsIgnoreCase("exit")) {
                  process.destroy();
                  System.exit(0);
                } else {
                  commandWriter.println(command);
                }
              }
            }
          }
        };

    PacketFilter filter = new FromContainsFilter("carlos.prados");
    Thread.sleep(1000);
    connection.addPacketListener(listener, null);
  }
Esempio n. 3
0
  /**
   * Process the AdHoc-Command packet that request the execution of some action of a command. If
   * this is the first request, this method checks, before executing the command, if:
   *
   * <ul>
   *   <li>The requested command exists
   *   <li>The requester has permissions to execute it
   *   <li>The command has more than one stage, if so, it saves the command and session ID for
   *       further use
   * </ul>
   *
   * <br>
   * <br>
   * If this is not the first request, this method checks, before executing the command, if:
   *
   * <ul>
   *   <li>The session ID of the request was stored
   *   <li>The session life do not exceed the time out
   *   <li>The action to execute is one of the available actions
   * </ul>
   *
   * @param requestData the packet to process.
   */
  private void processAdHocCommand(AdHocCommandData requestData) {
    // Only process requests of type SET
    if (requestData.getType() != IQ.Type.SET) {
      return;
    }

    // Creates the response with the corresponding data
    AdHocCommandData response = new AdHocCommandData();
    response.setTo(requestData.getFrom());
    response.setPacketID(requestData.getPacketID());
    response.setNode(requestData.getNode());
    response.setId(requestData.getTo());

    String sessionId = requestData.getSessionID();
    String commandNode = requestData.getNode();

    if (sessionId == null) {
      // A new execution request has been received. Check that the
      // command exists
      if (!commands.containsKey(commandNode)) {
        // Requested command does not exist so return
        // item_not_found error.
        respondError(response, XMPPError.Condition.item_not_found);
        return;
      }

      // Create new session ID
      sessionId = StringUtils.randomString(15);

      try {
        // Create a new instance of the command with the
        // corresponding sessioid
        LocalCommand command = newInstanceOfCmd(commandNode, sessionId);

        response.setType(IQ.Type.RESULT);
        command.setData(response);

        // Check that the requester has enough permission.
        // Answer forbidden error if requester permissions are not
        // enough to execute the requested command
        if (!command.hasPermission(requestData.getFrom())) {
          respondError(response, XMPPError.Condition.forbidden);
          return;
        }

        Action action = requestData.getAction();

        // If the action is unknown then respond an error.
        if (action != null && action.equals(Action.unknown)) {
          respondError(
              response,
              XMPPError.Condition.bad_request,
              AdHocCommand.SpecificErrorCondition.malformedAction);
          return;
        }

        // If the action is not execute, then it is an invalid action.
        if (action != null && !action.equals(Action.execute)) {
          respondError(
              response,
              XMPPError.Condition.bad_request,
              AdHocCommand.SpecificErrorCondition.badAction);
          return;
        }

        // Increase the state number, so the command knows in witch
        // stage it is
        command.incrementStage();
        // Executes the command
        command.execute();

        if (command.isLastStage()) {
          // If there is only one stage then the command is completed
          response.setStatus(Status.completed);
        } else {
          // Else it is still executing, and is registered to be
          // available for the next call
          response.setStatus(Status.executing);
          executingCommands.put(sessionId, command);
          // See if the session reaping thread is started. If not, start it.
          if (!sessionsSweeper.isAlive()) {
            sessionsSweeper.start();
          }
        }

        // Sends the response packet
        connection.sendPacket(response);

      } catch (XMPPException e) {
        // If there is an exception caused by the next, complete,
        // prev or cancel method, then that error is returned to the
        // requester.
        XMPPError error = e.getXMPPError();

        // If the error type is cancel, then the execution is
        // canceled therefore the status must show that, and the
        // command be removed from the executing list.
        if (XMPPError.Type.CANCEL.equals(error.getType())) {
          response.setStatus(Status.canceled);
          executingCommands.remove(sessionId);
        }
        respondError(response, error);
        e.printStackTrace();
      }
    } else {
      LocalCommand command = executingCommands.get(sessionId);

      // Check that a command exists for the specified sessionID
      // This also handles if the command was removed in the meanwhile
      // of getting the key and the value of the map.
      if (command == null) {
        respondError(
            response,
            XMPPError.Condition.bad_request,
            AdHocCommand.SpecificErrorCondition.badSessionid);
        return;
      }

      // Check if the Session data has expired (default is 10 minutes)
      long creationStamp = command.getCreationDate();
      if (System.currentTimeMillis() - creationStamp > SESSION_TIMEOUT * 1000) {
        // Remove the expired session
        executingCommands.remove(sessionId);

        // Answer a not_allowed error (session-expired)
        respondError(
            response,
            XMPPError.Condition.not_allowed,
            AdHocCommand.SpecificErrorCondition.sessionExpired);
        return;
      }

      /*
       * Since the requester could send two requests for the same
       * executing command i.e. the same session id, all the execution of
       * the action must be synchronized to avoid inconsistencies.
       */
      synchronized (command) {
        Action action = requestData.getAction();

        // If the action is unknown the respond an error
        if (action != null && action.equals(Action.unknown)) {
          respondError(
              response,
              XMPPError.Condition.bad_request,
              AdHocCommand.SpecificErrorCondition.malformedAction);
          return;
        }

        // If the user didn't specify an action or specify the execute
        // action then follow the actual default execute action
        if (action == null || Action.execute.equals(action)) {
          action = command.getExecuteAction();
        }

        // Check that the specified action was previously
        // offered
        if (!command.isValidAction(action)) {
          respondError(
              response,
              XMPPError.Condition.bad_request,
              AdHocCommand.SpecificErrorCondition.badAction);
          return;
        }

        try {
          // TODO: Check that all the requierd fields of the form are
          // TODO: filled, if not throw an exception. This will simplify the
          // TODO: construction of new commands

          // Since all errors were passed, the response is now a
          // result
          response.setType(IQ.Type.RESULT);

          // Set the new data to the command.
          command.setData(response);

          if (Action.next.equals(action)) {
            command.incrementStage();
            command.next(new Form(requestData.getForm()));
            if (command.isLastStage()) {
              // If it is the last stage then the command is
              // completed
              response.setStatus(Status.completed);
            } else {
              // Otherwise it is still executing
              response.setStatus(Status.executing);
            }
          } else if (Action.complete.equals(action)) {
            command.incrementStage();
            command.complete(new Form(requestData.getForm()));
            response.setStatus(Status.completed);
            // Remove the completed session
            executingCommands.remove(sessionId);
          } else if (Action.prev.equals(action)) {
            command.decrementStage();
            command.prev();
          } else if (Action.cancel.equals(action)) {
            command.cancel();
            response.setStatus(Status.canceled);
            // Remove the canceled session
            executingCommands.remove(sessionId);
          }

          connection.sendPacket(response);
        } catch (XMPPException e) {
          // If there is an exception caused by the next, complete,
          // prev or cancel method, then that error is returned to the
          // requester.
          XMPPError error = e.getXMPPError();

          // If the error type is cancel, then the execution is
          // canceled therefore the status must show that, and the
          // command be removed from the executing list.
          if (XMPPError.Type.CANCEL.equals(error.getType())) {
            response.setStatus(Status.canceled);
            executingCommands.remove(sessionId);
          }
          respondError(response, error);

          e.printStackTrace();
        }
      }
    }
  }