Ejemplo n.º 1
0
/******************************************************************************
 * cmd_port - see net.h
 *****************************************************************************/
int cmd_port (session_info_t *si, char *cmdStr)
{
  int cmdStrLen;  //The length of the command string.
  int csfd = si->csfd;

  //The data connection address to connect to.
  char hostname[INET_ADDRSTRLEN];  //Maximum size of an IPv4 dot notation addr.
  char service[MAX_PORT_STR];

  //The port command must have an argument.
  if (cmdStr == NULL) {
    send_mesg_501 (csfd);
    return -1;
  }

  //Ensure the client has logged in.
  if (!si->loggedin) {
    send_mesg_530 (csfd, REPLY_530_REQUEST);
    return -1;
  }

  /* The server "MUST" close the data connection port when: 
   * "The port specification is changed by a command from the user".
   * Source: RFC 959 page 19 */
  if (si->dsfd > 0) {
    if (close (si->dsfd) == -1)
      fprintf (stderr, "%s: close: %s\n", __FUNCTION__, strerror (errno));
    si->dsfd = 0;
  }

  /* Filter invalid PORT arguments by comparing the length of the argument. Too
   * many or too little number of characters in the string means that the
   * argument is invalid. */
  if ((cmdStrLen = strlen (cmdStr)) < (MIN_PORT_STR_LEN - 1)) {
    fprintf (stderr, "%s: PORT argument too short\n", __FUNCTION__);
    send_mesg_501 (csfd);
    return -1;
  } else if (cmdStrLen > (MAX_PORT_STR_LEN - 1)) {
    fprintf (stderr, "%s: PORT argument too long\n", __FUNCTION__);
    send_mesg_501 (csfd);
    return -1;
  }    

  //Convert the address h1,h2,h3,h4,p1,p2 into a hostname and service.
  if (get_port_address (csfd, &hostname, &service, cmdStr) == -1) {
    return -1;
  }

  //Create a data connection to the hostname and service provided by the client.
  if ((si->dsfd = port_connect (hostname, service)) == -1) {
    return -1;
  }
  send_mesg_200 (csfd, REPLY_200_PORT);
  
  return si->dsfd;
}
Ejemplo n.º 2
0
int main (int argc, char *argv[])
{
    int    option;                                            // holds the option from getopt_long
    const char *const short_options = "hp:v:c:mis:g:w:r:lt:j:b:n";  // possible cmd line short options
    const struct option long_options[] = {                    // possible cmd line long options
        { "help",           0, NULL, 'h' },
        { "port",           1, NULL, 'p' },
        { "verbose",        1, NULL, 'v' },
        { "command",        1, NULL, 'c' },
        { "memdump",        0, NULL, 'm' },
        { "image",          0, NULL, 'i' },
        { "sahara",         1, NULL, 's' },
        { "prefix",         1, NULL, 'g' },
        { "where",          1, NULL, 'w' },
        { "ramdumpimage",   1, NULL, 'r' },
        { "efssyncloop",    0, NULL, 'l' },
        { "rxtimeout",      1, NULL, 't' },
        { "maxwrite",       1, NULL, 'j' },
        { "addsearchpath",  1, NULL, 'b' },
        { "noreset",        0, NULL, 'n' },
        { NULL,             0, NULL,  0  }
    };

    bool efs_sync = false;
    unsigned int i;
    bool   enable_sahara_transfer = false;

#ifndef WINDOWSPC
    unsigned long cap;
    int err;
    int rc;
    struct __user_cap_header_struct capheader;
    struct __user_cap_data_struct capdata[2];


    if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
        dbg(LOG_WARN, "set keepcaps failed!");
    }
    for (cap = 0; prctl(PR_CAPBSET_READ, cap, 0, 0, 0) >= 0; cap++) {
        if ((cap == CAP_SETUID) || (cap == CAP_SETGID) || (cap == CAP_BLOCK_SUSPEND)) {
            continue;
        }
        err = prctl(PR_CAPBSET_DROP, cap, 0, 0, 0);
        if ((err < 0) && (errno != EINVAL)) {
            dbg(LOG_WARN, "Drop capability %d failed\n", cap);
        }
    }

    if (setgid(AID_SYSTEM) != 0) {
      dbg(LOG_WARN, "setgid failed");
    }
    else {
      if (setuid(AID_SYSTEM) != 0) {
        dbg(LOG_WARN, "setuid failed");
      }
      else {
          memset(&capheader, 0, sizeof(capheader));
          memset(&capdata, 0, sizeof(capdata));
          capheader.version = _LINUX_CAPABILITY_VERSION_3;
          capheader.pid = 0;
          capdata[CAP_TO_INDEX(CAP_BLOCK_SUSPEND)].permitted |= CAP_TO_MASK(CAP_BLOCK_SUSPEND);
          capdata[CAP_TO_INDEX(CAP_BLOCK_SUSPEND)].effective |= CAP_TO_MASK(CAP_BLOCK_SUSPEND);

          if ((rc = capset(&capheader, capdata)) < 0) {
              dbg(LOG_WARN, "capset failed: %s, rc = %d\n", strerror(errno), rc);
          }
      }
    }
