Ejemplo n.º 1
0
void process_ipv6_packet (char *buf, int len){
	struct ip6_hdr *ip6 = (struct ip6_hdr *)buf;
	struct mapping *result;
	char log_ipv6[256];
	char log_ipv4[256];

	if((result = search_mapping_table_v6(ip6->ip6_src)) != NULL){
		reset_ttl(result);
		translate_6to4(result, buf, len);
	}else{
		result = (struct mapping *)malloc(sizeof(struct mapping));
		memset(result, 0, sizeof(struct mapping));
		
		reset_ttl(result);
		result->source_ipv6_addr = ip6->ip6_src;
		if(insert_new_mapping(result) < 0){
			return;
		}

                inet_ntop(AF_INET6, &(result->source_ipv6_addr), log_ipv6, sizeof(log_ipv6));
                inet_ntop(AF_INET, &(result->mapped_ipv4_addr), log_ipv4, sizeof(log_ipv4));
                syslog_write(LOG_INFO, "session created: %s <-> %s", log_ipv6, log_ipv4);
		
		translate_6to4(result, buf, len);
	}
}
Ejemplo n.º 2
0
static void client_srv_passive(char *arg)
{
	int h1, h2, h3, h4, p1, p2;
	u_int32_t addr, ladr;
	u_int16_t port;
	int       incr;

	if (arg == NULL)		/* Basic sanity check	*/
		return;

	/*
	** Read the port. According to RFC 1123, 4.1.2.6,
	** we have to scan the string for the first digit.
	*/
	while (*arg < '0' || *arg > '9')
		arg++;
	if (sscanf(arg, "%d,%d,%d,%d,%d,%d",
			&h1, &h2, &h3, &h4, &p1, &p2) != 6) {
		syslog_error("bad PASV 277 response from server for %s",
						ctx.cli_ctrl->peer);
		client_respond(425, NULL, "Can't open data connection");
		client_data_reset(MOD_RESET);
		ctx.expect = EXP_IDLE;
		return;
	}
	addr = (u_int32_t) ((h1 << 24) + (h2 << 16) + (h3 << 8) + h4);
	port = (u_int16_t) ((p1 <<  8) +  p2);
	syslog_write(T_DBG, "got SRV-PASV %s:%d for %s:%d",
	                    socket_addr2str(addr), port,
	                    ctx.cli_ctrl->peer, ctx.cli_ctrl->port);

	/*
	** should we bind a rand(port-range) or increment?
	*/
	incr = !config_bool(NULL,"SockBindRand", 0);

	/*
	** Open a connection to the server at the given port
	*/
	ladr = socket_sck2addr(ctx.srv_ctrl->sock, LOC_END, NULL);
	if (socket_d_connect(addr, port, ladr, ctx.srv_lrng,
			ctx.srv_urng, &(ctx.srv_data),
			"Srv-Data", incr) == 0)
	{
		syslog_error("can't connect Srv-Data for %s",
						ctx.cli_ctrl->peer);
		client_respond(425, NULL, "Can't open data connection");
		client_data_reset(MOD_RESET);
		ctx.expect = EXP_IDLE;
		return;
	}

	/*
	** Finally send the original command from the client
	*/
	client_xfer_fireup();
}
Ejemplo n.º 3
0
Archivo: route.c Proyecto: edenden/lix
void *ipv6_rem_list_by_ttl(void *args){
	struct info *ptr;
	struct info *prev;

        while(1){
	        /* lock ipv6 info */
                if(pthread_mutex_lock(&mutex_ipv6_info) != 0){
			err(EXIT_FAILURE, "pthread: ttl: ipv6_info lock failed");
                }

                if(ipv6_info.next != NULL){
			prev = &ipv6_info;
			ptr = &ipv6_info;
			while(ptr->next != NULL){
				prev = ptr;
				ptr = ptr->next;

				if(ptr->state == STATE_TTL || ptr->state == STATE_NONCE){
                                        if(ptr->ttl != 0xffffffff && ptr->ttl != 0){
                                                ptr->ttl--;
                                        }
					if(ptr->ttl == 0){
						/* for syslog */
						char log_eid_addr[100];
						char log_rloc_addr[100];
						inet_ntop(AF_INET6, ptr->address, log_eid_addr, 100);
						if(ptr->af == 1){
							inet_ntop(AF_INET, ptr->nexthop, log_rloc_addr, 100);
						}else if(ptr->af == 2){
							inet_ntop(AF_INET6, ptr->nexthop, log_rloc_addr, 100);
						}else if(ptr->af == 0){
							if(ptr->state == STATE_TTL){
								strcpy(log_rloc_addr, "NativelyForward");
							}else if(ptr->state == STATE_NONCE){
								strcpy(log_rloc_addr, "Drop");
							}
						}
						syslog_write(LOG_INFO, "removed cache by ttl: %s/%d -> %s", log_eid_addr, ptr->prefix, log_rloc_addr);

                				delete_prefix(2, ptr->address, ptr->prefix);
						prev->next = ptr->next;
						free(ptr);
						ptr = prev;
					}
				}
			}
		}

                /* unlock ipv6 info */
                if(pthread_mutex_unlock(&mutex_ipv6_info) != 0){
			err(EXIT_FAILURE, "pthread: ttl: ipv4_info unlock failed");
                }

		sleep(1);
        }
}
Ejemplo n.º 4
0
void log_session_destroy(struct sockmap *external, struct sockmap *balanced){
        char external_addr[BUF_WORD_SIZE];
        char balanced_addr[BUF_WORD_SIZE];

	inet_ntop(AF_INET6, &(external->server.sin6_addr), external_addr, sizeof(external_addr));
	inet_ntop(AF_INET6, &(balanced->server.sin6_addr), balanced_addr, sizeof(balanced_addr));

	syslog_write(LOG_INFO, "session destroyed %s <-> %s\n", external_addr, balanced_addr);
	return;
}
Ejemplo n.º 5
0
int log_error(const char *fmt, ...)
{
    va_list vl;
    char time_buffer[32]    = {0};
    char line_buffer[LINE_BUFFER_SIZE]  = {0};
    char format_buffer[FORMAT_BUFFER_SIZE] = {0};
    int  line_size          = 0;
    int  level              = LOG_LEVEL_ERROR;

    if(level < log_level)
        return 1;
    
    if(level > LOG_LEVEL_ERROR){
        level = LOG_LEVEL_ERROR;
    }

    if(LOG_DESTINATION_SYSLOG != log_dst){
        format_cur_time(time_buffer, sizeof(time_buffer), NULL);
        snprintf(format_buffer, sizeof(format_buffer) - 1, "[%s] [%s] %s", 
                log_level_map[level], time_buffer, fmt);

        va_start(vl, fmt);
        line_size = vsnprintf(line_buffer, sizeof(line_buffer) - 2, format_buffer, vl);
        if(line_size <= 0){
            return 0;
        }
        va_end(vl);

        if ((unsigned int)line_size > sizeof(line_buffer) - 2) {
            line_size = sizeof(line_buffer) - 2;
        }
        line_buffer[line_size] = '\n';
        line_size++;
        write(log_fd, line_buffer, line_size);
    }
    else{
        va_start(vl, fmt);
        line_size = vsnprintf(line_buffer, sizeof(line_buffer) - 2, fmt, vl);
        if(line_size <= 0){
            return 0;
        }
        va_end(vl);

        if ((unsigned int)line_size > sizeof(line_buffer) - 2) {
            line_size = sizeof(line_buffer) - 2;
        }
        line_buffer[line_size] = '\n';
        line_size++;

        if(!syslog_write(syslog_level_map[level], line_buffer, line_size)){
            return 0;
        }
    }
    return 1;
}
Ejemplo n.º 6
0
Archivo: route.c Proyecto: edenden/lix
void ipv6_add_list(struct info *obj){
	struct info *ptr;
	struct info *prev;
	struct info *temp;

	/* for syslog */
	char log_eid_addr[100];
	char log_rloc_addr[100];
	inet_ntop(AF_INET6, obj->address, log_eid_addr, 100);
	if(obj->af == 1){
		inet_ntop(AF_INET, obj->nexthop, log_rloc_addr, 100);
	}else if(obj->af == 2){
		inet_ntop(AF_INET6, obj->nexthop, log_rloc_addr, 100);
	}else if(obj->af == 0){
		if(obj->state == STATE_TTL){
			strcpy(log_rloc_addr, "NativelyForward");
		}else if(obj->state == STATE_NONCE){
			strcpy(log_rloc_addr, "Drop");
		}
	}
	syslog_write(LOG_INFO, "added cache: %s/%d -> %s", log_eid_addr, obj->prefix, log_rloc_addr);


        /* lock ipv6 info */
        if(pthread_mutex_lock(&mutex_ipv6_info) != 0){
		err(EXIT_FAILURE, "pthread: ttl: ipv6_info lock failed");
        }

	ptr = &ipv6_info;
	prev = &ipv6_info;
	while(ptr->next != NULL){
		ptr = ptr->next;
		if(!memcmp(ptr->address, obj->address, 16) && ptr->prefix == obj->prefix){
			prev->next = ptr->next;
			temp = ptr;
			ptr = prev;
			free(temp);
		}
		prev = ptr;
	}

        obj->next = ipv6_info.next;
        ipv6_info.next = obj;

        /* unlock ipv6 info */
        if(pthread_mutex_unlock(&mutex_ipv6_info) != 0){
		err(EXIT_FAILURE, "pthread: ttl: ipv6_info unlock failed");
        }
}
Ejemplo n.º 7
0
Archivo: route.c Proyecto: edenden/lix
int ipv6_rem_list_by_nonce(char *nonce){
        struct info *ptr;
        struct info *prev;

        while(1){
                /* lock ipv6 info */
                if(pthread_mutex_lock(&mutex_ipv6_info) != 0){
			err(EXIT_FAILURE, "pthread: ttl: ipv6_info lock failed");
                }

                if(ipv6_info.next != NULL){
                        prev = &ipv6_info;
                        ptr = &ipv6_info;
                        while(ptr->next != NULL){
                                prev = ptr;
                                ptr = ptr->next;

                                if(ptr->state == STATE_NONCE){
                                        if(!memcmp(ptr->nonce, nonce, 8)){
						/* for syslog */
						char log_eid_addr[100];
						inet_ntop(AF_INET6, ptr->address, log_eid_addr, 100);
						syslog_write(LOG_INFO, "removed temporary cache: %s/%d", log_eid_addr, ptr->prefix);

                                                delete_prefix(2, ptr->address, ptr->prefix);

                                                prev->next = ptr->next;
                                                free(ptr);
                                                ptr = prev;

				                /* unlock ipv6 info */
				                if(pthread_mutex_unlock(&mutex_ipv6_info) != 0){
							err(EXIT_FAILURE, "pthread: ttl: ipv6_info unlock failed");
				                }
						return 1;
                                        }
                                }
                        }
                }

                /* unlock ipv6 info */
                if(pthread_mutex_unlock(&mutex_ipv6_info) != 0){
			err(EXIT_FAILURE, "pthread: ttl: ipv6_info unlock failed");
                }
		return 0;
        }  
}
Ejemplo n.º 8
0
/* call-seq:
 *   log(priority, format_string, *format_args)
 *
 * Log a message with the specified priority. Example:
 *
 *   Syslog.log(Syslog::LOG_CRIT, "Out of disk space")
 *   Syslog.log(Syslog::LOG_CRIT, "User %s logged in", ENV['USER'])
 *
 * The priority levels, in descending order, are:
 *
 * LOG_EMERG::   System is unusable
 * LOG_ALERT::   Action needs to be taken immediately
 * LOG_CRIT::    A critical condition has occurred
 * LOG_ERR::     An error occurred
 * LOG_WARNING:: Warning of a possible problem
 * LOG_NOTICE::  A normal but significant condition occurred
 * LOG_INFO::    Informational message
 * LOG_DEBUG::   Debugging information
 *
 * Each priority level also has a shortcut method that logs with it's named priority.
 * As an example, the two following statements would produce the same result:
 *
 *   Syslog.log(Syslog::LOG_ALERT, "Out of memory")
 *   Syslog.alert("Out of memory")
 *
 * Format strings are as for printf/sprintf, except that in addition %m is
 * replaced with the error message string that would be returned by
 * strerror(errno).
 *
 */
