コード例 #1
0
/* utility wrapper */
static void
spawned_shell(void *targ)
{
  rtems_status_code    sc;
  FILE                *nstd[3]={0};
  FILE                *ostd[3]={ stdin, stdout, stderr };
  int                  i=0;
  struct shell_args  *arg = targ;
  bool login_failed = false;
  bool start = true;

  sc=rtems_libio_set_private_env();

  /* newlib hack/workaround. Before we change stdin/out/err we must make
         * sure the internal data are initialized (fileno(stdout) has this sideeffect).
   * This should probably be done from RTEMS' libc support layer...
   * (T.S., newlibc-1.13; 2005/10)
         */

  fileno(stdout);

  if (RTEMS_SUCCESSFUL != sc) {
    rtems_error(sc,"rtems_libio_set_private_env");
    goto cleanup;
  }

  /* redirect stdio */
  for (i=0; i<3; i++) {
    if ( !(nstd[i]=fopen(arg->devname,"r+")) ) {
      perror("unable to open stdio");
      goto cleanup;
    }
  }

  stdin  = nstd[0];
  stdout = nstd[1];
  stderr = nstd[2];

  #if 0
    printk("STDOUT is now %x (%x) (FD %i/%i)\n",
           stdout,nstd[1],fileno(stdout),fileno(nstd[1]));
    printf("hello\n");
    write(fileno(stdout),"hellofd\n",8);
  #endif

  /* call their routine */
  if (rtems_telnetd_config.login_check != NULL) {
    start = rtems_shell_login_prompt(
      stdin,
      stderr,
      arg->devname,
      rtems_telnetd_config.login_check
    );
    login_failed = !start;
  }
  if (start) {
    rtems_telnetd_config.command( arg->devname, arg->arg);
  }

  stdin  = ostd[0];
  stdout = ostd[1];
  stderr = ostd[2];

  if (login_failed) {
    syslog(
      LOG_AUTHPRIV | LOG_WARNING,
      "telnetd: to many wrong passwords entered from %s",
      arg->peername
    );
  }

cleanup:
  release_a_Connection(arg->devname, arg->peername, nstd, i);
  free(arg);
}
コード例 #2
0
ファイル: shell.c プロジェクト: 0871087123/rtems
static bool rtems_shell_login(FILE * in,FILE * out) {
  FILE          *fd;
  int            c;
  time_t         t;

  rtems_shell_init_issue();
  setuid(0);
  setgid(0);
  rtems_current_user_env->euid =
  rtems_current_user_env->egid =0;

  if (out) {
    if ((rtems_current_shell_env->devname[5]!='p')||
        (rtems_current_shell_env->devname[6]!='t')||
        (rtems_current_shell_env->devname[7]!='y')) {
      fd = fopen("/etc/issue","r");
      if (fd) {
        while ((c=fgetc(fd))!=EOF) {
          if (c=='@')  {
            switch(c=fgetc(fd)) {
              case 'L':
                fprintf(out,"%s",rtems_current_shell_env->devname);
                break;
              case 'B':
                fprintf(out,"0");
                break;
              case 'T':
              case 'D':
                time(&t);
                fprintf(out,"%s",ctime(&t));
                break;
              case 'S':
                fprintf(out,"RTEMS");
                break;
              case 'V':
                fprintf(out,"%s\n%s",_RTEMS_version, _Copyright_Notice);
                break;
              case '@':
                fprintf(out,"@");
                break;
              default :
                fprintf(out,"@%c",c);
                break;
            }
          } else if (c=='\\')  {
            switch(c=fgetc(fd)) {
              case '\\': fprintf(out,"\\"); break;
              case 'b':  fprintf(out,"\b"); break;
              case 'f':  fprintf(out,"\f"); break;
              case 'n':  fprintf(out,"\n"); break;
              case 'r':  fprintf(out,"\r"); break;
              case 's':  fprintf(out," ");  break;
              case 't':  fprintf(out,"\t"); break;
              case '@':  fprintf(out,"@");  break;
            }
          } else {
            fputc(c,out);
          }
        }
        fclose(fd);
      }
    } else {
      fd = fopen("/etc/issue.net","r");
      if (fd) {
        while ((c=fgetc(fd))!=EOF) {
          if (c=='%')  {
            switch(c=fgetc(fd)) {
              case 't':
                fprintf(out,"%s",rtems_current_shell_env->devname);
                break;
              case 'h':
                fprintf(out,"0");
                break;
              case 'D':
                fprintf(out," ");
                break;
              case 'd':
                time(&t);
                fprintf(out,"%s",ctime(&t));
                break;
              case 's':
                fprintf(out,"RTEMS");
                break;
              case 'm':
                fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")");
                break;
              case 'r':
                fprintf(out,_RTEMS_version);
                break;
              case 'v':
                fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
	        break;
	      case '%':fprintf(out,"%%");
	        break;
	      default:
                fprintf(out,"%%%c",c);
                break;
            }
          } else {
            fputc(c,out);
          }
        }
        fclose(fd);
      }
    }
  }

  return rtems_shell_login_prompt(
    in,
    out,
    rtems_current_shell_env->devname,
    rtems_current_shell_env->login_check
  );
}
コード例 #3
0
static void
rtems_task_telnetd(void *task_argument)
{
  int                des_socket;
  uni_sa             srv;
  char              *devname;
  char               peername[16];
  int                i=1;
  int                size_adr;
  struct shell_args *arg = NULL;

  if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
    perror("telnetd:socket");
    telnetd_task_id = RTEMS_ID_NONE;
    rtems_task_delete(RTEMS_SELF);
  };
  setsockopt(des_socket,SOL_SOCKET,SO_KEEPALIVE,&i,sizeof(i));

  memset(&srv,0,sizeof(srv));
  srv.sin.sin_family=AF_INET;
  srv.sin.sin_port=htons(23);
  size_adr=sizeof(srv.sin);
  if ((bind(des_socket,&srv.sa,size_adr))<0) {
    perror("telnetd:bind");
    close(des_socket);
    telnetd_task_id = RTEMS_ID_NONE;
    rtems_task_delete(RTEMS_SELF);
  };
  if ((listen(des_socket,5))<0) {
    perror("telnetd:listen");
          close(des_socket);
    telnetd_task_id = RTEMS_ID_NONE;
    rtems_task_delete(RTEMS_SELF);
  };

  /* we don't redirect stdio as this probably
   * was started from the console anyways..
   */
  do {
    if (rtems_telnetd_config.keep_stdio) {
      bool start = true;
      char device_name [32];

      ttyname_r( 1, device_name, sizeof( device_name));
      if (rtems_telnetd_config.login_check != NULL) {
        start = rtems_shell_login_prompt(
          stdin,
          stderr,
          device_name,
          rtems_telnetd_config.login_check
        );
      }
      if (start) {
        rtems_telnetd_config.command( device_name, arg->arg);
      } else {
        syslog(
          LOG_AUTHPRIV | LOG_WARNING,
          "telnetd: to many wrong passwords entered from %s",
          device_name
        );
      }
    } else {
      devname = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));

      if ( !devname ) {
        /* if something went wrong, sleep for some time */
        sleep(10);
        continue;
      }

      arg = malloc( sizeof(*arg) );

      arg->devname = devname;
      arg->arg = rtems_telnetd_config.arg;
      strncpy(arg->peername, peername, sizeof(arg->peername));

      telnetd_task_id = telnetd_spawn_task(
        devname,
        rtems_telnetd_config.priority,
        rtems_telnetd_config.stack_size,
        spawned_shell,
        arg
      );
      if (telnetd_task_id == RTEMS_ID_NONE) {
        FILE *dummy;

        if ( telnetd_spawn_task != telnetd_dflt_spawn ) {
          fprintf(stderr,"Telnetd: Unable to spawn child task\n");
        }

        /* hmm - the pty driver slot can only be
         * released by opening and subsequently
         * closing the PTY - this also closes
         * the underlying socket. So we mock up
         * a stream...
         */

        if ( !(dummy=fopen(devname,"r+")) )
          perror("Unable to dummy open the pty, losing a slot :-(");
        release_a_Connection(devname, peername, &dummy, 1);
        free(arg);
        sleep(2); /* don't accept connections too fast */
      }
    }
  } while(1);

  /* TODO: how to free the connection semaphore? But then -
   *       stopping the daemon is probably only needed during
   *       development/debugging.
   *       Finalizer code should collect all the connection semaphore
   *       counts and eventually clean up...
   */
  close(des_socket);
  telnetd_task_id = RTEMS_ID_NONE;
}