summaryrefslogtreecommitdiffstats
path: root/cpukit/telnetd/telnetd.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2007-09-25 17:14:01 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2007-09-25 17:14:01 +0000
commit8ad6681b6bb601c670726ca36c924f5852d01efd (patch)
tree275fca640d9fe0e35af05bbeda01a35541d51d74 /cpukit/telnetd/telnetd.c
parent2007-09-25 Joel Sherrill <joel.sherrill@OARcorp.com> (diff)
downloadrtems-8ad6681b6bb601c670726ca36c924f5852d01efd.tar.bz2
2007-09-25 Joel Sherrill <joel.sherrill@oarcorp.com>
* telnetd/README, telnetd/pty.c, telnetd/pty.h, telnetd/telnetd.c, telnetd/telnetd.h: telnetd rewrite. * telnetd/check_passwd.c, telnetd/des.c, telnetd/genpw.c: New files.
Diffstat (limited to 'cpukit/telnetd/telnetd.c')
-rw-r--r--cpukit/telnetd/telnetd.c442
1 files changed, 225 insertions, 217 deletions
diff --git a/cpukit/telnetd/telnetd.c b/cpukit/telnetd/telnetd.c
index 24282059aa..ba3d10f25c 100644
--- a/cpukit/telnetd/telnetd.c
+++ b/cpukit/telnetd/telnetd.c
@@ -78,15 +78,15 @@ extern int telnet_pty_initialize();
extern int telnet_pty_finalize();
struct shell_args {
- char *devname;
- void *arg;
- char peername[16];
- char delete_myself;
+ char *devname;
+ void *arg;
+ char peername[16];
+ char delete_myself;
};
typedef union uni_sa {
- struct sockaddr_in sin;
- struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr sa;
} uni_sa;
static int sockpeername(int sock, char *buf, int bufsz);
@@ -113,35 +113,35 @@ socklen_t
/* 4.6 doesn't have socklen_t */
uint32_t
#endif
- size_adr = sizeof(srv->sin);
+ size_adr = sizeof(srv->sin);
int acp_sock;
- acp_sock = accept(des_socket,&srv->sa,&size_adr);
+ acp_sock = accept(des_socket,&srv->sa,&size_adr);
- if (acp_sock<0) {
- perror("telnetd:accept");
- goto bailout;
- };
+ if (acp_sock<0) {
+ perror("telnetd:accept");
+ goto bailout;
+ };
- if ( !(rval=telnet_get_pty(acp_sock)) ) {
- syslog( LOG_DAEMON | LOG_ERR, "telnetd: unable to obtain PTY");
- /* NOTE: failing 'do_get_pty()' closed the socket */
- goto bailout;
- }
+ if ( !(rval=telnet_get_pty(acp_sock)) ) {
+ syslog( LOG_DAEMON | LOG_ERR, "telnetd: unable to obtain PTY");
+ /* NOTE: failing 'do_get_pty()' closed the socket */
+ goto bailout;
+ }
- if (sockpeername(acp_sock, peername, sz))
- strncpy(peername, "<UNKNOWN>", sz);
+ if (sockpeername(acp_sock, peername, sz))
+ strncpy(peername, "<UNKNOWN>", sz);
#ifdef PARANOIA
- syslog(LOG_DAEMON | LOG_INFO,
- "telnetd: accepted connection from %s on %s",
- peername,
- rval);
+ syslog(LOG_DAEMON | LOG_INFO,
+ "telnetd: accepted connection from %s on %s",
+ peername,
+ rval);
#endif
bailout:
- return rval;
+ return rval;
}
@@ -149,14 +149,14 @@ static void release_a_Connection(char *devname, char *peername, FILE **pstd, int
{
#ifdef PARANOIA
- syslog( LOG_DAEMON | LOG_INFO,
- "telnetd: releasing connection from %s on %s",
- peername,
- devname );
+ syslog( LOG_DAEMON | LOG_INFO,
+ "telnetd: releasing connection from %s on %s",
+ peername,
+ devname );
#endif
- while (--n>=0)
- if (pstd[n]) fclose(pstd[n]);
+ while (--n>=0)
+ if (pstd[n]) fclose(pstd[n]);
}
@@ -169,17 +169,17 @@ socklen_t
/* 4.6 doesn't have socklen_t */
uint32_t
#endif
- len = sizeof(peer.sin);
+ len = sizeof(peer.sin);
int rval = sock < 0;
- if ( !rval)
- rval = getpeername(sock, &peer.sa, &len);
+ if ( !rval)
+ rval = getpeername(sock, &peer.sa, &len);
- if ( !rval )
- rval = !inet_ntop( AF_INET, &peer.sin.sin_addr, buf, bufsz );
+ if ( !rval )
+ rval = !inet_ntop( AF_INET, &peer.sin.sin_addr, buf, bufsz );
- return rval;
+ return rval;
}
#if 1
@@ -205,136 +205,144 @@ int i=1;
int size_adr;
struct shell_args *arg;
- if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
- perror("telnetd:socket");
- telnetd_task_id=0;
- 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=0;
- rtems_task_delete(RTEMS_SELF);
- };
- if ((listen(des_socket,5))<0) {
- perror("telnetd:listen");
- close(des_socket);
- telnetd_task_id=0;
- rtems_task_delete(RTEMS_SELF);
- };
-
- /* we don't redirect stdio as this probably
- * was started from the console anyways..
- */
- do {
- devname = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
-
- if ( !devname ) {
- /* if something went wrong, sleep for some time */
- sleep(10);
- continue;
- }
- if ( telnetd_dont_spawn ) {
- if ( 0 == check_passwd(peername) )
- telnetd_shell(devname, telnetd_shell_arg);
- } else {
- arg = malloc( sizeof(*arg) );
-
- arg->devname = devname;
- arg->arg = telnetd_shell_arg;
- strncpy(arg->peername, peername, sizeof(arg->peername));
-
- if ( !telnetd_spawn_task(&devname[5], telnetd_task_priority, telnetd_stack_size, spawned_shell, arg) ) {
-
- 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 */
+ if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
+ perror("telnetd:socket");
+ telnetd_task_id=0;
+ 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=0;
+ rtems_task_delete(RTEMS_SELF);
+ };
+ if ((listen(des_socket,5))<0) {
+ perror("telnetd:listen");
+ close(des_socket);
+ telnetd_task_id=0;
+ rtems_task_delete(RTEMS_SELF);
+ };
+
+ /* we don't redirect stdio as this probably
+ * was started from the console anyways..
+ */
+ do {
+ devname = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
+
+ if ( !devname ) {
+ /* if something went wrong, sleep for some time */
+ sleep(10);
+ continue;
+ }
+ if ( telnetd_dont_spawn ) {
+ if ( 0 == check_passwd(peername) )
+ telnetd_shell(devname, telnetd_shell_arg);
+ } else {
+ arg = malloc( sizeof(*arg) );
+
+ arg->devname = devname;
+ arg->arg = telnetd_shell_arg;
+ strncpy(arg->peername, peername, sizeof(arg->peername));
+
+ if ( !telnetd_spawn_task(&devname[5], telnetd_task_priority, telnetd_stack_size, spawned_shell, arg) ) {
+
+ 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=0;
+ }
+ } 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=0;
}
/***********************************************************/
static int initialize_telnetd(void) {
-
- if (telnetd_task_id ) return RTEMS_RESOURCE_IN_USE;
- if (telnetd_stack_size<=0 ) telnetd_stack_size =32000;
-
- if ( !telnetd_spawn_task("TNTD", telnetd_task_priority, RTEMS_MINIMUM_STACK_SIZE, rtems_task_telnetd, 0) ) {
- return -1;
- }
- return 0;
+
+ if (telnetd_task_id ) return RTEMS_RESOURCE_IN_USE;
+ if (telnetd_stack_size<=0 ) telnetd_stack_size =32000;
+
+ if ( !telnetd_spawn_task("TNTD", telnetd_task_priority, RTEMS_MINIMUM_STACK_SIZE, rtems_task_telnetd, 0) ) {
+ return -1;
+ }
+ return 0;
}
/***********************************************************/
-int startTelnetd(void (*cmd)(char *, void *), void *arg, int dontSpawn, int stack, int priority)
+int rtems_telnetd_initialize(
+ void (*cmd)(char *, void *),
+ void *arg,
+ int dontSpawn,
+ size_t stack,
+ rtems_task_priority priority
+)
{
- rtems_status_code sc;
-
- printf("This is rtems-telnetd (modified by Till Straumann)\n");
- printf("$Id$\n");
- printf("Release $Name$\n");
-
- if ( !telnetd_shell && !cmd ) {
- fprintf(stderr,"startTelnetd(): setup error - NO SHELL; bailing out\n");
- return 1;
- }
-
- if (telnetd_task_id) {
- fprintf(stderr,"ERROR:telnetd already started\n");
- return 1;
- };
-
- if ( !telnet_pty_initialize() ) {
- fprintf(stderr,"PTY driver probably not properly registered\n");
- return 1;
- }
-
- if (cmd)
- telnetd_shell = cmd;
- telnetd_shell_arg = arg;
- telnetd_stack_size = stack;
- if ( !priority ) {
- priority = rtems_bsdnet_config.network_task_priority;
- }
- if ( priority < 2 )
- priority=100;
- telnetd_task_priority = priority;
- telnetd_dont_spawn = dontSpawn;
-
- sc=initialize_telnetd();
+ rtems_status_code sc;
+
+#if 0
+ printf("This is rtems-telnetd (modified by Till Straumann)\n");
+ printf("$Id$\n");
+ printf("Release $Name$\n");
+#endif
+
+ if ( !telnetd_shell && !cmd ) {
+ fprintf(stderr,"startTelnetd(): setup error - NO SHELL; bailing out\n");
+ return 1;
+ }
+
+ if (telnetd_task_id) {
+ fprintf(stderr,"ERROR:telnetd already started\n");
+ return 1;
+ };
+
+ if ( !telnet_pty_initialize() ) {
+ fprintf(stderr,"PTY driver probably not properly registered\n");
+ return 1;
+ }
+
+ if (cmd)
+ telnetd_shell = cmd;
+ telnetd_shell_arg = arg;
+ telnetd_stack_size = stack;
+ if ( !priority ) {
+ priority = rtems_bsdnet_config.network_task_priority;
+ }
+ if ( priority < 2 )
+ priority=100;
+ telnetd_task_priority = priority;
+ telnetd_dont_spawn = dontSpawn;
+
+ sc=initialize_telnetd();
if (sc!=RTEMS_SUCCESSFUL) return sc;
- printf("rtems_telnetd() started with stacksize=%u,priority=%d\n",
+ printf("rtems_telnetd() started with stacksize=%u,priority=%d\n",
(unsigned)telnetd_stack_size,(int)telnetd_task_priority);
- return 0;
+ return 0;
}
/* utility wrapper */
@@ -347,32 +355,32 @@ FILE *ostd[3]={ stdin, stdout, stderr };
int i=0;
struct shell_args *arg = targ;
- sc=rtems_libio_set_private_env();
+ sc=rtems_libio_set_private_env();
- /* newlib hack/workaround. Before we change stdin/out/err we must make
+ /* 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)
+ * This should probably be done from RTEMS' libc support layer...
+ * (T.S., newlibc-1.13; 2005/10)
*/
- fileno(stdout);
+ fileno(stdout);
- if (RTEMS_SUCCESSFUL != sc) {
- rtems_error(sc,"rtems_libio_set_private_env");
- goto cleanup;
- }
+ 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;
- }
- }
+ /* 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];
+ stdin = nstd[0];
+ stdout = nstd[1];
+ stderr = nstd[2];
@@ -382,22 +390,22 @@ printf("hello\n");
write(fileno(stdout),"hellofd\n",8);
#endif
- /* call their routine */
- if ( 0 == check_passwd(arg->peername) )
- telnetd_shell(arg->devname, arg->arg);
+ /* call their routine */
+ if ( 0 == check_passwd(arg->peername) )
+ telnetd_shell(arg->devname, arg->arg);
- stdin = ostd[0];
- stdout = ostd[1];
- stderr = ostd[2];
+ stdin = ostd[0];
+ stdout = ostd[1];
+ stderr = ostd[2];
cleanup:
- release_a_Connection(arg->devname, arg->peername, nstd, i);
- free(arg);
+ release_a_Connection(arg->devname, arg->peername, nstd, i);
+ free(arg);
}
struct wrap_delete_args {
- void (*t)(void *);
- void *a;
+ void (*t)(void *);
+ void *a;
};
static rtems_task
@@ -407,12 +415,12 @@ struct wrap_delete_args *pwa = (struct wrap_delete_args *)arg;
register void (*t)(void *) = pwa->t;
register void *a = pwa->a;
- /* free argument before calling function (which may never return if
- * they choose to delete themselves)
- */
- free(pwa);
- t(a);
- rtems_task_delete(RTEMS_SELF);
+ /* free argument before calling function (which may never return if
+ * they choose to delete themselves)
+ */
+ free(pwa);
+ t(a);
+ rtems_task_delete(RTEMS_SELF);
}
void *
@@ -423,32 +431,32 @@ rtems_id task_id;
char nm[4] = {'X','X','X','X' };
struct wrap_delete_args *pwa = malloc(sizeof(*pwa));
- strncpy(nm, name, 4);
-
- if ( !pwa ) {
- perror("Telnetd: no memory\n");
- return 0;
- }
-
- pwa->t = fn;
- pwa->a = fnarg;
-
- if ((sc=rtems_task_create(
- rtems_build_name(nm[0], nm[1], nm[2], nm[3]),
- (rtems_task_priority)priority,
- stackSize,
- RTEMS_DEFAULT_MODES,
- RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,
- &task_id)) ||
- (sc=rtems_task_start(
- task_id,
- wrap_delete,
- (rtems_task_argument)pwa))) {
- free(pwa);
- rtems_error(sc,"Telnetd: spawning task failed");
- return 0;
- }
- return (void*)task_id;
+ strncpy(nm, name, 4);
+
+ if ( !pwa ) {
+ perror("Telnetd: no memory\n");
+ return 0;
+ }
+
+ pwa->t = fn;
+ pwa->a = fnarg;
+
+ if ((sc=rtems_task_create(
+ rtems_build_name(nm[0], nm[1], nm[2], nm[3]),
+ (rtems_task_priority)priority,
+ stackSize,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,
+ &task_id)) ||
+ (sc=rtems_task_start(
+ task_id,
+ wrap_delete,
+ (rtems_task_argument)pwa))) {
+ free(pwa);
+ rtems_error(sc,"Telnetd: spawning task failed");
+ return 0;
+ }
+ return (void*)task_id;
}
/* convenience routines for CEXP (retrieve stdio descriptors