#endif

	if (false == init_search_path_list() || false == init_sahara_mapping_list()) {
		dbg(LOG_ERROR, "Could not initialize.");
		return EXIT_FAILURE;
	}

    /* parse command-line options */
    do {
        option = getopt_long (argc, argv, short_options, long_options, NULL);

        switch (option) {
        case -1:                /* no more option arguments */
            break;

        case 'h':               /* -h or --help */
            usage();
            return EXIT_SUCCESS;

        case 'p':               /* Get the port string name */
            com_port.port_name = optarg;
            dbg(LOG_INFO, "Port name '%s'", com_port.port_name);
            break;

        case 's':               /* -s or --sahara */
            /*add the input to <id,file_name> list*/
            if (false == add_input_to_sahara_mapping_list(optarg)) {
               dbg(LOG_ERROR, "Failed to add file to file list");
               return EXIT_FAILURE;
            }
            enable_sahara_transfer = true;
            break;

		case 'b':
            if (false == add_search_path(optarg)) {
               dbg(LOG_ERROR, "Failed to add to search path list");
               return EXIT_FAILURE;
            }
            break;

        case 'i':               /* -i or --image */
            sahara_data.mode = SAHARA_MODE_IMAGE_TX_PENDING;
			enable_sahara_transfer = true;
            break;

        case 'v':               /* -v or --verbose */
            kickstart_options.verbose = atoi(optarg);
            break;

        case 'm':               /* -m or --memdump */
            sahara_data.mode = SAHARA_MODE_MEMORY_DEBUG;
            enable_sahara_transfer = true;
            break;

        case 'r':               /* -r or --ramdumpimage */
            sahara_data.ram_dump_image = atoi(optarg);
			enable_sahara_transfer = true;
            break;

        case 'g':               /* -g or --prefix */
            kickstart_options.saved_file_prefix = optarg;
            break;

        case 'w':               /* -w or --where - path for memory dump */
            kickstart_options.path_to_save_files = optarg;
            break;

        case 'c':               /* -c or --command */
            sahara_data.mode = SAHARA_MODE_COMMAND;
			sahara_data.command = atoi(optarg);
			enable_sahara_transfer = true;
            break;

        case 'l':               /* -l or --loop */
            efs_sync = true;
			sahara_data.mode = SAHARA_MODE_MEMORY_DEBUG;
			com_port.rx_timeout = -1;
			enable_sahara_transfer = true;
            break;

        case 't':
            com_port.rx_timeout = atoi(optarg);
            break;

		case 'j':               /* -c or --command */
			com_port.MAX_TO_WRITE = atoi(optarg);
            break;

        case 'n':               /* -n or --noreset */
			sahara_data.allow_sahara_reset = false;
            break;

        default:                /* unknown option. */
            dbg(LOG_ERROR, "unrecognized option: '%c'", option);
            usage ();
            return EXIT_FAILURE;
        }
    } while (option != -1);

    #ifndef WINDOWSPC
    /* After parsing the command line args try to change the verbosity level of
       the logs if the system property was set. */
       kickstart_options.verbose = read_verbosity_property (kickstart_options.verbose);
    #endif

	if (true == enable_sahara_transfer) {
        if (NULL == com_port.port_name) {
            dbg(LOG_ERROR, "Port device name not specified; use -p option.");
            return EXIT_FAILURE;
        }

        for (i = 0; i < kickstart_options.port_connect_retries; i++) {
            if (true == port_connect(com_port.port_name)) {
                break;
            }
        }
        if (kickstart_options.port_connect_retries == i) {
            dbg(LOG_ERROR, "Could not connect to %s", com_port.port_name);
            return EXIT_FAILURE;
        }

        // This is a little hacky. Ideally the timeout values should be passed in
        // as an argument, but since they don't change too often, hardcoding them
        // here for now
        if (efs_sync) {
          com_port.rx_timeout_sec = 0;
          com_port.rx_timeout_usec = 500000;
          dbg(LOG_STATUS, "Setting timeout to 500ms");
        }
        else {
          com_port.rx_timeout_sec = 2;
          com_port.rx_timeout_usec = 0;
          dbg(LOG_STATUS, "Setting timeout to 2s");
        }

        if (false == sahara_main (efs_sync))
        {
           dbg(LOG_ERROR, "Uploading  Image using Sahara protocol failed");
           use_wakelock(WAKELOCK_RELEASE);
           port_disconnect();
           return EXIT_FAILURE;
        }
    }

    port_disconnect();
    return EXIT_SUCCESS;
}