int STREAMDoPostConnect(STREAM *S, int Flags) { int result=TRUE; char *ptr; struct timeval tv; if ((S->in_fd > -1) && (S->Timeout > 0) ) { tv.tv_sec=S->Timeout; tv.tv_usec=0; if (FDSelect(S->in_fd, SELECT_WRITE, &tv) <=0) { close(S->in_fd); S->in_fd=-1; S->out_fd=-1; } else if (! (Flags & CONNECT_NONBLOCK)) STREAMSetNonBlock(S, FALSE); } if (S->in_fd > -1) { S->Type=STREAM_TYPE_TCP; result=TRUE; STREAMSetFlushType(S,FLUSH_LINE,0); } //if (Flags & CONNECT_SOCKS_PROXY) result=DoSocksProxyTunnel(S); if (Flags & CONNECT_SSL) DoSSLClientNegotiation(S, Flags); ptr=GetRemoteIP(S->in_fd); if (ptr) STREAMSetValue(S,"PeerIP",ptr); return(result); }
STREAM *SMTPConnect(const char *Sender, const char *Recipients, int Flags) { char *MailFrom=NULL, *Recip=NULL, *Tempstr=NULL; char *Proto=NULL, *User=NULL, *Pass=NULL, *Host=NULL, *PortStr=NULL; const char *p_MailServer, *ptr; int result=FALSE, Caps=0, RecipientAccepted=FALSE; STREAM *S; p_MailServer=LibUsefulGetValue("SMTP:Server"); if (! StrValid(p_MailServer)) { RaiseError(0, "SendMail", "No Mailserver set"); return(NULL); } if (strncmp(p_MailServer,"smtp:",5) !=0) Tempstr=MCopyStr(Tempstr,"smtp:",p_MailServer,NULL); else Tempstr=CopyStr(Tempstr, p_MailServer); ParseURL(Tempstr, &Proto, &Host, &PortStr, &User, &Pass, NULL, NULL); if (! StrValid(PortStr)) PortStr=CopyStr(PortStr, "25"); Tempstr=MCopyStr(Tempstr,"tcp:",Host,":",PortStr,NULL); //syslog(LOG_DEBUG, "mailto: %s [%s] [%s] [%s]",Tempstr,Proto,Host,PortStr); S=STREAMOpen(Tempstr, ""); if (S) { if (SMTPInteract("", S)) { Caps=SMTPHelo(S); if (Caps > 0) { //try STARTTLS, the worst that will happen is the server will say no if ((! (Flags & SMTP_NOSSL)) && SSLAvailable() && SMTPInteract("STARTTLS\r\n", S)) DoSSLClientNegotiation(S, 0); if ( (Caps & (CAP_AUTH_LOGIN | CAP_AUTH_PLAIN)) && (StrValid(User) && StrValid(Pass)) ) SMTPLogin(S, Caps, User, Pass); //Whether login was needed or not, worked or not, let's try to send a mail Tempstr=MCopyStr(Tempstr, "MAIL FROM: ", Sender, "\r\n", NULL); if (! SMTPInteract(Tempstr, S)) RaiseError(0,"SendMail","mailserver refused sender"); else if (! SmtpSendRecipients(Recipients, S)) RaiseError(0,"SendMail","No recipients accepted by mailserver"); else if (! SMTPInteract("DATA\r\n", S)) RaiseError(0,"SendMail","mailserver refused mail"); else { //we got this far, rest of the process is handled by the calling function result=TRUE; } } else RaiseError(0,"SendMail","Initial mailserver handshake failed"); } else RaiseError(0,"SendMail","Initial mailserver handshake failed"); } else RaiseError(0,"SendMail","mailserver connection failed"); DestroyString(Tempstr); DestroyString(Recip); DestroyString(Proto); DestroyString(User); DestroyString(Pass); DestroyString(Host); DestroyString(PortStr); if (! result) { STREAMClose(S); return(NULL); } return(S); }
int STREAMProcessConnectHops(STREAM *S, const char *HopList) { int val, result=FALSE; char *Dest=NULL, *HopURL=NULL, *NextHop=NULL, *Token=NULL; const char *ptr; int count=0; ptr=GetToken(HopList, "|", &HopURL,0); //Note we check 'StrValid' not just whether ptr is null. This is because ptr will be an empty string //for the last token, and we don't want to process th last token, which will be the 'actual' connection while (StrValid(ptr)) { ptr=GetToken(ptr, "|", &NextHop,0); ParseConnectDetails(NextHop, NULL, &Dest, &Token, NULL, NULL, NULL); Dest=MCatStr(Dest,":",Token,NULL); GetToken(HopURL,":",&Token,0); val=MatchTokenFromList(Token,HopTypes,0); switch (val) { case CONNECT_HOP_TCP: //this type assumes that connecting to a host and port instantly puts us through to the Destination. //thus we do nothing with the Destination value, except maybe log it if connection fails //It's a no-op unless it's the first item in the connection chain, as otherwise previous connections //will have effectively processed this already if (count > 0) result=TRUE; else { if (STREAMDirectConnect(S, HopURL, 0)) result=TRUE; else RaiseError(0, "ConnectHopTCP", "failed to connect to %s for destination %s", HopURL, Dest); } break; case CONNECT_HOP_HTTPTUNNEL: result=ConnectHopHTTPSProxy(S, HopURL, Dest); break; case CONNECT_HOP_SSH: case CONNECT_HOP_SSHTUNNEL: if (count==0) result=ConnectHopSSH(S, val, HopURL, Dest); else { result=FALSE; RaiseError(0, "ConnectHopSSH", "SSH connect hops must be first in hop chain. Connection failed to %s for destination %s", HopURL, Dest); } break; case CONNECT_HOP_SOCKS4: case CONNECT_HOP_SOCKS5: result=ConnectHopSocks(S, val, HopURL, Dest); break; default: RaiseError(0, "ConnectHop", "unknown connection proxy type %s", HopURL); break; } S->State=SS_INITIAL_CONNECT_DONE; count++; HopURL=CopyStr(HopURL, NextHop); } if (StrValid(HopURL)) { if (! StrLen(S->Path)) S->Path=CopyStr(S->Path,HopURL); if (strncmp(HopURL,"ssl:",4)==0) DoSSLClientNegotiation(S,0); } DestroyString(HopURL); DestroyString(NextHop); DestroyString(Token); DestroyString(Dest); STREAMFlush(S); return(result); }