static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self)
{
    VALUE pri;

    rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);

    argc--;
    pri = *argv++;

    if (!FIXNUM_P(pri)) {
	rb_raise(rb_eTypeError, "type mismatch: %"PRIsVALUE" given", rb_obj_class(pri));
    }

    syslog_write(FIX2INT(pri), argc, argv);

    return self;
}
Ejemplo n.º 9
0
static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self)
{
    VALUE pri;

    if (argc < 2) {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2+)", argc);
    }

    argc--;
    pri = *argv++;

    if (!FIXNUM_P(pri)) {
      rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(pri)));
    }

    syslog_write(FIX2INT(pri), argc, argv);

    return self;
}
Ejemplo n.º 10
0
void log_cb_send(int hashed_index, struct ws_cblist *block){
        char server_addr[BUF_WORD_SIZE];
	struct ws_cblist *ptr_block = block;
	int cb_size;
	uint32_t channel;
        struct server_list *ptr_server = serv_list;
        int i;

        for(i = 0; i < hashed_index + 1; i++){
                ptr_server = ptr_server->next;
        }

        inet_ntop(AF_INET6, &(ptr_server->server.sin6_addr), server_addr, sizeof(server_addr));

	while(ptr_block != NULL){
		ws_cb_getsize(ptr_block->buf, &channel);
		syslog_write(LOG_INFO, "control-block(channel:%d) is queued to forward to %s\n", channel, server_addr);
		ptr_block = ptr_block->next;
	}
}
Ejemplo n.º 11
0
static int client_setup_file(CONTEXT *ctx, char *who)
{
	char      *p;
	u_int16_t  l, u;

	/*
	** little bit sanity check
	*/
	if( !(ctx && who && *who)) {
		return -1;
	}

	/*
	** Inform the auditor that we are using the config file
	*/
	syslog_write(U_INF, "reading data for '%s' from cfg-file", who);

	/*
	** Evaluate DestinationAddress, except we have magic_addr
	*/
	if (INADDR_ANY != ctx->magic_addr) {
		ctx->srv_addr = ctx->magic_addr;
	} else {
		ctx->srv_addr = config_addr(who, "DestinationAddress",
		                                 INADDR_ANY);
#if defined(COMPILE_DEBUG)
		debug(2, "file DestAddr for %s: '%s'",
		      ctx->cli_ctrl->peer, socket_addr2str(ctx->srv_addr));
#endif
	}

	/*
	** Evaluate DestinationPort, except we have magic_port
	*/
	if (INPORT_ANY != ctx->magic_port) {
		ctx->srv_port = ctx->magic_port;
	} else {
		ctx->srv_port = config_port(who, "DestinationPort",
		                                 IPPORT_FTP);
#if defined(COMPILE_DEBUG)
		debug(2, "file DestPort for %s: %d",
		      ctx->cli_ctrl->peer, (int) ctx->srv_port);
#endif
	}

	/*
	** Evaluate the destination transfer mode
	*/
	p = config_str(who, "DestinationTransferMode", "client");
	if(0 == strcasecmp(p, "active")) {
		ctx->srv_mode = MOD_ACT_FTP;
	} else
	if(0 == strcasecmp(p, "passive")) {
		ctx->srv_mode = MOD_PAS_FTP;
	} else
	if(0 == strcasecmp(p, "client")) {
		ctx->srv_mode = MOD_CLI_FTP;
	} else {
		syslog_error("can't eval DestMode for %s",
		             ctx->cli_ctrl->peer);
		return -1;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file DestMode for %s: %s", ctx->cli_ctrl->peer, p);
#endif

	/*
	** Evaluate min/max destination port range
	*/
	l = config_port(who, "DestinationMinPort", INPORT_ANY);
	u = config_port(who, "DestinationMaxPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->srv_lrng = l;
		ctx->srv_urng = u;
	} else {
		ctx->srv_lrng = INPORT_ANY;
		ctx->srv_urng = INPORT_ANY;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file DestRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->srv_lrng, ctx->srv_urng);
#endif

	/*
	** Evaluate min/max active port range
	*/
	l = config_port(who, "ActiveMinDataPort", INPORT_ANY);
	u = config_port(who, "ActiveMaxDataPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->act_lrng = l;
		ctx->act_urng = u;
	} else {
		/* do not try to bind a port < 1024 if running as UID != 0 */
		if(0 == getuid()) {
			ctx->act_lrng = (IPPORT_FTP - 1);
			ctx->act_urng = (IPPORT_FTP - 1);
		} else {
			ctx->act_lrng = INPORT_ANY;
			ctx->act_urng = INPORT_ANY;
		}
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file ActiveRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->act_lrng, ctx->act_urng);
#endif

	/*
	** Evaluate min/max passive port range
	*/
	l = config_port(who, "PassiveMinDataPort", INPORT_ANY);
	u = config_port(who, "PassiveMaxDataPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->pas_lrng = l;
		ctx->pas_urng = u;
	} else {
		ctx->pas_lrng = INPORT_ANY;
		ctx->pas_urng = INPORT_ANY;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file PassiveRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->pas_lrng, ctx->pas_urng);
#endif

	/*
	** Setup other configuration options
	*/
	ctx->same_adr = config_bool(who, "SameAddress", 1);
	ctx->timeout  = config_int (who, "TimeOut",   900);
#if defined(COMPILE_DEBUG)
	debug(2, "file SameAddress for %s: %s", ctx->cli_ctrl->peer,
	                                        ctx->same_adr ? "yes" : "no");
	debug(2, "file TimeOut for %s: %d", ctx->cli_ctrl->peer, ctx->timeout);
#endif

	/*
	** Adjust the allow/deny flags for the commands
	*/
	p = config_str(who, "ValidCommands", NULL);
	cmds_set_allow(p);

	return 0;
}
Ejemplo n.º 12
0
void log_handshake_verify(struct sockmap *balanced, char *key){
        char balanced_addr[BUF_WORD_SIZE];
        inet_ntop(AF_INET6, &balanced->server.sin6_addr, balanced_addr, sizeof(balanced_addr));

	syslog_write(LOG_INFO, "websocket handshake from %s verified. key: %s\n", balanced_addr, key);
}
Ejemplo n.º 13
0
static ssize_t syslog_console_write(FAR struct file *filep,
                                    FAR const char *buffer, size_t buflen)
{
  return syslog_write(buffer, buflen);
}
Ejemplo n.º 14
0
int syslog_putc(int ch)
{
  ssize_t nbytes;
  uint8_t uch;
  int errcode;
  int ret;

  /* Ignore any output:
   *
   * (1) Before the SYSLOG device has been initialized.  This could happen
   *     from debug output that occurs early in the boot sequence before
   *     syslog_initialize() is called (SYSLOG_UNINITIALIZED).
   * (2) While the device is being initialized.  The case could happen if
   *     debug output is generated while syslog_initialize() executes
   *     (SYSLOG_INITIALIZING).
   * (3) While we are generating SYSLOG output.  The case could happen if
   *     debug output is generated while syslog_putc() executes
   *     (This case is actually handled inside of syslog_semtake()).
   * (4) Any debug output generated from interrupt handlers.  A disadvantage
   *     of using the generic character device for the SYSLOG is that it
   *     cannot handle debug output generated from interrupt level handlers.
   * (5) Any debug output generated from the IDLE loop.  The character
   *     driver interface is blocking and the IDLE thread is not permitted
   *     to block.
   * (6) If an irrecoverable failure occurred during initialization.  In
   *     this case, we won't ever bother to try again (ever).
   *
   * NOTE: That the third case is different.  It applies only to the thread
   * that currently holds the sl_sem sempaphore.  Other threads should wait.
   * that is why that case is handled in syslog_semtake().
   */

  /* Cases (4) and (5) */

  if (up_interrupt_context() || getpid() == 0)
    {
      errcode = ENOSYS;
      goto errout_with_errcode;
    }

  /* We can save checks in the usual case:  That after the SYSLOG device
   * has been successfully opened.
   */

  if (g_sysdev.sl_state != SYSLOG_OPENED)
    {
      /* Case (1) and (2) */

      if (g_sysdev.sl_state == SYSLOG_UNINITIALIZED ||
          g_sysdev.sl_state == SYSLOG_INITIALIZING)
       {
         errcode = EAGAIN; /* Can't access the SYSLOG now... maybe next time? */
         goto errout_with_errcode;
       }

      /* Case (6) */

      if (g_sysdev.sl_state == SYSLOG_FAILURE)
        {
          errcode = ENXIO;  /* There is no SYSLOG device */
          goto errout_with_errcode;
        }

      /* syslog_initialize() is called as soon as enough of the operating
       * system is in place to support the open operation... but it is
       * possible that the SYSLOG device is not yet registered at that time.
       * In this case, we know that the system is sufficiently initialized
       * to support an attempt to re-open the SYSLOG device.
       *
       * NOTE that the scheduler is locked.  That is because we do not have
       * fully initialized semaphore capability until the SYSLOG device is
       * successfully initialized
       */

      sched_lock();
      if (g_sysdev.sl_state == SYSLOG_REOPEN)
        {
          /* Try again to initialize the device.  We may do this repeatedly
           * because the log device might be something that was not ready
           * the first time that syslog_initializee() was called (such as a
           * USB serial device that has not yet been connected or a file in
           * an NFS mounted file system that has not yet been mounted).
           */

          ret = syslog_initialize();
          if (ret < 0)
            {
              sched_unlock();
              errcode = -ret;
              goto errout_with_errcode;
            }
        }

      sched_unlock();
      DEBUGASSERT(g_sysdev.sl_state == SYSLOG_OPENED);
    }

  /* Ignore carriage returns */

  if (ch == '\r')
    {
      return ch;
    }

  /* The syslog device is ready for writing and we have something of
   * value to write.
   */

  ret = syslog_takesem();
  if (ret < 0)
    {
      /* We probably already hold the semaphore and were probably
       * re-entered by the logic kicked off by syslog_write().
       * We might also have been interrupted by a signal.  Either
       * way, we are outta here.
       */

      errcode = -ret;
      goto errout_with_errcode;
    }

  /* Pre-pend a newline with a carriage return. */

  if (ch == '\n')
    {
      /* Write the CR-LF sequence */

      nbytes = syslog_write(g_syscrlf, 2);

      /* Synchronize the file when each CR-LF is encountered (i.e.,
       * implements line buffering always).
       */

#ifndef CONFIG_DISABLE_MOUNTPOINT
      if (nbytes > 0)
        {
          syslog_flush();
        }
#endif
    }
  else
    {
      /* Write the non-newline character (and don't flush) */

      uch = (uint8_t)ch;
      nbytes = syslog_write(&uch, 1);
    }

  syslog_givesem();

  /* Check if the write was successful.  If not, nbytes will be
   * a negated errno value.
   */

  if (nbytes < 0)
    {
      errcode = -ret;
      goto errout_with_errcode;
    }

  return ch;

errout_with_errcode:
  set_errno(errcode);
  return EOF;
}
Ejemplo n.º 15
0
static int client_setup_file(CONTEXT *ctx, char *who)
{
	char      *p;

	u_int16_t  l, u;

	/*
	** little bit sanity check
	*/
	if( !(ctx && who && *who)) {
		return -1;
	}

	/*
	** Inform the auditor that we are using the config file
	*/
	syslog_write(U_INF, "[ %s ] reading data for '%s' from cfg-file", ctx->cli_ctrl->peer, who);

	/*
	** Evaluate DestinationAddress, except we have magic_addr
	*/
	if (INADDR_ANY != ctx->magic_addr) {
		ctx->srv_addr = ctx->magic_addr;
	} else {
		ctx->srv_addr = config_addr(who, "DestinationAddress",
		                                 INADDR_ANY);
#if defined(COMPILE_DEBUG)
		debug(2, "[ %s ] file DestAddr for %s: '%s'", ctx->cli_ctrl->peer,
		      ctx->cli_ctrl->peer, socket_addr2str(ctx->srv_addr));
#endif
	}

	/*
	** Evaluate DestinationPort, except we have magic_port
	*/
	if (INPORT_ANY != ctx->magic_port) {
		ctx->srv_port = ctx->magic_port;
	} else {
		ctx->srv_port = config_port(who, "DestinationPort",
		                                 IPPORT_FTP);
#if defined(COMPILE_DEBUG)
		debug(2, "[ %s ] file DestPort for %s: %d", ctx->cli_ctrl->peer,
		      ctx->cli_ctrl->peer, (int) ctx->srv_port);
#endif
	}

	/*
	** Evaluate the destination transfer mode
	*/
	p = config_str(who, "DestinationTransferMode", "client");
	if(0 == strcasecmp(p, "active")) {
		ctx->srv_mode = MOD_ACT_FTP;
	} else
	if(0 == strcasecmp(p, "passive")) {
		ctx->srv_mode = MOD_PAS_FTP;
	} else
	if(0 == strcasecmp(p, "client")) {
		ctx->srv_mode = MOD_CLI_FTP;
	} else {
		syslog_error("can't eval DestMode for %s",
		             ctx->cli_ctrl->peer);
		return -1;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file DestMode for %s: %s", ctx->cli_ctrl->peer, p);
#endif

	/*
	** Evaluate min/max destination port range
	*/
	l = config_port(who, "DestinationMinPort", INPORT_ANY);
	u = config_port(who, "DestinationMaxPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->srv_lrng = l;
		ctx->srv_urng = u;
	} else {
		ctx->srv_lrng = INPORT_ANY;
		ctx->srv_urng = INPORT_ANY;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file DestRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->srv_lrng, ctx->srv_urng);
#endif

	/*
	** Evaluate min/max active port range
	*/
	l = config_port(who, "ActiveMinDataPort", INPORT_ANY);
	u = config_port(who, "ActiveMaxDataPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->act_lrng = l;
		ctx->act_urng = u;
	} else {
		/* do not try to bind a port < 1024 if running as UID != 0 */
		if(0 == getuid()) {
			ctx->act_lrng = (IPPORT_FTP - 1);
			ctx->act_urng = (IPPORT_FTP - 1);
		} else {
			ctx->act_lrng = INPORT_ANY;
			ctx->act_urng = INPORT_ANY;
		}
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file ActiveRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->act_lrng, ctx->act_urng);
#endif

	/*
	** Evaluate min/max passive port range
	*/
	l = config_port(who, "PassiveMinDataPort", INPORT_ANY);
	u = config_port(who, "PassiveMaxDataPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->pas_lrng = l;
		ctx->pas_urng = u;
	} else {
		ctx->pas_lrng = INPORT_ANY;
		ctx->pas_urng = INPORT_ANY;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file PassiveRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->pas_lrng, ctx->pas_urng);
#endif

	/*
	** Setup other configuration options
	*/
	ctx->same_adr = config_bool(who, "SameAddress", 1);
	ctx->timeout  = config_int (who, "TimeOut",   900);
#if defined(COMPILE_DEBUG)
	debug(2, "file SameAddress for %s: %s", ctx->cli_ctrl->peer,
	                                        ctx->same_adr ? "yes" : "no");
	debug(2, "file TimeOut for %s: %d", ctx->cli_ctrl->peer, ctx->timeout);
#endif

/*** Adjust the allow/deny flags for the commands ** Fred patch */
	
	char dest[17];
	char ipdest[17];
	char ipsrc[17];
	strcpy (ipsrc,ctx->cli_ctrl->peer);
	strcpy (ipdest, socket_addr2str(ctx->srv_addr));
	syslog_write(U_INF, "\n");	
	syslog_write(U_INF, "[ %s ] Fred Patch rules dest: %s src: %s", ipsrc, ipdest, ipsrc);	

	char groupname[]="group";
	char commandename[]="ValidCommands";
	char *group;
	FILE *fp;
	group = "group1";
	int ix;
	int ix2;
	u_int32_t dnsaddr;
	for(ix=1; group != NULL; ix++) {
		sprintf (&groupname[5],"%d",ix);
		group = config_str(who, groupname, NULL);
		}
	
	syslog_write(U_INF, "[ %s ] Number of groups: %d", ipsrc, ix-2);
		
	for (ix2=1; ix2 <= ix-2; ix2++) {
		sprintf (&groupname[5],"%d",ix2);
		group = config_str(who, groupname, NULL);
		syslog_write(U_INF, "[ %s ] Reading: %s",ipsrc, group );
		if ((fp = fopen(group, "r")) == NULL)
			{
			syslog_write(U_INF, "File not found");
			return 0;
			}
		else
			{	
			fseek(fp, 0, SEEK_SET);
			while (fgets(dest, 17 , fp) != NULL)
				{	
				// Pour une IP
				// Correction Bug Ligne sans \n 
					dest[16] = '\n';
					char *c = strchr (dest, '\n');
					*c = 0;
					/*  Dns resolution */
					if (ipdest != dest) {
						dnsaddr = socket_str2addr(dest, INADDR_ANY);
						if (dnsaddr != 0) 
							strcpy (dest, socket_addr2str(dnsaddr));
						}
					if (strcmp(dest,ipdest) == 0 || strcmp(dest,ipsrc) == 0)
					{
						sprintf (&commandename[13],"%d",ix);
						p = config_str(who,commandename, NULL);
						cmds_set_allow(p);
						syslog_write(U_INF, "[ %s ] Apply rules for: %s dst: %s",ipsrc, ipsrc, ipdest);
						syslog_write(U_INF, "[ %s ] Server match %s ",ipsrc, group );
						syslog_write(U_INF, "\n");
						fclose(fp);
						return 0;
					}
			// Network
				if (strchr(dest, 'x') != NULL)
					{ 
						char *c = strchr(dest, 'x');
						*c = 0;
						int longueur;
						longueur = strlen(dest);
						if (strncmp(dest,ipdest,longueur) == 0 || strncmp(dest,ipsrc,longueur) == 0)
						{
							sprintf (&commandename[13],"%d",ix);
							p = config_str(who,commandename, NULL);
							cmds_set_allow(p);
							syslog_write(U_INF, "[ %s ] Apply rules for Network: %s src: %s",ipsrc, ipdest, ipsrc);
							syslog_write(U_INF, "[ %s ] Server match %s ",ipsrc, group );
							syslog_write(U_INF, "\n");
							fclose(fp);
							return 0;
						}
					}
				}

			fclose(fp);
			}	
		}
	syslog_write(U_INF, "[ %s ] Oh, Oh, no rule found -> defaultrules", ipsrc) ;
	p = config_str(who, "defaultrules", NULL);
	cmds_set_allow(p); 
	return 0;
}
Ejemplo n.º 16
0
static void client_xfer_fireup(void)
{
	u_int32_t ladr = INADDR_ANY;
	int       incr;

	/*
	** should we bind a rand(port-range) or increment?
	*/
	incr = !config_bool(NULL,"SockBindRand", 0);

	/*
	** If appropriate, connect to the client's data port
	*/
	if (ctx.cli_mode == MOD_ACT_FTP) {
		/*
		** TransProxy mode: check if we can use our real
		** ip instead of the server's one as our local ip,
		** we pre-bind the socket/ports to before connect.
		*/
		if(config_bool(NULL, "AllowTransProxy", 0)) {
			ladr = config_addr(NULL, "Listen",
					(u_int32_t)INADDR_ANY);
		}
		if(INADDR_ANY == ladr) {
			ladr = socket_sck2addr(ctx.cli_ctrl->sock,
						LOC_END, NULL);
		}
		if (socket_d_connect(ctx.cli_addr, ctx.cli_port,
				ladr, ctx.act_lrng, ctx.act_urng,
				&(ctx.cli_data), "Cli-Data", incr) == 0)
		{
			syslog_error("can't connect Cli-Data for %s",
						ctx.cli_ctrl->peer);
			client_respond(425, NULL,
					"Can't open data connection");
			client_data_reset(MOD_RESET);
			ctx.expect = EXP_IDLE;
			return;
		}
	}

	/*
	** Send the original command from the client
	*/
	if (ctx.xfer_arg[0] != '\0') {
		socket_printf(ctx.srv_ctrl, "%s %s\r\n",
				ctx.xfer_cmd, ctx.xfer_arg);
		syslog_write(T_INF, "'%s %s' sent for %s",
			ctx.xfer_cmd, ctx.xfer_arg, ctx.cli_ctrl->peer);
	} else {
		socket_printf(ctx.srv_ctrl, "%s\r\n", ctx.xfer_cmd);
		syslog_write(T_INF, "'%s' sent for %s",
			ctx.xfer_cmd, ctx.cli_ctrl->peer);
	}

	/*
	** Prepare the handling and statistics buffers
	*/
	memset(ctx.xfer_rep, 0, sizeof(ctx.xfer_rep));
	ctx.xfer_beg = time(NULL);

	ctx.expect = EXP_XFER;		/* Expect 226 complete	*/
}
Ejemplo n.º 17
0
int send_map_register(struct record *request_dest, struct record *request_source){
	char buffer[MTU];

        struct sockaddr_storage dest;
        memset(&dest, 0, sizeof(struct sockaddr_storage));
        int sockaddr_size;
	int i;
	int send_size;

        if(control_version == 6){
                struct sockaddr_in6 *dest6 = (struct sockaddr_in6 *)&dest;

	        struct config *mapserver_config = (struct config *)config_root.under_layers[MAPSERVER_LAYER];
       		struct mapserver_layer_data *mapserver_data = (struct mapserver_layer_data *)(mapserver_config->data);
        	struct address_list *addr_list = &(mapserver_data->v6address);
        	addr_list = addr_list->next;

                dest6->sin6_family = AF_INET6;
                dest6->sin6_port = htons(4342);
                inet_pton(AF_INET6, addr_list->address, &(dest6->sin6_addr));
                sockaddr_size = sizeof(struct sockaddr_in6);
        }else if(control_version == 4){
                struct sockaddr_in *dest4 = (struct sockaddr_in *)&dest;

                struct config *mapserver_config = (struct config *)config_root.under_layers[MAPSERVER_LAYER];
                struct mapserver_layer_data *mapserver_data = (struct mapserver_layer_data *)(mapserver_config->data);
                struct address_list *addr_list = &(mapserver_data->v4address);
                addr_list = addr_list->next;

                dest4->sin_family = AF_INET;
                dest4->sin_port = htons(4342);
                inet_pton(AF_INET, addr_list->address, &(dest4->sin_addr));
                sockaddr_size = sizeof(struct sockaddr_in);
        }

	/* initiate register thread */
        if(pthread_mutex_lock(&mutex_reg) != 0){
		err(EXIT_FAILURE, "pthread: register: lock failed");
        }

	syslog_write(LOG_INFO, "Initial fast map-regist signaling");

	for(i = 0; i < 5; i++){
		memset(buffer, 0, sizeof(buffer));
		int ret = create_map_register(buffer, request_dest, request_source);
		if(ret < 0){
			return -1;
		}

		send_size = sendto(udp_sock, buffer, ret, 0, (struct sockaddr *)&dest, sockaddr_size);
                if(send_size == -1){
			err(EXIT_FAILURE, "send");
                }
                sleep(1);
	}

	/* signaling to main thread */
	if(pthread_cond_signal(&cond_reg) != 0){
		err(EXIT_FAILURE, "pthread: register: cond_signal failed");
	}

        /* finalize initiation */
        if(pthread_mutex_unlock(&mutex_reg) != 0){
		err(EXIT_FAILURE, "pthread: register: unlock failed");
        }

	syslog_write(LOG_INFO, "Started normal map-regist per %d sec", MAPREGIST_INTERVAL);

	while(1){
		memset(buffer, 0, sizeof(buffer));
		int ret = create_map_register(buffer, request_dest, request_source);
		if(ret < 0){
			return -1;
		}

		send_size = sendto(udp_sock, buffer, ret, 0, (struct sockaddr *)&dest, sockaddr_size);
		if(send_size == -1){
			err(EXIT_FAILURE, "send");
		}
		sleep(MAPREGIST_INTERVAL);
	}

	return 0;
}
Ejemplo n.º 18
0
static void client_srv_ctrl_read(char *str)
{
	int code, c1, c2, c3;
	char *arg;

	if (str == NULL)		/* Basic sanity check	*/
		return;

	syslog_write(T_DBG, "from Server-PI (%d): '%.512s'",
	             ctx.srv_ctrl->sock, str);
#if defined(COMPILE_DEBUG)
	debug(1, "from Server-PI (%d): '%.512s'",
					ctx.srv_ctrl->sock, str);
#endif

	/*
	** Intermediate responses can usually be forwarded
	*/
	if (*str < '2' || *str > '5' || str[3] != ' ') {
		/*
		** If this is the destination host's
		** welcome message let's discard it.
		*/
		if (ctx.expect == EXP_CONN)
			return;
		if (ctx.expect == EXP_USER && UAUTH_NONE != ctx.auth_mode)
			return;

#if defined(COMPILE_DEBUG)
		debug(2, "'%.4s'... forwarded to %s %d=%s", str,
			ctx.cli_ctrl->ctyp, ctx.cli_ctrl->sock,
			ctx.cli_ctrl->peer);
#endif
		socket_printf(ctx.cli_ctrl, "%s\r\n", str);
		return;
	}

	/*
	** Consider only valid final response codes
	*/
	if ((code = atoi(str)) < 200 || code > 599) {
		syslog_error("bad response %d from server for %s",
					code, ctx.srv_ctrl->peer);
		return;
	}
	c1 =  code / 100;
	c2 = (code % 100) / 10;
	c3 =  code % 10;
	for (arg = str + 3; *arg == ' '; arg++)
		;

	/*
	** We have a response code, go see what we expected
	*/
	switch (ctx.expect) {
		case EXP_CONN:
			/*
			** Waiting for a 220 Welcome
			*/
			if (c1 == 2) {
				socket_printf(ctx.srv_ctrl,
				              "USER %s\r\n",
				              ctx.username);
				ctx.expect = EXP_USER;
			} else {
				if(UAUTH_NONE != ctx.auth_mode) {
					client_respond(530, NULL,
					               "Login incorrect");
				} else {
					socket_printf(ctx.cli_ctrl,
					              "%s\r\n", str);
				}
				ctx.expect = EXP_IDLE;
				ctx.cli_ctrl->kill = 1;
			}
			break;

		case EXP_USER:
			/*
			** Only the following codes are useful:
			**	230=logged in,
			**	331=need password,
			**	332=need password+account
			*/
			if(UAUTH_NONE != ctx.auth_mode) {
				/*
				** logged in, NO password needed
				*/
				if(c1 == 2 && c2 == 3) {
					client_respond(230, NULL,
					               "User logged in, proceed.");
					ctx.expect = EXP_IDLE;
					break;
				} else
				/*
				** OK, password (+account) needed
				*/
				if(c1 == 3 && c2 == 3) {
					if(ctx.userpass) {
						socket_printf(ctx.srv_ctrl,
						              "PASS %s\r\n",
						              ctx.userpass);
						misc_free(FL, ctx.userpass);
						ctx.userpass = NULL;
					} else {
						socket_printf(ctx.srv_ctrl,
						              "PASS \r\n");
					}
					ctx.expect = EXP_PTHR;
					break;
				}
			}
			/*
			** pass server response through to client
			*/
			socket_printf(ctx.cli_ctrl, "%s\r\n", str);
			if (c1 != 2 && c1 != 3) {
				ctx.cli_ctrl->kill = 1;
			}
			ctx.expect = EXP_IDLE;
			break;

		case EXP_ABOR:
			if (c1 == 2) {
				client_data_reset(MOD_RESET);
				ctx.expect = EXP_IDLE;
			}
			break;

		case EXP_PASV:
			if (code == 227 && *arg != '\0') {
				client_srv_passive(arg);
			} else {
				socket_printf(ctx.cli_ctrl,
						"%s\r\n", str);
				client_data_reset(MOD_RESET);
				ctx.expect = EXP_IDLE;
			}
			break;

		case EXP_PORT:
			if (code == 200) {
				client_xfer_fireup();
			} else {
				socket_printf(ctx.cli_ctrl,
						"%s\r\n", str);
				client_data_reset(MOD_RESET);
				ctx.expect = EXP_IDLE;
			}
			break;

		case EXP_XFER:
			/*
			** Distinguish between success and failure
			*/
			if (c1 == 2) {
				misc_strncpy(ctx.xfer_rep, str,
					sizeof(ctx.xfer_rep));
			} else {
				socket_printf(ctx.cli_ctrl,
						"%s\r\n", str);
				if(config_bool(NULL,"FailResetsPasv", 0)) {
					client_data_reset(MOD_RESET);
				} else {
					client_data_reset(ctx.cli_mode);
				}
			}
			ctx.expect = EXP_IDLE;
			break;

		case EXP_PTHR:
			socket_printf(ctx.cli_ctrl, "%s\r\n", str);
			ctx.expect = EXP_IDLE;
			break;

		case EXP_IDLE:
			socket_printf(ctx.cli_ctrl, "%s\r\n", str);
			if (code == 421) {
				syslog_write(T_WRN,
					"server closed connection "
					"for %s", ctx.cli_ctrl->peer);
				ctx.cli_ctrl->kill = 1;
			} else {
				syslog_write(T_WRN,
					"bogus '%.512s' from "
					"Server-PI for %s",
					ctx.cli_ctrl->peer, str);
			}
			break;
	}
}
Ejemplo n.º 19
0
static void client_cli_ctrl_read(char *str)
{
	char *arg;
	CMD *cmd;
	int c;

	if (str == NULL) {		/* Basic sanity check	*/
#if defined(COMPILE_DEBUG)
		debug(2, "null User-PI msg: nothing to do");
#endif
		return;
	}

	/*
	** Handle a minimum amount of Telnet line control
	*/
	while ((arg = strchr(str, IAC)) != NULL) {
		c = (arg[1] & 255);
		switch (c) {
			case WILL:
			case WONT:
				/*
				** RFC 1123, 4.1.2.12
				*/
				syslog_write(U_WRN,
					"WILL/WONT refused for %s",
					ctx.cli_ctrl->peer);
				socket_printf(ctx.cli_ctrl,
					"%c%c%c", IAC, DONT, arg[2]);
				if(arg[2])
					memmove(arg, arg + 3, strlen(arg) - 2);
				else
					memmove(arg, arg + 1, strlen(arg));
				break;

			case DO:
			case DONT:
				/*
				** RFC 1123, 4.1.2.12
				*/
				syslog_write(U_WRN,
					"DO/DONT refused for %s",
					ctx.cli_ctrl->peer);
				socket_printf(ctx.cli_ctrl,
					"%c%c%c", IAC, WONT, arg[2]);
				if(arg[2])
					memmove(arg, arg + 3, strlen(arg) - 2);
				else
					memmove(arg, arg + 1, strlen(arg));
				break;

			case IAC:
				memmove(arg, arg + 1, strlen(arg));
				break;

			case IP:
			case DM:
				syslog_write(U_INF, "IAC-%s from %s",
						(c == IP) ? "IP" : "DM",
						ctx.cli_ctrl->peer);
				memmove(arg, arg + 2, strlen(arg) - 1);
				break;

			default:
				memmove(arg, arg + 1, strlen(arg));
		}
	}

	/*
	** If there is nothing left to process, please call again
	*/
	if (str[0] == '\0') {
#if defined(COMPILE_DEBUG)
		debug(2, "empty User-PI msg: nothing to do");
#endif
		return;
	}

	/*
	** Separate arguments if given
	*/
	if ((arg = strchr(str, ' ')) == NULL)
		arg = strchr(str, '\t');
	if (arg == NULL)
		arg = "";
	else {
		while (*arg == ' ' || *arg == '\t')
			*arg++ = '\0';
	}

#if defined(COMPILE_DEBUG)
	debug(1, "from User-PI (%d): cmd='%.32s' arg='%.512s'",
				ctx.cli_ctrl->sock, str, NIL(arg));
#endif

	/*
	** Try to execute the given command. The "USER" command
	**   must be enabled in any case, since it's the one to
	**   setup allow/deny (let's call it bootstrapping) ...
	*/
	for (cmd = cmds_get_list(); cmd->name != NULL; cmd++) {
		if (strcasecmp("USER", cmd->name) == 0)
			cmd->legal = 1;		/* Need this one! */
		if (strcasecmp(str, cmd->name) != 0)
			continue;
		if ((cmd->legal == 0) && strcasecmp("QUIT", cmd->name)) {
			client_respond(502, NULL, "'%.32s': "
				"command not implemented", str);
			syslog_write(U_WRN,
				"'%.32s' from %s not allowed",
				str, ctx.cli_ctrl->peer);
			return;
		}
#if defined(HAVE_REGEX)
		if (cmd->regex != NULL) {
			char *p;
			p = cmds_reg_exec(cmd->regex, arg);
			if (p != NULL) {
				client_respond(501, NULL,
					"'%.32s': syntax error "
					"in arguments", str);
				syslog_write(U_WRN,
					"bad arg '%.128s'%s for "
					"'%s' from %s: %s", arg,
					(strlen(arg) > 128) ?
					"..." : "", cmd->name,
					ctx.cli_ctrl->peer, p);
				return;
			}
		}
#endif
		ctx.curr_cmd = str;
		(*cmd->func)(&ctx, arg);
		return;
	}

	/*
	** Arriving here means the command was not found...
	*/
	client_respond(500, NULL, "'%.32s': command unrecognized", str);
	syslog_write(U_WRN, "unknown '%.32s' from %s",
					str, ctx.cli_ctrl->peer);
}
Ejemplo n.º 20
0
void client_run(void)
{
	int  sock, need, diff;
	char str[MAX_PATH_SIZE * 2];
	char *p, *q;
	FILE *fp;
	BUF  *buf;

	/*
	** Setup client signal handling (mostly graceful exit)
	*/
	signal(SIGINT,  client_signal);
	signal(SIGTERM, client_signal);
	signal(SIGQUIT, client_signal);
	signal(SIGHUP,  client_signal);
	signal(SIGCHLD, SIG_IGN);
	signal(SIGUSR1, SIG_IGN);

	/*
	** Prepare our general client context
	*/
	memset(&ctx, 0, sizeof(ctx));
	ctx.sess_beg = time(NULL);
	ctx.cli_mode = MOD_ACT_FTP;
	ctx.expect   = EXP_IDLE;
	ctx.timeout  = config_int(NULL, "TimeOut", 900);

	sock = fileno(stdin);		/* "recover" our socket */

	/*
	** Check whether a DenyMessage file exists. This
	** indicates that we are currently not willing
	** to serve any clients.
	*/
	p = config_str(NULL, "DenyMessage", NULL);
	if (p != NULL && (fp = fopen(p, "r")) != NULL) {
		while (fgets(str, sizeof(str) - 4, fp) != NULL) {
			p = socket_msgline(str);
			if ((q = strchr(p, '\n')) != NULL)
				strcpy(q, "\r\n");
			else
				strcat(p, "\r\n");
			send(sock, "421-", 4, 0);
			send(sock, p, strlen(p), 0);
		}
		fclose(fp);
		if ((p = config_str(NULL, "DenyString", NULL)) != NULL)
			p = socket_msgline(p);
		else
			p = "Service not available";
		send(sock, "421 ", 4, 0);
		send(sock, p, strlen(p), 0);
		send(sock, ".\r\n", 3, 0);
		p = socket_addr2str(socket_sck2addr(sock, REM_END, NULL));
		close(sock);
		syslog_write(U_ERR, "reject: '%s' (DenyMessage)", p);
		exit(EXIT_SUCCESS);
	}

	/*
	** Create a High Level Socket for the client's User-PI
	*/
	if ((ctx.cli_ctrl = socket_init(sock)) == NULL)
		misc_die(FL, "client_run: ?cli_ctrl?");
	ctx.cli_ctrl->ctyp = "Cli-Ctrl";

	/*
	** Announce the connection request
	*/
	syslog_write(U_INF, "connect from %s", ctx.cli_ctrl->peer);

	/*
	** Display the welcome message (invite the user to login)
	*/
	if ((p = config_str(NULL, "WelcomeString", NULL)) == NULL)
		p = "%h FTP server (Version %v - %b) ready";
	misc_strncpy(str, socket_msgline(p), sizeof(str));
	client_respond(220,
		config_str(NULL, "WelcomeMessage", NULL), str);

	/*
	** Enter the client mainloop
	*/
	while (close_flag == 0) {
		/*
		** We need to go into select() only
		** if all input has been processed
		**   or
		** we wait for more data to get a line
		** complete (partially sent, no EOL).
		**
		** (data buffers are never splited)
		*/
		need = 1;
		if (ctx.cli_ctrl && ctx.cli_ctrl->rbuf)
			need = 0;
		if (ctx.srv_ctrl && ctx.srv_ctrl->rbuf)
			need = 0;
		if((ctx.cli_ctrl && ctx.cli_ctrl->more>0) ||
		   (ctx.srv_ctrl && ctx.srv_ctrl->more>0))
			need = 1;

		/*
		** use higher priority to writes;
		** read only if nothing to write...
		*/
		if(ctx.srv_data && ctx.cli_data) {
			if(ctx.srv_data->wbuf) {
				ctx.cli_data->more = -1;
			} else {
				ctx.cli_data->more = 0;
			}
			if(ctx.cli_data->wbuf) {
				ctx.srv_data->more = -1;
			} else {
				ctx.srv_data->more = 0;
			}
		}

		if (need != 0) {
			if (socket_exec(ctx.timeout, &close_flag) <= 0)
				break;	/* Timed out or worse */
		}
#if defined(COMPILE_DEBUG)
		debug(4, "client-loop ...");
#endif

		/*
		** Check if any zombie sockets can be removed
		*/
		if (ctx.cli_ctrl != NULL && ctx.cli_ctrl->sock == -1)
			close_flag = 1;		/* Oops, forget it ... */

		if (ctx.srv_ctrl != NULL && ctx.srv_ctrl->sock == -1) {
#if defined(COMPILE_DEBUG)
			debug(3, "about to destroy Srv-Ctrl");
#endif
			/*
			** If we have any open data connections,
			** make really sure they don't survive.
			*/
			if (ctx.cli_data != NULL)
				ctx.cli_data->kill = 1;
			if (ctx.srv_data != NULL)
				ctx.srv_data->kill = 1;

			/*
			** Our client should be informed
			*/
			if (ctx.cli_ctrl->kill == 0) {
				client_respond(421, NULL,
					"Service not available, "
					"closing control connection");
			}

			/*
			** Don't forget to remove the dead socket
			*/
			socket_kill(ctx.srv_ctrl);
			ctx.srv_ctrl = NULL;
		}

		if (ctx.cli_data != NULL && ctx.cli_data->sock == -1) {
#if defined(COMPILE_DEBUG)
			debug(3, "about to destroy Cli-Data");
#endif
			/*
			** If we have an outstanding server reply
			** (e.g. 226 Transfer complete), send it.
			*/
			if (ctx.xfer_rep[0] != '\0') {
				socket_printf(ctx.cli_ctrl,
					"%s\r\n", ctx.xfer_rep);
				memset(ctx.xfer_rep, 0,
					sizeof(ctx.xfer_rep));
			} else {
				if(ctx.expect == EXP_XFER)
					ctx.expect = EXP_PTHR;
			}

			/*
			** Good time for statistics and data reset
			*/
			if (ctx.xfer_beg == 0)
				ctx.xfer_beg = time(NULL);
			diff = (int) (time(NULL) - ctx.xfer_beg);
			if (diff < 1)
				diff = 1;

			/*
			** print our current statistic
			*/
			syslog_write(U_INF,
				"Transfer for %s %s: %s '%s' %s %u/%d byte/sec",
				ctx.cli_ctrl->peer,
				ctx.cli_data->ernr ?  "failed" : "completed",
				ctx.xfer_cmd, ctx.xfer_arg,
				ctx.cli_data->rcnt ? "sent" : "read",
				ctx.cli_data->rcnt ? ctx.cli_data->rcnt
				                   : ctx.cli_data->wcnt,
				diff);

			/*
			** update session statistics data
			*/
			if(ctx.cli_data->rcnt)
				ctx.xfer_rsec += diff;
			ctx.xfer_rcnt += ctx.cli_data->rcnt;
			if(ctx.cli_data->wcnt)
				ctx.xfer_wsec += diff;
			ctx.xfer_wcnt += ctx.cli_data->wcnt;

			/*
			** reset data transfer state
			*/
			client_data_reset(MOD_RESET);

			/*
			** Doom the corresponding server socket
			*/
			if (ctx.srv_data != NULL)
				ctx.srv_data->kill = 1;

			/*
			** Don't forget to remove the dead socket
			*/
			socket_kill(ctx.cli_data);
			ctx.cli_data = NULL;
		}

		if (ctx.srv_data != NULL && ctx.srv_data->sock == -1) {

#if defined(COMPILE_DEBUG)
			debug(3, "about to destroy Srv-Data");
#endif
			/*
			** Doom the corresponding client socket if an
			** error occured, FailResetsPasv=yes or we
			** expect other response than PASV (Netscape!)
			*/
			if(ctx.cli_data != NULL) {
				if(0 != ctx.srv_data->ernr) {
					ctx.cli_data->ernr = -1;
					ctx.cli_data->kill =  1;
				}
				if(config_bool(NULL,"FailResetsPasv", 0)) {
					ctx.cli_data->kill = 1;
				} else if(ctx.expect != EXP_PASV) {
					ctx.cli_data->kill = 1;
				}
			}

			/*
			** Don't forget to remove the dead socket
			*/
			socket_kill(ctx.srv_data);
			ctx.srv_data = NULL;
		}

		/*
		** Serve the control connections
		*/
		if (ctx.cli_ctrl != NULL && ctx.cli_ctrl->rbuf != NULL) {
			if (socket_gets(ctx.cli_ctrl,
					str, sizeof(str)) != NULL)
				client_cli_ctrl_read(str);
		}
		if (ctx.srv_ctrl != NULL && ctx.srv_ctrl->rbuf != NULL) {
			if (socket_gets(ctx.srv_ctrl,
					str, sizeof(str)) != NULL)
				client_srv_ctrl_read(str);
		}

		/*
		** Serve the data connections. This is a bit tricky,
		** since all we do is move the buffer pointers.
		*/
		if (ctx.cli_data != NULL && ctx.srv_data != NULL) {
			if (ctx.cli_data->rbuf != NULL) {
#if defined(COMPILE_DEBUG)
				debug(2, "Cli-Data -> Srv-Data");
#endif
				if (ctx.srv_data->wbuf == NULL) {
					ctx.srv_data->wbuf =
						ctx.cli_data->rbuf;
				} else {
					for (buf = ctx.srv_data->wbuf;
							buf && buf->next;
							buf = buf->next)
						;
					buf->next = ctx.cli_data->rbuf;
				}
				ctx.cli_data->rbuf = NULL;
			}
			if (ctx.srv_data->rbuf != NULL) {
#if defined(COMPILE_DEBUG)
				debug(2, "Srv-Data -> Cli-Data");
#endif
				if (ctx.cli_data->wbuf == NULL) {
					ctx.cli_data->wbuf =
						ctx.srv_data->rbuf;
				} else {
					for (buf = ctx.cli_data->wbuf;
							buf && buf->next;
							buf = buf->next)
						;
					buf->next = ctx.srv_data->rbuf;
				}
				ctx.srv_data->rbuf = NULL;
			}
		}
		/* at this point the main loop resumes ... */
	}

	/*
	** Display basic session statistics...
	**   in secs since session begin
	**   downloads / read (xfer-reads from server)
	**   uploads   / send (xfer-sends from server)
	*/
	syslog_write(U_INF, "closing connect from %s after %d secs - "
	                    "read %d/%d, sent %d/%d byte/sec",
	             ctx.cli_ctrl ? ctx.cli_ctrl->peer : "unknown peer",
	             time(NULL)-ctx.sess_beg,
	             ctx.xfer_wcnt, ctx.xfer_wsec,
	             ctx.xfer_rcnt, ctx.xfer_rsec);

	/*
	** Free allocated memory
	*/
	ctx.magic_auth = NULL;
	if (ctx.userauth != NULL) {
		misc_free(FL, ctx.userauth);
		ctx.userauth = NULL;
	}
	if (ctx.username != NULL) {
		misc_free(FL, ctx.username);
		ctx.username = NULL;
	}
	if(ctx.userpass != NULL) {
		misc_free(FL, ctx.userpass);
		ctx.userpass = NULL;
	}

#if defined(COMPILE_DEBUG)
	debug(1, "}}}}} %s client-exit", misc_getprog());
#endif
	exit(EXIT_SUCCESS);
}
Ejemplo n.º 21
0
int client_setup(char *pwd)
{
	char      *type;
	char      *who;

	/*
	** Setup defaults for the client's DTP process
	*/
	ctx.cli_mode = MOD_ACT_FTP;
	ctx.cli_addr = ctx.cli_ctrl->addr;
	ctx.cli_port = ctx.cli_ctrl->port;
	ctx.srv_addr = INADDR_ANY;
	ctx.srv_port = INPORT_ANY;

	/*
	** select the proper name for user specific setup...
	*/
	if(NULL != ctx.userauth) {
		who = ctx.userauth;
	} else {
		who = ctx.username;
	}

	/*
	** don't allow empty or invalid names...
	*/
	if(NULL != who && '\0' != who[0]) {
		char *ptr;
#if defined(HAVE_REGEX)
		char *rule;
		void *preg = NULL;

		rule = config_str(NULL, "UserNameRule",
		       "^[[:alnum:]]+([%20@/\\._-][[:alnum:]]+)*$");
		       
		syslog_write(T_DBG, "compiling UserNameRule: '%.1024s'", rule);
		if(NULL == (ptr = cmds_reg_comp(&preg, rule))) {
		    return -1;
		}
		syslog_write(T_DBG, "DeHTMLized UserNameRule: '%.1024s'", ptr);

		ptr = cmds_reg_exec(preg, who);
		if(NULL != ptr) {
			syslog_write(U_WRN, "invalid user name '%.128s'%s: %s",
			             who, (strlen(who)>128 ? "..." : ""), ptr);
			cmds_reg_comp(&preg, NULL); /* free regex ptr */
			return -1;
		} else {
			cmds_reg_comp(&preg, NULL); /* free regex ptr */
		}
#else
		/*
		** Simplified "emulation" of the above regex:
		*/
		if( !(isalnum(who[0]) && isalnum(who[strlen(who)-1]))) {
		    syslog_write(U_ERR, "invalid user name '%.128s'%s",
		                 who, (strlen(who)>128 ? "..." : ""));
		    return 1;
		}
		for(ptr=who+1; *ptr; ptr++) {
		    if( !(isalnum(*ptr) ||
		           ' ' == *ptr  || '@' == *ptr || '/' == *ptr ||
		           '.' == *ptr  || '_' == *ptr || '-' == *ptr))
		    {
			syslog_write(U_ERR, "invalid user name '%.128s'%s",
			             who, (strlen(who)>128 ? "..." : ""));
			return -1;
		    }
		}
#endif
	} else {
		/* HUH ?! */
		syslog_write(U_ERR, "empty user name");
		return -1;
	}

	/*
	** user specific setup from config file
	** with fallback to default values
	*/
	if(0 != client_setup_file(&ctx, who)) {
		return -1;
	}

	/*
	** check if we have to authenticate the user
	**
	** authenticate user and setup user specific
	** from ldap server if configured
	*/
	type = config_str(NULL, "UserAuthType", NULL);
	if(NULL != type) {

		if(0 == strcasecmp(type, "ldap")) {
			/*
			** ldap server is mandatory
			*/
			if(NULL == config_str(NULL, "LDAPServer", NULL)) {
				misc_die(FL, "client_setup: ?LDAPServer?");
			}

			/*
			** ldap auth + setup
			*/
			if(0 != ldap_setup_user(&ctx, who, pwd ? pwd : ""))
				return -1;
		} else {
			misc_die(FL, "client_setup: unknown ?UserAuthType?");
		}

	} else {
		/*
		** try ldap setup only
		*/
		ldap_setup_user(&ctx, who, NULL);
	}

	/*
	** Evaluate mandatory settings or refuse to run.
	*/
	errno = 0;
	if(INADDR_ANY == ctx.srv_addr || INADDR_BROADCAST == ctx.srv_addr) {
		syslog_error("can't eval DestAddr for %s", ctx.cli_ctrl->peer);
		return -1;
	}
	if(INPORT_ANY == ctx.srv_port) {
		syslog_error("can't eval DestPort for %s", ctx.cli_ctrl->peer);
		return -1;
	}

	return 0; /* all right */
}