예제 #1
0
파일: parser.c 프로젝트: Anakros/tsocks
int read_config (char *filename, struct parsedfile *config) {
	FILE *conf;
	char line[MAXLINE];
	int rc = 0;
	int lineno = 1;
	struct serverent *server;

   /* Clear out the structure */
   memset(config, 0x0, sizeof(*config));

	/* Initialization */
   currentcontext = &(config->defaultserver);

	/* If a filename wasn't provided, use the default */
	if (filename == NULL) {
		strncpy(line, CONF_FILE, sizeof(line) - 1);
		/* Insure null termination */
		line[sizeof(line) - 1] = (char) 0;
		filename = line;
	}

	/* Read the configuration file */
	if ((conf = fopen(filename, "r")) == NULL) {
		show_msg(MSGERR, "Could not open socks configuration file "
			   "(%s), assuming all networks local\n", filename);
      handle_local(config, 0, "0.0.0.0/0.0.0.0");
		rc = 1; /* Severe errors reading configuration */
	}	
	else {
      memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));

		while (NULL != fgets(line, MAXLINE, conf)) {
			/* This line _SHOULD_ end in \n so we  */
			/* just chop off the \n and hand it on */
			if (strlen(line) > 0)
				line[strlen(line) - 1] = '\0';
			handle_line(config, line, lineno);
			lineno++;
		} 
		fclose(conf);

		/* Always add the 127.0.0.1/255.0.0.0 subnet to local */
		handle_local(config, 0, "127.0.0.0/255.0.0.0");

		/* Check default server */
		check_server(&(config->defaultserver));
		server = (config->paths);
		while (server != NULL) {
			check_server(server);
			server = server->next;
		}

	}

	return(rc);
}
예제 #2
0
void assign_local ( void )
{
    signed long wlen;
    bool is_okay;
    u8 *savd_pc = pc;
    unsigned int savd_lineno = lineno;

    wlen = get_word();

	if ( wlen <= 0 )
	{
	    warn_unterm(TKERROR, "Locals Assignment", lineno);
	    return;
	}

    local_op = "!";   /*  Set to Store  */

    is_okay = handle_local( statbuf);
    if( INVERSE(is_okay)  )
    {
        tokenization_error ( TKERROR,
	    "Cannot apply -> to %s, only to a declared Local.\n", statbuf );
        pc = savd_pc;
	lineno = savd_lineno;
    }
    local_op = "@";   /*  Reset to Fetch  */
}
예제 #3
0
파일: parser.c 프로젝트: Anakros/tsocks
static int handle_line(struct parsedfile *config, char *line, int lineno) {
	char *words[10];
	static char savedline[MAXLINE];
	int   nowords = 0, i;

	/* Save the input string */
	strncpy(savedline, line, MAXLINE - 1);
	savedline[MAXLINE - 1] = (char) 0;
	/* Tokenize the input string */
	nowords = tokenize(line, 10, words);	

	/* Set the spare slots to an empty string to simplify */
	/* processing                                         */
	for (i = nowords; i < 10; i++) 
		words[i] = "";

	if (nowords > 0) {
		/* Now this can either be a "path" block starter or */
		/* ender, otherwise it has to be a pair (<name> =   */
		/* <value>)                                         */
		if (!strcmp(words[0], "path")) {
			handle_path(config, lineno, nowords, words);
		} else if (!strcmp(words[0], "}")) {
			handle_endpath(config, lineno, nowords, words);
		} else {
			/* Has to be a pair */
			if ((nowords != 3) || (strcmp(words[1], "="))) {
				show_msg(MSGERR, "Malformed configuration pair "
					   "on line %d in configuration "
					   "file, \"%s\"\n", lineno, savedline);
			} else if (!strcmp(words[0], "reaches")) {
				handle_reaches(config, lineno, words[2]);
			} else if (!strcmp(words[0], "server")) {
				handle_server(config, lineno, words[2]);
			} else if (!strcmp(words[0], "server_port")) {
				handle_port(config, lineno, words[2]);
			} else if (!strcmp(words[0], "server_type")) {
				handle_type(config, lineno, words[2]);
			} else if (!strcmp(words[0], "default_user")) {
				handle_defuser(config, lineno, words[2]);
			} else if (!strcmp(words[0], "default_pass")) {
				handle_defpass(config, lineno, words[2]);
			} else if (!strcmp(words[0], "local")) {
				handle_local(config, lineno, words[2]);
			} else {
				show_msg(MSGERR, "Invalid pair type (%s) specified "
					   "on line %d in configuration file, "
					   "\"%s\"\n", words[0], lineno, 
					   savedline);
			}
		}
	}

	return(0);
}
예제 #4
0
파일: cmdmon.c 프로젝트: pompomJuice/chrony
static void
read_from_cmd_socket(int sock_fd, int event, void *anything)
{
  CMD_Request rx_message;
  CMD_Reply tx_message;
  int status, read_length, expected_length, rx_message_length;
  int localhost, allowed, log_index;
  union sockaddr_all where_from;
  socklen_t from_length;
  IPAddr remote_ip;
  unsigned short remote_port, rx_command;
  struct timeval now, cooked_now;

  rx_message_length = sizeof(rx_message);
  from_length = sizeof(where_from);

  status = recvfrom(sock_fd, (char *)&rx_message, rx_message_length, 0,
                    &where_from.sa, &from_length);

  if (status < 0) {
    LOG(LOGS_WARN, LOGF_CmdMon, "Error [%s] reading from control socket %d",
        strerror(errno), sock_fd);
    return;
  }

  if (from_length > sizeof (where_from) ||
      from_length <= sizeof (where_from.sa.sa_family)) {
    DEBUG_LOG(LOGF_CmdMon, "Read command packet without source address");
    return;
  }

  read_length = status;

  /* Get current time cheaply */
  SCH_GetLastEventTime(&cooked_now, NULL, &now);

  UTI_SockaddrToIPAndPort(&where_from.sa, &remote_ip, &remote_port);

  /* Check if it's from localhost (127.0.0.1, ::1, or Unix domain) */
  switch (remote_ip.family) {
    case IPADDR_INET4:
      assert(sock_fd == sock_fd4);
      localhost = remote_ip.addr.in4 == INADDR_LOOPBACK;
      break;
#ifdef FEAT_IPV6
    case IPADDR_INET6:
      assert(sock_fd == sock_fd6);
      localhost = !memcmp(remote_ip.addr.in6, &in6addr_loopback,
                          sizeof (in6addr_loopback));
      break;
#endif
    case IPADDR_UNSPEC:
      /* This should be the Unix domain socket */
      if (where_from.sa.sa_family != AF_UNIX)
        return;
      assert(sock_fd == sock_fdu);
      localhost = 1;
      break;
    default:
      assert(0);
  }

  DEBUG_LOG(LOGF_CmdMon, "Received %d bytes from %s fd %d",
            status, UTI_SockaddrToString(&where_from.sa), sock_fd);

  if (!(localhost || ADF_IsAllowed(access_auth_table, &remote_ip))) {
    /* The client is not allowed access, so don't waste any more time
       on him.  Note that localhost is always allowed access
       regardless of the defined access rules - otherwise, we could
       shut ourselves out completely! */
    return;
  }

  if (read_length < offsetof(CMD_Request, data) ||
      read_length < offsetof(CMD_Reply, data) ||
      rx_message.pkt_type != PKT_TYPE_CMD_REQUEST ||
      rx_message.res1 != 0 ||
      rx_message.res2 != 0) {

    /* We don't know how to process anything like this or an error reply
       would be larger than the request */
    DEBUG_LOG(LOGF_CmdMon, "Command packet dropped");
    return;
  }

  expected_length = PKL_CommandLength(&rx_message);
  rx_command = ntohs(rx_message.command);

  tx_message.version = PROTO_VERSION_NUMBER;
  tx_message.pkt_type = PKT_TYPE_CMD_REPLY;
  tx_message.res1 = 0;
  tx_message.res2 = 0;
  tx_message.command = rx_message.command;
  tx_message.reply = htons(RPY_NULL);
  tx_message.status = htons(STT_SUCCESS);
  tx_message.pad1 = 0;
  tx_message.pad2 = 0;
  tx_message.pad3 = 0;
  tx_message.sequence = rx_message.sequence;
  tx_message.pad4 = 0;
  tx_message.pad5 = 0;

  if (rx_message.version != PROTO_VERSION_NUMBER) {
    DEBUG_LOG(LOGF_CmdMon, "Command packet has invalid version (%d != %d)",
              rx_message.version, PROTO_VERSION_NUMBER);

    if (rx_message.version >= PROTO_VERSION_MISMATCH_COMPAT_SERVER) {
      tx_message.status = htons(STT_BADPKTVERSION);
      transmit_reply(&tx_message, &where_from);
    }
    return;
  }

  if (rx_command >= N_REQUEST_TYPES ||
      expected_length < (int)offsetof(CMD_Request, data)) {
    DEBUG_LOG(LOGF_CmdMon, "Command packet has invalid command %d", rx_command);

    tx_message.status = htons(STT_INVALID);
    transmit_reply(&tx_message, &where_from);
    return;
  }

  if (read_length < expected_length) {
    DEBUG_LOG(LOGF_CmdMon, "Command packet is too short (%d < %d)", read_length,
              expected_length);

    tx_message.status = htons(STT_BADPKTLENGTH);
    transmit_reply(&tx_message, &where_from);
    return;
  }

  /* OK, we have a valid message.  Now dispatch on message type and process it. */

  log_index = CLG_LogCommandAccess(&remote_ip, &cooked_now);

  /* Don't reply to all requests from hosts other than localhost if the rate
     is excessive */
  if (!localhost && log_index >= 0 && CLG_LimitCommandResponseRate(log_index)) {
      DEBUG_LOG(LOGF_CmdMon, "Command packet discarded to limit response rate");
      return;
  }

  if (rx_command >= N_REQUEST_TYPES) {
    /* This should be already handled */
    assert(0);
  } else {
    /* Check level of authority required to issue the command.  All commands
       from the Unix domain socket (which is accessible only by the root and
       chrony user/group) are allowed. */
    if (where_from.sa.sa_family == AF_UNIX) {
      assert(sock_fd == sock_fdu);
      allowed = 1;
    } else {
      switch (permissions[rx_command]) {
        case PERMIT_AUTH:
          allowed = 0;
          break;
        case PERMIT_LOCAL:
          allowed = localhost;
          break;
        case PERMIT_OPEN:
          allowed = 1;
          break;
        default:
          assert(0);
          allowed = 0;
      }
    }

    if (allowed) {
      switch(rx_command) {
        case REQ_NULL:
          /* Do nothing */
          break;

        case REQ_DUMP:
          handle_dump(&rx_message, &tx_message);
          break;

        case REQ_ONLINE:
          handle_online(&rx_message, &tx_message);
          break;

        case REQ_OFFLINE:
          handle_offline(&rx_message, &tx_message);
          break;

        case REQ_BURST:
          handle_burst(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_MINPOLL:
          handle_modify_minpoll(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_MAXPOLL:
          handle_modify_maxpoll(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_MAXDELAY:
          handle_modify_maxdelay(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_MAXDELAYRATIO:
          handle_modify_maxdelayratio(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_MAXDELAYDEVRATIO:
          handle_modify_maxdelaydevratio(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_MAXUPDATESKEW:
          handle_modify_maxupdateskew(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_MAKESTEP:
          handle_modify_makestep(&rx_message, &tx_message);
          break;

        case REQ_LOGON:
          /* Authentication is no longer supported, log-on always fails */
          tx_message.status = htons(STT_FAILED);
          break;

        case REQ_SETTIME:
          handle_settime(&rx_message, &tx_message);
          break;
        
        case REQ_LOCAL2:
          handle_local(&rx_message, &tx_message);
          break;

        case REQ_MANUAL:
          handle_manual(&rx_message, &tx_message);
          break;

        case REQ_N_SOURCES:
          handle_n_sources(&rx_message, &tx_message);
          break;

        case REQ_SOURCE_DATA:
          handle_source_data(&rx_message, &tx_message);
          break;

        case REQ_REKEY:
          handle_rekey(&rx_message, &tx_message);
          break;

        case REQ_ALLOW:
          handle_allowdeny(&rx_message, &tx_message, 1, 0);
          break;

        case REQ_ALLOWALL:
          handle_allowdeny(&rx_message, &tx_message, 1, 1);
          break;

        case REQ_DENY:
          handle_allowdeny(&rx_message, &tx_message, 0, 0);
          break;

        case REQ_DENYALL:
          handle_allowdeny(&rx_message, &tx_message, 0, 1);
          break;

        case REQ_CMDALLOW:
          handle_cmdallowdeny(&rx_message, &tx_message, 1, 0);
          break;

        case REQ_CMDALLOWALL:
          handle_cmdallowdeny(&rx_message, &tx_message, 1, 1);
          break;

        case REQ_CMDDENY:
          handle_cmdallowdeny(&rx_message, &tx_message, 0, 0);
          break;

        case REQ_CMDDENYALL:
          handle_cmdallowdeny(&rx_message, &tx_message, 0, 1);
          break;

        case REQ_ACCHECK:
          handle_accheck(&rx_message, &tx_message);
          break;

        case REQ_CMDACCHECK:
          handle_cmdaccheck(&rx_message, &tx_message);
          break;

        case REQ_ADD_SERVER:
          handle_add_source(NTP_SERVER, &rx_message, &tx_message);
          break;

        case REQ_ADD_PEER:
          handle_add_source(NTP_PEER, &rx_message, &tx_message);
          break;

        case REQ_DEL_SOURCE:
          handle_del_source(&rx_message, &tx_message);
          break;

        case REQ_WRITERTC:
          handle_writertc(&rx_message, &tx_message);
          break;
          
        case REQ_DFREQ:
          handle_dfreq(&rx_message, &tx_message);
          break;

        case REQ_DOFFSET:
          handle_doffset(&rx_message, &tx_message);
          break;

        case REQ_TRACKING:
          handle_tracking(&rx_message, &tx_message);
          break;

        case REQ_SMOOTHING:
          handle_smoothing(&rx_message, &tx_message);
          break;

        case REQ_SMOOTHTIME:
          handle_smoothtime(&rx_message, &tx_message);
          break;

        case REQ_SOURCESTATS:
          handle_sourcestats(&rx_message, &tx_message);
          break;

        case REQ_RTCREPORT:
          handle_rtcreport(&rx_message, &tx_message);
          break;
          
        case REQ_TRIMRTC:
          handle_trimrtc(&rx_message, &tx_message);
          break;

        case REQ_CYCLELOGS:
          handle_cyclelogs(&rx_message, &tx_message);
          break;

        case REQ_CLIENT_ACCESSES_BY_INDEX2:
          handle_client_accesses_by_index(&rx_message, &tx_message);
          break;

        case REQ_MANUAL_LIST:
          handle_manual_list(&rx_message, &tx_message);
          break;

        case REQ_MANUAL_DELETE:
          handle_manual_delete(&rx_message, &tx_message);
          break;

        case REQ_MAKESTEP:
          handle_make_step(&rx_message, &tx_message);
          break;

        case REQ_ACTIVITY:
          handle_activity(&rx_message, &tx_message);
          break;

        case REQ_RESELECTDISTANCE:
          handle_reselect_distance(&rx_message, &tx_message);
          break;

        case REQ_RESELECT:
          handle_reselect(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_MINSTRATUM:
          handle_modify_minstratum(&rx_message, &tx_message);
          break;

        case REQ_MODIFY_POLLTARGET:
          handle_modify_polltarget(&rx_message, &tx_message);
          break;

        case REQ_REFRESH:
          handle_refresh(&rx_message, &tx_message);
          break;

        case REQ_SERVER_STATS:
          handle_server_stats(&rx_message, &tx_message);
          break;

        default:
          DEBUG_LOG(LOGF_CmdMon, "Unhandled command %d", rx_command);
          tx_message.status = htons(STT_FAILED);
          break;
      }
    } else {
      tx_message.status = htons(STT_UNAUTH);
    }
  }

  /* Transmit the response */
  {
    /* Include a simple way to lose one message in three to test resend */

    static int do_it=1;

    if (do_it) {
      transmit_reply(&tx_message, &where_from);
    }

#if 0
    do_it = ((do_it + 1) % 3);
#endif
  }
}
예제 #5
0
int read_config (char *filename, struct parsedfile *config) {
    FILE *conf;
    char line[MAXLINE];
    int rc = 0;
    int lineno = 1;
    struct serverent *server;

   /* Clear out the structure */
   memset(config, 0x0, sizeof(*config));

   /* Initialization */
   currentcontext = &(config->defaultserver);

   /* Tordns defaults */
   config->tordns_cache_size = 256;
   config->tordns_enabled = 1;


    /* If a filename wasn't provided, use the default */
    if (filename == NULL) {
        strncpy(line, CONF_FILE, sizeof(line) - 1);
        /* Insure null termination */
        line[sizeof(line) - 1] = (char) 0;
        filename = line;
        show_msg(MSGWARN, "Configuration file not provided by TORSOCKS_CONF_FILE "
                "environment variable, attempting to use defaults in %s.\n", filename);
    }

    /* If there is no configuration file use reasonable defaults for Tor */
    if ((conf = fopen(filename, "r")) == NULL) {
        show_msg(MSGERR, "Could not open socks configuration file "
                "(%s) errno (%d), assuming sensible defaults for Tor.\n", filename, errno);
        memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));
        check_server(&(config->defaultserver));
        handle_local(config, 0, "127.0.0.0/255.0.0.0");
        handle_local(config, 0, "10.0.0.0/255.0.0.0");
        handle_local(config, 0, "192.168.0.0/255.255.0.0");
        handle_local(config, 0, "172.16.0.0/255.240.0.0");
        handle_local(config, 0, "169.254.0.0/255.255.0.0");
        rc = 1; /* Severe errors reading configuration */
    } else {
        memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));

        while (NULL != fgets(line, MAXLINE, conf)) {
            /* This line _SHOULD_ end in \n so we  */
            /* just chop off the \n and hand it on */
            if (strlen(line) > 0)
                line[strlen(line) - 1] = '\0';
            handle_line(config, line, lineno);
            lineno++;
        }
        fclose(conf);

        /* Always add the 127.0.0.1/255.0.0.0 subnet to local */
        handle_local(config, 0, "127.0.0.0/255.0.0.0");
        /* We always consider this local, because many users' dsl
          routers act as their DNS. */
        handle_local(config, 0, "10.0.0.0/255.0.0.0");
        handle_local(config, 0, "192.168.0.0/255.255.0.0");
        handle_local(config, 0, "172.16.0.0/255.240.0.0");
        handle_local(config, 0, "169.254.0.0/255.255.0.0");
        handle_local(config, 0, "192.168.0.0/255.255.0.0");

        /* Check default server */
        check_server(&(config->defaultserver));
        server = (config->paths);
        while (server != NULL) {
            check_server(server);
            server = server->next;
        }
    }

    /* Initialize tordns deadpool_range if not supplied */
    if(config->tordns_deadpool_range == NULL) {
        handle_tordns_deadpool_range(config, 0, "127.0.69.0/255.255.255.0");
    }

    return(rc);
}