// Returns a test client and the end of a connection pipe func getTestClient() (*transaction, *textproto.Conn) { sc, cc := net.Pipe() sconn, cconn := textproto.NewConn(sc), textproto.NewConn(cc) client := &transaction{ Mode: stateHELO, Message: new(mailbox.Message), text: sconn, host: &mockHost{ QueryMock: func(addr *mail.Address) int { switch strings.Split(addr.Address, "@")[0] { case "not_found": return mailbox.QueryNotFound case "not_local": return mailbox.QueryNotLocal case "success": return mailbox.QuerySuccess } return mailbox.QueryError }, SettingsMock: func() jamon.Group { return jamon.Group{} }, DigestMock: func(c *transaction) error { return nil }, }, } return client, cconn }
// DialTimeout initializes the connection to the specified ftp server address. // // It is generally followed by a call to Login() as most FTP commands require // an authenticated user. func DialTimeout(addr string, timeout time.Duration) (*ServerConn, error) { tconn, err := net.DialTimeout("tcp", addr, timeout) if err != nil { return nil, err } conn := textproto.NewConn(tconn) a := strings.SplitN(addr, ":", 2) c := &ServerConn{ conn: conn, host: a[0], timeout: timeout, features: make(map[string]string), } _, _, err = c.conn.ReadResponse(StatusReady) if err != nil { c.Quit() return nil, err } err = c.feat() if err != nil { c.Quit() return nil, err } return c, nil }
func SendStartTLS(conn net.Conn, config *tls.Config) (econn *textproto.Conn, state tls.ConnectionState, err error) { _, err = io.WriteString(conn, "STARTTLS\r\n") if err == nil { r := bufio.NewReader(conn) var line string line, err = r.ReadString(10) if strings.HasPrefix(line, "382 ") { // we gud tconn := tls.Client(conn, config) err = tconn.Handshake() if err == nil { // tls okay state = tconn.ConnectionState() econn = textproto.NewConn(tconn) } else { log.Println("STARTTLS failed", err) tconn.Close() } } else { // it won't do tls err = TlsNotSupported } r = nil } return }
// do a oneshot pull based sync with another server func (self NNTPDaemon) syncPull(proxy_type, proxy_addr, remote_addr string) { c, err := self.dialOut(proxy_type, proxy_addr, remote_addr) if err == nil { conn := textproto.NewConn(c) // we connected nntp := createNNTPConnection() nntp.name = remote_addr + "-sync" // do handshake _, reader, err := nntp.outboundHandshake(conn) if reader { // we can do it err = nntp.scrapeServer(self, conn) if err == nil { log.Println(nntp.name, "Scrape successful") nntp.Quit(conn) } else { log.Println(nntp.name, "scrape failed", err) conn.Close() } } else if err == nil { // we can't do it log.Println(nntp.name, "does not support reader mode, cancel scrape") nntp.Quit(conn) } else { // error happened log.Println(nntp.name, "error occurred when scraping", err) } } }
// It should reply using the attached network connection func TestClientNotify(t *testing.T) { sc, cc := net.Pipe() cconn := textproto.NewConn(cc) testClient := &transaction{text: textproto.NewConn(sc)} go testClient.notify(reply{200, "Hello"}) msg, err := cconn.ReadLine() if err != nil { t.Errorf("Error reading end of pipe (%s)", err) } if msg != "200 Hello" { t.Errorf("Got '%s' but expected '%s'", msg, "200 Hello") } }
func (self NNTPDaemon) persistFeed(conf FeedConfig, mode string) { for { if self.running { conn, err := self.dialOut(conf.proxy_type, conf.proxy_addr, conf.addr) if err != nil { time.Sleep(time.Second * 5) continue } nntp := createNNTPConnection() nntp.policy = conf.policy nntp.name = conf.name + "-" + mode c := textproto.NewConn(conn) stream, reader, err := nntp.outboundHandshake(c) if err == nil { if mode == "reader" && !reader { log.Println(nntp.name, "we don't support reader on this feed, dropping") return } self.register_outfeed <- nntp nntp.runConnection(self, false, stream, reader, mode, c) self.deregister_outfeed <- nntp } else { log.Println("error doing outbound hanshake", err) } } time.Sleep(1 * time.Second) } }
//Connect establishes a connection with the local Freeswitch server. func (client *Client) connect() (err error) { //Connect to Freeswitch Event Socket. conn, err := net.DialTimeout("tcp", client.addr, time.Duration(5*time.Second)) if err != nil { return } //Convert the raw TCP connection to a textproto connection. client.connMu.Lock() defer client.connMu.Unlock() if client.eventConn != nil { client.eventConn.Close() } client.eventConn = textproto.NewConn(conn) //Read the welcome message. resp, err := client.eventConn.ReadMIMEHeader() if err != nil { return } //Send authentication request to server. client.eventConn.PrintfLine("auth %s\r\n", client.password) if resp, err = client.eventConn.ReadMIMEHeader(); err != nil { return } //Check the command was processed OK. if resp.Get("Reply-Text") == "+OK accepted" { return } return errors.New("Authentication failed: " + resp.Get("Reply-Text")) }
func NewAmiConn(ctx context.Context, conn io.ReadWriteCloser, c *AmiServer) *AmiConn { var ( sctx context.Context cancel context.CancelFunc ) sctx, cancel = context.WithCancel(ctx) amic := &AmiConn{ Context: sctx, cancel: cancel, uuid: uuid.New("C"), srv: c, messageCh: make(chan textproto.MIMEHeader, 100), connRaw: conn, conn: textproto.NewConn(conn), } go amic.doHeartBeat() go amic.doReader() go amic.doWriter() go func(amic *AmiConn) { <-amic.Done() amic.Close() }(amic) amic.conn.PrintfLine("Asterisk Call Manager") return amic }
// Should create a client that picks up commands // and greet the connection with 220 status func TestServerCreateClient(t *testing.T) { var wg sync.WaitGroup cc, sc := mocks.Pipe( &mocks.Conn{RAddr: "1.1.1.1:123"}, &mocks.Conn{RAddr: "1.1.1.1:123"}, ) cconn := textproto.NewConn(cc) testServer := server{ spec: commandSpec{ "EXIT": func(ctx *transaction, params string) error { return io.EOF }, }, config: jamon.Group{"host": "mecca.local"}, } wg.Add(1) go func() { testServer.createTransaction(sc) wg.Done() }() _, _, err := cconn.ReadResponse(220) if err != nil { t.Errorf("Expected code 220 but got %+v", err) } cconn.PrintfLine("EXIT") wg.Wait() }
// create a new connection from an established connection func newOutboundConn(c net.Conn, s *Server, conf *config.FeedConfig) Conn { sname := s.Name() if len(sname) == 0 { sname = "nntp.anon.tld" } storage := s.Storage if storage == nil { storage = store.NewNullStorage() } return &v1OBConn{ conf: conf, C: v1Conn{ hooks: s, state: ConnState{ FeedName: conf.Name, HostName: conf.Addr, Open: true, }, serverName: sname, storage: storage, C: textproto.NewConn(c), conn: c, hdrio: message.NewHeaderIO(), }, } }
func (s *Server) serve(conn net.Conn) { c := textproto.NewConn(conn) // state controlled processing here for { cr, err := NewCommandRequest(c) if err != nil { log.Println(err) continue } // start of a muxer // s.handler[verb](c) sr := &StatusResponse{} if s.mux == nil { panic("awp: no servemux specified") } s.mux.ServeAWP(cr, sr) c.PrintfLine("%d %s\r\n", sr.Code, sr.Status) } }
// NewTestConnection is for test facilitation. // Creates a server and then dials the server, returning the connection, // allowing test to inject state and wait for an expected response // The connection must be started manually with `go conn.Start()` // once desired state has been injected func NewTestConnection(transcript io.Writer) (s *Server, clientConn *textproto.Conn, serverConn *conn.Conn, server *Server, err error) { mStore := mailstore.NewDummyMailstore() s = NewServer(mStore) s.Addr = ":10143" s.Transcript = transcript if err = s.Listen(); err != nil { return nil, nil, nil, nil, err } c, err := net.Dial("tcp4", "localhost:10143") if err != nil { return nil, nil, nil, nil, err } textc := textproto.NewConn(c) clientConn = textc conn, err := s.listener.Accept() if err != nil { return nil, nil, nil, nil, err } fmt.Fprintf(s.Transcript, "Client connected\n") serverConn, err = s.newConn(conn) return s, clientConn, serverConn, s, nil }
// handle inbound STARTTLS command func upgradeTLS(c *v1Conn, line string, hooks EventHooks) (err error) { if c.tlsConfig == nil { err = c.printfLine("%s TLS not supported", RPL_TLSRejected) } else { err = c.printfLine("%s Continue with TLS Negotiation", RPL_TLSContinue) if err == nil { tconn := tls.Server(c.conn, c.tlsConfig) err = tconn.Handshake() if err == nil { // successful tls handshake c.tlsConn = tconn c.C = textproto.NewConn(c.tlsConn) } else { // tls failed log.WithFields(log.Fields{ "pkg": "nntp-conn", "addr": c.conn.RemoteAddr(), "state": c.state, }).Warn("TLS Handshake failed ", err) // fall back to plaintext err = nil } } } return }
func NewLilyConn(address string) *LilyConn { localAddress, _ := net.ResolveTCPAddr("0.0.0.0:0") lilyAddress, err := net.ResolveTCPAddr(address) if err != nil { logger.Logf("failed resolving %s: %s", address, err) return nil } tcpConn, err := net.DialTCP("tcp", localAddress, lilyAddress) if err != nil { logger.Logf("failed connecting to %s: %s", address, err) return nil } var newLilyConn LilyConn newLilyConn.tcpConn = tcpConn newLilyConn.textConn = textproto.NewConn(tcpConn) newLilyConn.incomingChannel = make(chan *LilyMessage, 100) newLilyConn.outgoingChannel = make(chan *LilyMessage, 100) newLilyConn.handleMap = make(map[string]*LilyHandle) newLilyConn.SendOptions() go newLilyConn.Dispatch() return &newLilyConn }
func newInboundConn(s *Server, c net.Conn) Conn { sname := s.Name if len(sname) == 0 { sname = "nntp.anon.tld" } storage := s.Storage if storage == nil { storage = store.NewNullStorage() } return &v1IBConn{ C: v1Conn{ authenticated: true, serverName: sname, storage: storage, acceptor: s.Acceptor, hdrio: message.NewHeaderIO(), C: textproto.NewConn(c), conn: c, cmds: map[string]lineHandlerFunc{ "IHAVE": nntpRecvArticle, "POST": nntpPostArticle, "MODE": switchModeInbound, "QUIT": quitConnection, "CAPABILITIES": sendCapabilities, "CHECK": streamingLine, "TAKETHIS": streamingLine, "LIST": newsgroupList, "GROUP": switchNewsgroup, }, }, } }
// NewTLS connects with TLS func NewTLS(net, addr string, cfg *tls.Config) (*Conn, error) { c, err := tls.Dial(net, addr, cfg) if err != nil { return nil, err } return newClient(textproto.NewConn(c)) }
func (self *NNTPDaemon) acceptloop() { for { // accept conn, err := self.listener.Accept() if err != nil { log.Fatal(err) } // make a new inbound nntp connection handler hostname := "" if self.conf.crypto != nil { hostname = self.conf.crypto.hostname } nntp := createNNTPConnection(hostname) if self.conf.daemon["anon_nntp"] == "1" { nntp.authenticated = true } addr := conn.RemoteAddr() nntp.name = fmt.Sprintf("%s-inbound-feed", addr.String()) c := textproto.NewConn(conn) // send banners and shit err = nntp.inboundHandshake(c) if err == nil { // run, we support stream and reader go nntp.runConnection(self, true, true, true, false, "stream", conn, nil) } else { log.Println("failed to send banners", err) c.Close() } } }
// NewConn returns a new Conn using nconn for I/O. func NewConn(nconn io.ReadWriteCloser) (conn *Conn, code int, message string, err error) { conn = &Conn{ conn: textproto.NewConn(nconn), } code, message, err = conn.conn.ReadResponse(2) return }
// create a new connection from an established connection func newOutboundConn(c net.Conn) *v1RemoteConn { return &v1RemoteConn{ C: v1Conn{ C: textproto.NewConn(c), conn: c, }, } }
func (s *Server) newSession(conn net.Conn) *session { return &session{ srv: s, conn: textproto.NewConn(conn), raddr: conn.RemoteAddr(), laddr: conn.LocalAddr(), } }
func responder(reply string) (*Conn, *bytes.Buffer) { var wr bytes.Buffer rd := strings.NewReader(reply) rwc := &ReadWriter{rd, &wr} textConn := textproto.NewConn(rwc) c := newConn("<fake>", textConn, nil) return c, &wr }
func Connect(conn io.ReadWriteCloser, bck bucket.Bucket) *Connection { c := new(Connection) c.conn = textproto.NewConn(conn) c.bck = bck c.block1 = c.block1raw[:] c.block2 = c.block2raw[:] return c }
func TestSocketReusePort(t *testing.T) { testName := "TestSocketReusePort" if ok, conn, err := isChildProcess(); ok { // Child process if err != nil { childError(t, conn, err) } addr, err := conn.ReadLine() if err != nil { childError(t, conn, err) } _, err = TuneAndListen("tcp", addr, ReusePort) if err != nil { childError(t, conn, err) } conn.PrintfLine("S") // success conn.ReadLine() // wait for the socket to close os.Exit(0) } // Parent process conns := make([]*textproto.Conn, 5) for i := 0; i < 5; i++ { sConn, _, err := startChildOf(testName) if err != nil { t.Error(err) } conn := textproto.NewConn(sConn) conns[i] = conn defer conn.Close() } tcpAddr, err := findUnusedAddr() if err != nil { t.Error(err) return } // send the children the bind address for _, conn := range conns { conn.PrintfLine(tcpAddr.String()) } // read the status character for _, conn := range conns { if status, err := conn.ReadLine(); err != nil { t.Error(err) } else if status[:1] != "S" { t.Errorf("Unexpected result from child: %s", status) } } }
// NewConn returns a new Conn using conn for I/O. func NewConn(conn io.ReadWriteCloser) *Conn { c := new(Conn) c.c = textproto.NewConn(conn) c.Tube = Tube{c, "default"} c.TubeSet = *NewTubeSet(c, "default") c.used = "default" c.watched = map[string]bool{"default": true} return c }
func (c *starttls) execute(sess *session) *response { sess.conn.Write([]byte(fmt.Sprintf("%s Begin TLS negotiation now", c.tag))) sess.conn = tls.Server(sess.conn, &tls.Config{Certificates: sess.listener.certificates}) textConn := textproto.NewConn(sess.conn) sess.encryption = tlsLevel return empty().replaceBuffers(textConn) }
// StartTLS sends the STARTTLS command and encrypts all further communication. // Only servers that advertise the STARTTLS extension support this function. func (c *Client) StartTLS(config *tls.Config) error { _, _, err := c.cmd(220, "STARTTLS") if err != nil { return err } c.conn = tls.Client(c.conn, config) c.Text = textproto.NewConn(c.conn) c.tls = true return c.ehlo() }
func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) { c = new(conn) c.resetSession() c.remoteAddr = rwc.RemoteAddr().String() c.server = srv c.rwc = rwc c.text = textproto.NewConn(c.rwc) c.tlsState = nil return c, nil }
// NewClient returns a new Client using an existing connection and host as a // server name to be used when authenticating. func NewClient(conn net.Conn, host string) (*Client, error) { text := textproto.NewConn(conn) _, _, err := text.ReadResponse(220) if err != nil { text.Close() return nil, err } c := &Client{Text: text, conn: conn, serverName: host, localName: "localhost"} return c, nil }
func (c *amiServer) do(listener net.Listener) { for { conn, err := listener.Accept() if err != nil { return } fmt.Fprintf(conn, "Asterisk Call Manager\r\n") tconn := textproto.NewConn(conn) //install event HeartBeat go func(conn *textproto.Conn) { for now := range time.Tick(time.Second) { fmt.Fprintf(conn.W, "Event: HeartBeat\r\nTime: %d\r\n\r\n", now.Unix()) } }(tconn) go func(conn *textproto.Conn) { defer conn.Close() for { header, err := conn.ReadMIMEHeader() if err != nil { return } var output bytes.Buffer time.AfterFunc(time.Millisecond*time.Duration(rand.Intn(1000)), func() { if _, ok := c.actionsMocked[header.Get("Action")]; ok { rvals := c.actionsMocked[header.Get("Action")](header) for k, vals := range rvals { fmt.Fprintf(&output, "%s: %s\r\n", k, vals) } output.WriteString("\r\n") err := conn.PrintfLine(output.String()) if err != nil { panic(err) } } else { //default response fmt.Fprintf(&output, "Response: TEST\r\nActionID: %s\r\n\r\n", header.Get("Actionid")) err := conn.PrintfLine(output.String()) if err != nil { panic(err) } } }) } }(tconn) } }
func pipeResponder() (*Conn, *bufio.ReadWriter) { server, client := net.Pipe() textConn := textproto.NewConn(client) c := newConn("<fake>", textConn, nil) r := bufio.NewReader(server) w := bufio.NewWriter(server) rw := bufio.NewReadWriter(r, w) return c, rw }