Example #1
0
func newServerContactReqChan(conn *ricochetConn, msg *packet.OpenChannel) (*contactReqChan, error) {
	ch := new(contactReqChan)
	ch.conn = conn
	ch.chanID = (uint16)(msg.GetChannelIdentifier())
	ch.reqData = new(ContactRequest)

	ext, err := proto.GetExtension(msg, packet.E_ContactRequest)
	if err != nil {
		return nil, err
	}
	if ext == nil {
		return nil, fmt.Errorf("server: missing ContactRequest extension")
	}
	req := ext.(*packet.ContactRequest)
	ch.reqData.Hostname = conn.hostname
	ch.reqData.MyNickname = req.GetNickname()
	if len(ch.reqData.MyNickname) > ContactReqNicknameMaxCharacters {
		return nil, fmt.Errorf("server: ContactRequest nickname too long")
	}
	ch.reqData.Message = req.GetMessageText()
	if len(ch.reqData.Message) > ContactReqMessageMaxCharacters {
		return nil, fmt.Errorf("server: ContactRequest message too long")
	}
	return ch, nil
}
Example #2
0
func newServerChatChan(conn *ricochetConn, msg *packet.OpenChannel) (*chatChan, error) {
	ch := new(chatChan)
	ch.conn = conn
	ch.chanID = (uint16)(msg.GetChannelIdentifier())
	ch.isOutgoing = false

	return ch, nil
}
Example #3
0
func newServerAuthHSChan(conn *ricochetConn, msg *packet.OpenChannel) (*authHSChan, error) {
	ch := new(authHSChan)
	ch.conn = conn
	ch.chanID = (uint16)(msg.GetChannelIdentifier())

	ext, err := proto.GetExtension(msg, packet.E_ClientCookie)
	if err != nil {
		return nil, err
	}
	ch.clientCookie = ext.([]byte)
	if len(ch.clientCookie) != authHiddenServiceCookieSize {
		return nil, fmt.Errorf("invalid AuthHiddenService client_cookie")
	}
	return ch, nil
}
Example #4
0
func (ch *controlChan) onOpenChannelMsg(msg *packet.OpenChannel) error {
	log := ch.conn.endpoint.log
	chanType := msg.GetChannelType()
	rawChanID := msg.GetChannelIdentifier()
	if rawChanID <= 0 || rawChanID >= math.MaxUint16 {
		return fmt.Errorf("attempted to open invalid channel ID: %v", rawChanID)
	}
	chanID := (uint16)(rawChanID) // So f*****g stupid.
	if ch.conn.isServer && (chanID&1 == 0) {
		return fmt.Errorf("client attempted to open even channel ID: %v", chanID)
	}
	if !ch.conn.isServer && (chanID&1 == 1) {
		return fmt.Errorf("server attempted to open odd channel ID: %v", chanID)
	}
	if ch.conn.chanMap[chanID] != nil {
		return fmt.Errorf("attempted to open duplicate channel ID: %v", chanID)
	}

	log.Printf("chan open attempt: %v (%d)", chanType, chanID)

	var newCh ricochetChan
	var err error
	switch chanType {
	case authHiddenServiceChannelType:
		if !ch.conn.isServer {
			return fmt.Errorf("attempted to open auth channel to client")
		}
		if ch.isAuthenticated {
			return fmt.Errorf("attempted to open auth channel when authed")
		}
		if ch.authChan != invalidChanID {
			return fmt.Errorf("attempted to open auth channel when one exists")
		}
		if newCh, err = newServerAuthHSChan(ch.conn, msg); err != nil {
			return err
		}
		ch.authChan = (int)(chanID)
	case contactReqChannelType:
		if !ch.conn.isServer {
			return fmt.Errorf("attempted to open contact req channel to client")
		}
		if !ch.isAuthenticated {
			return fmt.Errorf("attempted to open contact req channel pre-auth")
		}
		if ch.contactReqChan != invalidChanID {
			return fmt.Errorf("attempted to open contact req channel when one exists")
		}
		if newCh, err = newServerContactReqChan(ch.conn, msg); err != nil {
			return err
		}
		ch.contactReqChan = (int)(chanID)
	case chatChannelType:
		if !ch.isAuthenticated {
			return fmt.Errorf("attempted to open chat channel pre-auth")
		}
		if ch.incomingChatChan != invalidChanID {
			return fmt.Errorf("attempted to open chat channel when one exists")
		}
		if newCh, err = newServerChatChan(ch.conn, msg); err != nil {
			return err
		}
		ch.incomingChatChan = (int)(chanID)
	default:
		return fmt.Errorf("attempted to open unknown channel type")
	}

	// Send the response and add the channel to the global channel map.
	//
	// Note: The code will opt to tear down the connection instead of sending
	// any sort of failure response.  Rather rude, but that's arguably correct
	// behavior for most responses anyway.
	if newCh != nil && err == nil {
		if err = newCh.onOpenChannel(); err != nil {
			return err
		}

		ch.conn.Lock()
		defer ch.conn.Unlock()
		ch.conn.chanMap[chanID] = newCh
	}
	return err
}