STREAM *STREAMSpawnFunction(BASIC_FUNC Func, void *Data, const char *Config) { int to_fd, from_fd, *iptr; pid_t pid=0; STREAM *S=NULL; char *Tempstr=NULL; int Flags=0; Flags=TTYParseConfig(Config, NULL); if (Flags & TTYFLAG_PTY) { pid=PseudoTTYSpawnFunction(&to_fd, Func, Data, Flags, Config); from_fd=to_fd; } else { iptr=NULL; //if (Flags & COMMS_COMBINE_STDERR) iptr=(int *) COMMS_COMBINE_STDERR; pid=PipeSpawnFunction(&to_fd, &from_fd, iptr, Func, Data, Config); } if (pid > 0) S=STREAMFromDualFD(from_fd, to_fd); if (S) { STREAMSetFlushType(S,FLUSH_LINE,0,0); Tempstr=FormatStr(Tempstr,"%d",pid); STREAMSetValue(S,"PeerPID",Tempstr); S->Type=STREAM_TYPE_PIPE; } DestroyString(Tempstr); return(S); }
STREAM *STREAMOpenFile(const char *FilePath, int Flags) { int fd, Mode=FALSE; STREAM *Stream; struct stat myStat; Mode = Flags & ~(O_LOCK|O_TRUNC); if (strcmp(FilePath,"-")==0) { Stream=STREAMFromDualFD(0,1); Stream->Path=CopyStr(Stream->Path,FilePath); return(Stream); } fd=open(FilePath, Mode, 0600); if (fd==-1) return(NULL); if (Flags & O_LOCK) { if (flock(fd,LOCK_EX | LOCK_NB)==-1) { close(fd); return(NULL); } } // check for symlink naughtyness. Basically a malicious user can // try to guess the name of the file we are going to open in order // to get us to write somewhere other than intended. if (lstat(FilePath, &myStat) !=0) { close(fd); return(NULL); } if (S_ISLNK(myStat.st_mode)) { syslog(LOG_USER | LOG_WARNING, "STREAMOpenFile Opened symlink when trying to open %s. Possible DOS attack?",FilePath); close(fd); return(NULL); } if (Flags & O_TRUNC) ftruncate(fd,0); Stream=STREAMFromFD(fd); Stream->Path=CopyStr(Stream->Path,FilePath); STREAMSetTimeout(Stream,0); STREAMSetFlushType(Stream,FLUSH_FULL,0); return(Stream); }
void ParseCommandLineUpdateUser(int argc, char *argv[]) { int i; char *Path=NULL, *Type=NULL, *User=NULL, *Pass=NULL, *Dir=NULL, *RealUser=NULL, *Args=NULL; STREAM *S; Args=CopyStr(Args,""); RealUser=CopyStr(RealUser,GetDefaultUser()); Path=CopyStr(Path,"/etc/metaftpd.auth"); if (strcmp(argv[2],"add")==0) Type=CopyStr(Type,"md5"); else if (strcmp(argv[2],"del")==0) Type=CopyStr(Type,"delete"); else if (strcmp(argv[2],"list")==0) Type=CopyStr(Type,"list"); else { printf("ERROR: -user must have 'add', 'del' or 'list' as it's next argument\n"); exit(1); } for (i=3; i < argc; i++) { if (strcmp(argv[i],"-a")==0) Path=CopyStr(Path,argv[++i]); else if (strcmp(argv[i],"-t")==0) Type=CopyStr(Type,argv[++i]); else if (strcmp(argv[i],"-e")==0) Type=CopyStr(Type,argv[++i]); else if (StrLen(User)==0) User=CopyStr(User,argv[i]); else if (StrLen(Pass)==0) Pass=CopyStr(Pass,argv[i]); else if (StrLen(Dir)==0) Dir=CopyStr(Dir,argv[i]); else Args=MCatStr(Args,argv[i]," ",NULL); } if (StrLen(Dir)==0) Dir=CopyStr(Dir,"/tmp"); if (strcmp(Type,"list")==0) { S=STREAMFromDualFD(0,1); ListNativeFile(S,Path); } else UpdateNativeFile(Path, User, Type, Pass, Dir, RealUser,Args); DestroyString(Path); DestroyString(Type); DestroyString(User); DestroyString(RealUser); DestroyString(Pass); DestroyString(Args); DestroyString(Dir); }
STREAM *STREAMSpawnFunction(BASIC_FUNC Func, void *Data) { int to_fd, from_fd; pid_t pid; STREAM *S=NULL; char *Tempstr=NULL; pid=PipeSpawnFunction(&to_fd, &from_fd, COMMS_COMBINE_STDERR, Func, Data, "", "" ); if (pid > 0) S=STREAMFromDualFD(from_fd, to_fd); if (S) { STREAMSetFlushType(S,FLUSH_LINE,0,0); Tempstr=FormatStr(Tempstr,"%d",pid); STREAMSetValue(S,"PeerPID",Tempstr); } DestroyString(Tempstr); return(S); }
STREAM *STREAMSpawnCommand(const char *Command, const char *User, const char *Group, int Flags) { int to_fd, from_fd; pid_t pid; STREAM *S=NULL; char *Tempstr=NULL; if (Flags & SPAWN_TRUST_COMMAND) Tempstr=CopyStr(Tempstr,Command); else Tempstr=MakeShellSafeString(Tempstr, Command, 0); if (Flags & COMMS_BY_PTY) { pid=PseudoTTYSpawn(&to_fd,Tempstr,User,Group,Flags); if (pid > 0) S=STREAMFromFD(to_fd); } else { if (Flags & COMMS_COMBINE_STDERR) { pid=PipeSpawn(&to_fd, &from_fd, COMMS_COMBINE_STDERR, Tempstr,User,Group); } else pid=PipeSpawn(&to_fd, &from_fd, NULL, Tempstr,User,Group); if (pid > 0) S=STREAMFromDualFD(from_fd, to_fd); } if (S) { STREAMSetFlushType(S,FLUSH_LINE,0,0); Tempstr=FormatStr(Tempstr,"%d",pid); STREAMSetValue(S,"PeerPID",Tempstr); } DestroyString(Tempstr); return(S); }
void HandleClient() { TSession *Session; char *Tempstr=NULL; int i; Session=(TSession *) calloc(1,sizeof(TSession)); Session->Shell=CopyStr(Session->Shell,Settings.DefaultShell); Session->S=STREAMFromDualFD(0,1); STREAMSetTimeout(Session->S,0); GetSockDetails(0, &Session->ServerIP, &i, &Session->ClientIP, &i); GetClientHardwareAddress(Session); Session->ClientHost=CopyStr(Session->ClientHost,IPStrToHostName(Session->ClientIP)); openlog("ptelnetd",LOG_PID|LOG_NDELAY,LOG_AUTH); if (StrLen(Session->ClientMAC)) syslog(Settings.InfoLogLevel,"connection from: %s (%s / %s)", Session->ClientHost, Session->ClientIP, Session->ClientMAC); else syslog(Settings.InfoLogLevel,"connection from: %s (%s)", Session->ClientHost, Session->ClientIP); if (! CheckClientPermissions(Session)) Session->Flags |= FLAG_DENYAUTH; chdir(Settings.ChDir); if (StrLen(Settings.ChDir)==0) chdir(Settings.ChDir); if (Settings.Flags & FLAG_CHROOT) chroot("."); TelnetSendNegotiation(Session->S, TELNET_WONT, TELNET_LINEMODE); TelnetSendNegotiation(Session->S, TELNET_WILL, TELNET_NOGOAHEAD); //TelnetSendNegotiation(Session->S, TELNET_DONT, TELNET_LINEMODE); TelnetSendNegotiation(Session->S, TELNET_WILL, TELNET_ECHO); if (StrLen(Settings.Banner)) { Tempstr=SessionSubstituteVars(Tempstr,Settings.Banner,Session); STREAMWriteLine(Tempstr,Session->S); STREAMWriteLine("\r\n",Session->S); } if (strcmp(Settings.AuthMethods,"open")==0) Session->Flags |= FLAG_AUTHENTICATED; else { for (i=0; i < Settings.AuthTries; i++) { if (Login(Session)) break; printf("\r\nLogin incorrect\r\n"); fflush(NULL); if (! (Settings.Flags & FLAG_DENYAUTH)){ openlog("ptelnetd",LOG_PID|LOG_NDELAY,LOG_AUTH); syslog(Settings.ErrorLogLevel,"%s@%s login failed: tries used %d/%d",Session->User,Session->ClientIP,i,Settings.AuthTries); } sleep(Settings.AuthDelay); } } if (Session->Flags & FLAG_AUTHENTICATED) { syslog(Settings.InfoLogLevel,"%s@%s logged in after %d tries",Session->User,Session->ClientIP,i); RunTelnetSession(Session); } else syslog(Settings.ErrorLogLevel,"login from %s failed after %d tries",Session->ClientIP,i); DestroyString(Tempstr); free(Session); _exit(0); }