Example #1
0
func (c *chatSyncClient) processChat(resp *imap.Response) {
	msgInfo := resp.MessageInfo()
	message := c.getMessage(msgInfo.Seq)

	headerBytes := msgInfo.Attrs["RFC822.HEADER"]
	headers := imap.AsBytes(headerBytes)
	message.headers, _ = mail.ReadMessage(bytes.NewReader(headers))

	bodyBytes := msgInfo.Attrs["BODY[TEXT]"]
	body := imap.AsBytes(bodyBytes)
	message.body, _ = mail.ReadMessage(bytes.NewReader(body))

	err := message.process()
	checkError(err)

	c.done <- message.seq
}
Example #2
0
// checkAndPurge will pull message message ids off of requests and do some work
func purgeDestination(user string, dsts []*imap.Client, checkRequests chan checkExistsRequest, wg *sync.WaitGroup) {
	defer wg.Done()

	cmd, err := GetAllMessages(dsts[0])
	if err != nil {
		log.Printf("Unable to find destination messages: %s", err.Error())
	}

	workRequests := make(chan WorkRequest)

	// launch purgers
	var purgers sync.WaitGroup
	for _, dstConn := range dsts {
		purgers.Add(1)
		go checkAndPurgeMessages(dstConn, workRequests, checkRequests, &purgers)
	}

	// build the requests and send them
	var rsp *imap.Response
	var indx int
	startTime := time.Now()
	log.Printf("Beginning check/purge for %s with %d messages", user, len(cmd.Data))
	for indx, rsp = range cmd.Data {
		header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
		if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
			header := "Message-Id"
			value := msg.Header.Get(header)

			// create the store request and pass it to each dst's storers
			workRequests <- WorkRequest{Value: value, Header: header, UID: rsp.MessageInfo().UID}

			if ((indx % 100) == 0) && (indx > 0) {
				since := time.Since(startTime)
				rate := 100 / since.Seconds()
				startTime = time.Now()
				log.Printf("Processed %d messages from %s. Rate: %f msg/s", indx, user, rate)
			}
		}
	}
	log.Printf("Done passing purge requests for %s", user)
	close(workRequests)
	purgers.Wait()

	return
}
Example #3
0
func connectNet(user string) {
	netTimeout := time.Second * 30
	cl, err := imap.DialTLS("imap.gmail.com", nil)
	if err != nil {
		log.Println(err)
		time.Sleep(netTimeout)
		return
	}
	defer cl.Logout(-1)
	log.Println("server says hello:", cl.Data[0].Info)
	cl.Data = nil
	log.Println("logging in")
	if cl.State() == imap.Login {
		_, err = cl.Login(user+"@gmail.com", "PASSHERE")
		if err != nil {
			log.Println(err)
			time.Sleep(netTimeout)
			return
		}
	}
	log.Println("logged in")
	log.Println("selecting INBOX")
	_, err = cl.Select("INBOX", false)
	if err != nil {
		log.Println(err)
		time.Sleep(netTimeout)
		return
	}
	log.Println("selected INBOX")
	set, _ := imap.NewSeqSet("")
searchLoop:
	for {
		var successCounter int
		conTimeout := 5
		log.Println("searching INBOX")
		cmd, err := imap.Wait(cl.Search("SUBJECT \"Confirm your email\""))
		if err != nil {
			log.Println(err)
			break searchLoop
		}
		searchResults := cmd.Data[0].SearchResults()
		if searchResults == nil {
			log.Println("no email[s] found")
			time.Sleep(time.Second * 5)
			break searchLoop
		} else {
			log.Println("found", len(searchResults), "emails to spoof, results:", searchResults)
			set.AddNum(searchResults...)
		}
		var rsp *imap.Response
		link := regexp.MustCompile(`https:=\r\n\/\/invites.oneplus.net\/confirm\/[0-9A-Z]*.`)
		var UIDCounter int
		log.Println("beginning spoof confirmation loop")
		cmd, err = cl.Fetch(set, "RFC822")
		if err != nil {
			log.Println(err)
			break searchLoop
		}
		setDone, _ := imap.NewSeqSet("")
	getMailLoop:
		for cmd.InProgress() {
			cl.Recv(-1)
			for _, rsp = range cmd.Data {
				message := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822"])
				if msg, err := mail.ReadMessage(bytes.NewReader(message)); msg != nil {
					log.Println("current conTimeout", conTimeout)
					body, err := ioutil.ReadAll(msg.Body)
					if err != nil {
						log.Println(err)
						break searchLoop
					}
					linkRawM := link.FindSubmatch(body)
					var linkRaw []byte
					if len(linkRawM) > 0 {
						linkRaw = linkRawM[0]
					} else {
						log.Println("found nolink mail")
						continue getMailLoop
					}
					log.Println(string(linkRaw))
					url, err := url.Parse(string(linkRaw[:6]) + string(linkRaw[9:]))
					if err != nil {
						log.Println(err)
						break searchLoop
					}
					log.Println(url)
					req := confirmURL.ReplaceAll(reqTemplate, []byte(url.Path)[:len(url.Path)-1])
					for {
						log.Println("attempting to spoof confirmation for", searchResults[UIDCounter])
						c, err := tls.Dial("tcp", url.Host+":443", nil)
						if err != nil {
							log.Println(err)
							break searchLoop
						}
						_, err = c.Write(req)
						if err != nil {
							log.Println(err)
							break searchLoop
						}
						resp, err := http.ReadResponse(bufio.NewReader(c), nil)
						if err != nil {
							log.Println(err)
							break searchLoop
						}
						if resp.StatusCode == 302 {
							redirectReg := regexp.MustCompile(`https:\/\/oneplus\.net\/invites\?kid=[0-9A-Z]*`)
							redirectURL, err := resp.Location()
							if err != nil {
								log.Println(err)
								break searchLoop
							}
							log.Println(resp.Location())
							if redirectReg.MatchString(redirectURL.String()) {
								log.Println("successfully spoofed confirmation for", searchResults[UIDCounter])
								setDone.AddNum(searchResults[UIDCounter])
								UIDCounter++
								if successCounter == 10 {
									conTimeout--
									successCounter = 0
								}
								break
							} else {
								log.Println("server trying to migitate spoofing")
								conTimeout++
								successCounter = 0
							}
						} else {
							log.Println("gg rip hamsters")
							conTimeout++
							successCounter = 0
						}
						time.Sleep(time.Second * time.Duration(conTimeout))
					}
				} else {
					log.Println(err)
				}
			}
			time.Sleep(time.Second * time.Duration(conTimeout))
			cmd.Data = nil
		}
		log.Println("deleting mail", setDone)
		_, err = imap.Wait(cl.Store(setDone, "+FLAGS", "\\DELETED"))
		if err != nil {
			log.Println(err)
			break searchLoop
		}
		_, err = imap.Wait(cl.Expunge(nil))
		if err != nil {
			log.Println(err)
			break searchLoop
		}
	}
}
Example #4
0
// SearchAndStore will check check if each message in the source inbox
// exists in the destinations. If it doesn't exist in a destination, the message info will
// be pulled and stored into the destination.
func SearchAndStore(src []*imap.Client, dsts map[string][]*imap.Client, dbFile string, quickSyncCount int) (err error) {
	var cmd *imap.Command
	cmd, err = GetAllMessages(src[0])
	if err != nil {
		log.Printf("Unable to get all messages!")
		return
	}

	// connect to cache
	cache, err := NewCache(dbFile)
	if err != nil {
		log.Printf("problems initiating cache - %s", err.Error())
		return
	}
	defer cache.Close()

	// setup message fetchers to pull from the source/memcache
	fetchRequests := make(chan fetchRequest)
	for _, srcConn := range src {
		go fetchEmails(srcConn, fetchRequests, cache)
	}

	var appendRequests []chan WorkRequest
	var storers sync.WaitGroup
	// setup storers for each destination
	for _, dst := range dsts {
		storeRequests := make(chan WorkRequest)
		for _, dstConn := range dst {
			storers.Add(1)
			go CheckAndAppendMessages(dstConn, storeRequests, fetchRequests, &storers)
		}
		appendRequests = append(appendRequests, storeRequests)
	}

	// build the requests and send them
	log.Printf("store processing for %d messages from the source inbox", len(cmd.Data))
	var rsp *imap.Response
	var indx int
	startTime := time.Now()
	syncStart := 0
	// consider quick sync
	if quickSyncCount != 0 {
		syncStart = len(cmd.Data) - quickSyncCount
		log.Printf("found quick sync count. will only sync messages %d through %d", syncStart, len(cmd.Data))
	}
	for indx, rsp = range cmd.Data[syncStart:] {
		header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
		if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
			header := "Message-Id"
			value := msg.Header.Get(header)

			// create the store request and pass it to each dst's storers
			storeRequest := WorkRequest{Value: value, Header: header, UID: rsp.MessageInfo().UID}
			for _, storeRequests := range appendRequests {
				storeRequests <- storeRequest
			}

			if ((indx % 100) == 0) && (indx > 0) {
				since := time.Since(startTime)
				rate := 100 / since.Seconds()
				startTime = time.Now()
				log.Printf("Completed store processing for %d messages from the source inbox. Rate: %f msg/s", indx, rate)
			}
		}
	}

	// after everything is on the channel, close them...
	for _, storeRequests := range appendRequests {
		close(storeRequests)
	}
	// ... and wait for our workers to finish up.
	storers.Wait()

	// once the storers are complete we can close the fetch channel
	close(fetchRequests)

	log.Printf("search and store processes complete")
	return nil
}
Example #5
0
func ExampleClient() {
	//
	// Note: most of error handling code is omitted for brevity
	//
	var (
		c   *imap.Client
		cmd *imap.Command
		rsp *imap.Response
	)

	// Connect to the server
	c, _ = imap.Dial("imap.example.com")

	// Remember to log out and close the connection when finished
	defer c.Logout(30 * time.Second)

	// Print server greeting (first response in the unilateral server data queue)
	fmt.Println("Server says hello:", c.Data[0].Info)
	c.Data = nil

	// Enable encryption, if supported by the server
	if c.Caps["STARTTLS"] {
		c.StartTLS(nil)
	}

	// Authenticate
	if c.State() == imap.Login {
		c.Login("user@example.com", "mysupersecretpassword")
	}

	// List all top-level mailboxes, wait for the command to finish
	cmd, _ = imap.Wait(c.List("", "%"))

	// Print mailbox information
	fmt.Println("\nTop-level mailboxes:")
	for _, rsp = range cmd.Data {
		fmt.Println("|--", rsp.MailboxInfo())
	}

	// Check for new unilateral server data responses
	for _, rsp = range c.Data {
		fmt.Println("Server data:", rsp)
	}
	c.Data = nil

	// Open a mailbox (synchronous command - no need for imap.Wait)
	c.Select("INBOX", true)
	fmt.Print("\nMailbox status:\n", c.Mailbox)

	// Fetch the headers of the 10 most recent messages
	set, _ := imap.NewSeqSet("")
	if c.Mailbox.Messages >= 10 {
		set.AddRange(c.Mailbox.Messages-9, c.Mailbox.Messages)
	} else {
		set.Add("1:*")
	}
	cmd, _ = c.Fetch(set, "RFC822.HEADER")

	// Process responses while the command is running
	fmt.Println("\nMost recent messages:")
	for cmd.InProgress() {
		// Wait for the next response (no timeout)
		c.Recv(-1)

		// Process command data
		for _, rsp = range cmd.Data {
			header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
			if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
				fmt.Println("|--", msg.Header.Get("Subject"))
			}
		}
		cmd.Data = nil

		// Process unilateral server data
		for _, rsp = range c.Data {
			fmt.Println("Server data:", rsp)
		}
		c.Data = nil
	}

	// Check command completion status
	if rsp, err := cmd.Result(imap.OK); err != nil {
		if err == imap.ErrAborted {
			fmt.Println("Fetch command aborted")
		} else {
			fmt.Println("Fetch error:", rsp.Info)
		}
	}
}