コード例 #1
0
ファイル: imap.go プロジェクト: htr/imapfeeder
func (i *ImapSession) imapCleanup(folders []string) error {

	c := i.client

	for _, mbox := range folders {
		cmd, err := imap.Wait(c.Select(mbox, false))
		if err != nil {
			fmt.Println("unable to select", mbox, "=>", err, i.client.State())
			continue
		}
		fmt.Println("cleaning up", mbox)
		yesterday := time.Now().Add(-1 * 24 * time.Hour)

		cmd = imapMust(imap.Wait(c.UIDSearch("SEEN BEFORE " + yesterday.Format("02-Jan-2006") + " NOT FLAGGED")))

		toDelete, _ := imap.NewSeqSet("")
		toDelete.AddNum(cmd.Data[0].SearchResults()...)
		if !toDelete.Empty() {
			fmt.Println("deleting...", toDelete)
			if i.isGmail {
				imapMust(imap.Wait(c.UIDStore(toDelete, "X-GM-LABELS", imap.NewFlagSet(`\Trash`))))
			} else {
				imapMust(imap.Wait(c.UIDStore(toDelete, "+FLAGS.SILENT", imap.NewFlagSet(`\Deleted`))))
			}
			imapMust(imap.Wait(c.Expunge(nil)))
		}
	}

	return nil
}
コード例 #2
0
ファイル: imap.go プロジェクト: pruthvirajsinh/go-Simap
func FetchAllUIDs(c *imap.Client) (uids []uint32, err error) {
	maxmessages := 150000
	uids = make([]uint32, maxmessages)

	set, errS := imap.NewSeqSet("1:*")
	if errS != nil {
		err = errS
		return
	}

	cmd, errF := c.UIDFetch(set, "RFC822.SIZE")
	if errF != nil {
		err = errF
		return
	}

	messagenum := uint32(0)
	for cmd.InProgress() {
		errC := c.Recv(-1)
		if errC != nil {
			continue
		}
		for _, rsp := range cmd.Data {
			uid := imap.AsNumber(rsp.MessageInfo().Attrs["UID"])
			uids[messagenum] = uid
		}
		cmd.Data = nil
		messagenum++
	}

	uids = uids[:messagenum]
	return
}
コード例 #3
0
ファイル: copycat.go プロジェクト: jprobinson/copycat-imap
func GetAllMessages(conn *imap.Client) (*imap.Command, error) {
	// get headers and UID for ALL message in src inbox...
	allMsgs, _ := imap.NewSeqSet("")
	allMsgs.Add("1:*")
	cmd, err := imap.Wait(conn.Fetch(allMsgs, "RFC822.HEADER", "UID"))
	if err != nil {
		return &imap.Command{}, err
	}

	return cmd, nil
}
コード例 #4
0
ファイル: mailbox.go プロジェクト: sampsyo/madmin
// Retrieve metadata for all messages in a given mailbox.
func (conn *Connection) Messages(box string, count uint32) ([]*MessageMeta,
	error) {
	conn.client.Select(box, true)

	// Create a range set that selects the most recent `count` messages (or
	// all messages if the mailbox contains fewer than that). Also, allocate a
	// slice for the results.
	set, _ := imap.NewSeqSet("")
	var messages []*MessageMeta
	totalCount := conn.client.Mailbox.Messages
	if totalCount >= count {
		set.AddRange(totalCount-(count-1), totalCount)
		messages = make([]*MessageMeta, count)
	} else {
		set.Add("1:*")
		messages = make([]*MessageMeta, totalCount)
	}

	// Fetch messages.
	cmd, err := conn.client.Fetch(set, "RFC822.HEADER RFC822.SIZE UID")
	if err != nil {
		return nil, err
	}

	// Parse each message.
	i := 0
	for cmd.InProgress() {
		err = conn.client.Recv(time.Second * 5)
		if err != nil {
			return nil, err
		}

		// Process the message data received so far.
		for _, rsp := range cmd.Data {
			msgInfo := rsp.MessageInfo()
			header := imap.AsBytes(msgInfo.Attrs["RFC822.HEADER"])
			msg, err := mail.ReadMessage(bytes.NewReader(header))
			if err != nil {
				return nil, err
			}

			messages[i] = &MessageMeta{
				UID:     msgInfo.UID,
				Size:    msgInfo.Size,
				Subject: msg.Header.Get("Subject"),
			}
			i++
		}
		cmd.Data = nil
	}

	return messages, nil
}
コード例 #5
0
ファイル: mailbox.go プロジェクト: justjake/mail
// Issue a FETCH request for this message
// TODO make private, this is an abstraction-breaker
func (m *Email) RetrieveRaw(requestType string) (cmd *imap.Command, err error) {
	c, err := m.server.Connect()
	if err != nil {
		return
	}

	// fetch message by UID
	set, err := imap.NewSeqSet(fmt.Sprintf("%d", m.UID))
	if err != nil {
		return
	}
	cmd, err = c.UIDFetch(set, requestType)
	return cmd, err
}
コード例 #6
0
ファイル: mailbox.go プロジェクト: daffodil/go-mailkit
func GetLastUIDs(alluids []uint32) *imap.SeqSet {
	//payload.Uids, err = GetUIDs("INBOX", client)

	//= Calc last few messages
	lenny := len(alluids)
	last := lenny - 50 // ################
	if last < 0 {
		last = 0
	}
	//= Make List of messages uids
	uidlist, _ := imap.NewSeqSet("")
	for _, uid := range alluids[last:lenny] {
		uidlist.AddNum(uid)
	}
	return uidlist
}
コード例 #7
0
ファイル: imap.go プロジェクト: sqs/go-synco
func PrintMail(acct *IMAPAccount, query string) {
	imap.DefaultLogger = log.New(os.Stdout, "", 0)
	//	imap.DefaultLogMask = imap.LogConn | imap.LogRaw

	log.Printf("Running for user '%s' on IMAP server '%s:%d'", acct.Username, acct.Server.Host, acct.Server.Port)

	jobsize := 250

	// Fetch UIDs.
	c := Dial(acct.Server)
	login(c, acct.Username, acct.Password)
	c.Select(mbox, true)
	uids, _ := SearchUIDs(c, query)

	timestarted := time.Now()

	nparts := (len(uids) + jobsize - 1) / jobsize
	jobs := make([]*imap.SeqSet, nparts)
	for i := 0; i < nparts; i++ {
		lo := i * jobsize
		hi_exclusive := (i + 1) * jobsize
		if hi_exclusive >= len(uids) {
			hi_exclusive = len(uids) - 1
			for uids[hi_exclusive] == 0 { // hacky
				hi_exclusive--
			}
		}
		set, _ := imap.NewSeqSet("")
		set.AddNum(uids[lo:hi_exclusive]...)
		jobs[i] = set
	}

	log.Printf("%d UIDs total, %d jobs of size <= %d\n", len(uids), len(jobs), jobsize)

	for _, jobUIDs := range jobs {
		FetchMessages(c, jobUIDs)
	}

	timeelapsed := time.Since(timestarted)
	msecpermessage := timeelapsed.Seconds() / float64(len(uids)) * 1000
	messagespersec := float64(len(uids)) / timeelapsed.Seconds()
	log.Printf("Finished fetching %d messages in %.2fs (%.1fms per message; %.1f messages per second)\n", len(uids), timeelapsed.Seconds(), msecpermessage, messagespersec)

	c.Close(false)
	c.Logout(-1)
}
コード例 #8
0
ファイル: copycat.go プロジェクト: jprobinson/copycat-imap
func FetchMessage(conn *imap.Client, messageUID uint32) (msg MessageData, err error) {
	seq, _ := imap.NewSeqSet("")
	seq.AddNum(messageUID)
	var cmd *imap.Command
	cmd, err = imap.Wait(conn.UIDFetch(seq, "INTERNALDATE", "BODY[]", "UID", "RFC822.HEADER"))
	if err != nil {
		log.Printf("Unable to fetch message (%d): %s", messageUID, err.Error())
		return
	}

	if len(cmd.Data) == 0 {
		log.Printf("Unable to fetch message (%d) from src: NO DATA", messageUID)
		return msg, NotFound
	}

	msgFields := cmd.Data[0].MessageInfo().Attrs
	msg = MessageData{InternalDate: imap.AsDateTime(msgFields["INTERNALDATE"]), Body: imap.AsBytes(msgFields["BODY[]"])}
	return msg, nil
}
コード例 #9
0
ファイル: purge.go プロジェクト: jprobinson/copycat-imap
func checkAndPurgeMessages(conn *imap.Client, requests chan WorkRequest, checkRequests chan checkExistsRequest, wg *sync.WaitGroup) {
	defer wg.Done()

	timeout := time.NewTicker(NoopMinutes * time.Minute)
	done := false
	for {
		select {
		case request, ok := <-requests:
			if !ok {
				done = true
				break
			}
			// check and wait for response
			response := make(chan bool)
			cr := checkExistsRequest{UID: request.UID, MessageId: request.Value, Response: response}
			checkRequests <- cr

			// if response is false (does not exist), flag as Deleted
			if exists := <-response; !exists {
				log.Printf("not found in src. marking for deletion: %s", request.Value)
				err := AddDeletedFlag(conn, request.UID)
				if err != nil {
					log.Printf("Problems removing message from dst: %s", err.Error())
				}
			}
		case <-timeout.C:
			imap.Wait(conn.Noop())
		}

		if done {
			break
		}
	}

	log.Printf("expunging...")
	// expunge at the end
	allMsgs, _ := imap.NewSeqSet("")
	allMsgs.Add("1:*")
	imap.Wait(conn.Expunge(allMsgs))
	log.Printf("expunge complete.")
}
コード例 #10
0
ファイル: logsync.go プロジェクト: mithaler/imapsync
func (c *chatSyncClient) syncChats() error {
	log.Print("Starting sync...")

	// Create SeqSet specifying all messages
	set, err := imap.NewSeqSet("10:20")
	checkError(err)

	// Fetch all messages
	cmd, err := c.client.Fetch(set, "RFC822.HEADER", "BODY[TEXT]")
	checkError(err)

	for cmd.InProgress() {
		c.client.Recv(-1)

		for _, resp := range cmd.Data {
			go c.processChat(resp)
		}

		cmd.Data = nil
	}

	for {
		completed := <-c.done
		delete(c.messages, completed)

		allDone := true
		for k, _ := range c.messages {
			if !c.messages[k].done {
				allDone = false
				break
			}
		}
		if allDone {
			break
		}
	}

	log.Print("Processed all chats!")
	return nil
}
コード例 #11
0
ファイル: imap.go プロジェクト: htr/imapfeeder
func (i *ImapSession) Append(folder string, extraCopies []string, msg io.Reader) error {
	c := i.client

	mbox := folder

	buf := new(bytes.Buffer)
	buf.ReadFrom(msg)

	now := time.Now()
	cmd, err := imap.Wait(c.Append(mbox, nil, &now, imap.NewLiteral(buf.Bytes())))
	if err != nil {
		fmt.Println(err)
		return err
	}

	rsp, err := cmd.Result(imap.OK)
	if err != nil {
		fmt.Println(err)
		return err
	}

	uid := imap.AsNumber(rsp.Fields[len(rsp.Fields)-1])

	set, _ := imap.NewSeqSet("")
	set.AddNum(uid)

	imapMust(imap.Wait(c.Select(mbox, false)))

	for _, mb := range extraCopies {
		if i.isGmail {
			imapMust(imap.Wait(c.UIDStore(set, "X-GM-LABELS", imap.NewFlagSet(mb))))
		} else {
			imapMust(c.UIDCopy(set, mb))
		}
	}

	return nil
}
コード例 #12
0
ファイル: imap.go プロジェクト: pruthvirajsinh/go-Simap
//GetEmails gets Emails from mailbox mbox in Struct of Type MsgData.
//It searches the mailbox for messages that match the given searching criteria mentioned in query string.
//See RFC 3501 section 6.4.4 for a list of all valid search keys.
//It is the caller's responsibility to quote strings when necessary.
//All strings must use UTF-8 encoding.
func GetEMails(acct *IMAPAccount, query string, mbox string, jobSize int, skipCerti bool) (mails []MsgData, err error) {
	imap.DefaultLogger = log.New(os.Stdout, "", 0)
	//	imap.DefaultLogMask = imap.LogConn | imap.LogRaw

	log.Printf("Running for user '%s' on IMAP server '%s:%d'", acct.Username, acct.Server.Host, acct.Server.Port)

	if jobSize <= 0 {
		jobSize = 10
	}

	// Fetch UIDs.
	c, errD := Dial(acct.Server, skipCerti)
	if errD != nil {
		err = errD
		return
	}
	_, err = login(c, acct.Username, acct.Password)
	if err != nil {
		return
	}
	defer c.Logout(-1)
	if mbox == "" {
		mbox = "inbox"
	}
	err = WaitResp(c.Select(mbox, true))
	if err != nil {
		return
	}
	uids, err1 := SearchUIDs(c, query)
	if err1 != nil {
		err = err1
		return
	}

	timestarted := time.Now()

	var jobs []*imap.SeqSet

	var jUids []uint32
	for i := 0; i < len(uids); i++ {
		/*Logic
		1.If we are at last index len(uids)-1 and still have not reached jobSize limit then append that to jobs
			(In other words if set size is smaller then jobsize)
		2.if we go over index of size greater then jobsize then add all elemetns up to that index in to jobs
		3.0 mod n returns 0 hence i!=0 is checked

		*/
		if i%(jobSize) == 0 && i != 0 { //Append the new job to jobs
			set, _ := imap.NewSeqSet("")
			set.AddNum(jUids[:]...)
			jobs = append(jobs, set)
			jUids = nil
		}
		jUids = append(jUids, uids[i])
		if i == len(uids)-1 { //Last Element Encountered Add to jobs
			set, _ := imap.NewSeqSet("")
			set.AddNum(jUids[:]...)
			jobs = append(jobs, set)
			jUids = nil
		}
	}

	log.Printf("%d UIDs total, %d jobs of size <= %d\n", len(uids), len(jobs), jobSize)

	for _, jobUIDs := range jobs {
		fetched, errF := FetchMessages(c, jobUIDs)
		if errF != nil {
			log.Println("error while fetching ", jobUIDs, " ", err)
			continue
		}
		for _, msg := range fetched {
			mails = append(mails, msg)
		}
	}

	timeelapsed := time.Since(timestarted)
	msecpermessage := timeelapsed.Seconds() / float64(len(uids)) * 1000
	messagespersec := float64(len(uids)) / timeelapsed.Seconds()
	log.Printf("Finished fetching %d messages in %.2fs (%.1fms per message; %.1f messages per second)\n", len(uids), timeelapsed.Seconds(), msecpermessage, messagespersec)

	err = WaitResp(c.Close(false))
	return
}
コード例 #13
0
ファイル: imap.go プロジェクト: pruthvirajsinh/go-Simap
//UnmarkEmails unmarks/resets flags of mails having uids from src with IMAP flag specified in imapFlag.
//See RFC 3501 section 2.3.2 for a list of all valid flags.
func UnMarkEmails(acct *IMAPAccount, src string, imapFlag string, uids []uint32, jobSize int, skipCerti bool) (err error) {

	imap.DefaultLogger = log.New(os.Stdout, "", 0)
	//	imap.DefaultLogMask = imap.LogConn | imap.LogRaw

	log.Printf("Starting UnMarking for user '%s' on IMAP server '%s:%d'", acct.Username, acct.Server.Host, acct.Server.Port)

	if jobSize <= 0 {
		jobSize = 10
	}

	c, errD := Dial(acct.Server, skipCerti)
	if errD != nil {
		err = errD
		return
	}
	_, err = login(c, acct.Username, acct.Password)
	if err != nil {
		return
	}

	defer c.Logout(-1)

	if src == "" {
		err = errors.New("No source provided")
		return
	}

	err = WaitResp(c.Select(src, false))
	if err != nil {
		return
	}

	timestarted := time.Now()

	var jobs []*imap.SeqSet

	var jUids []uint32
	for i := 0; i < len(uids); i++ {

		if i%(jobSize) == 0 && i != 0 { //Append the new job to jobs
			set, _ := imap.NewSeqSet("")
			set.AddNum(jUids[:]...)
			jobs = append(jobs, set)
			jUids = nil
		}
		jUids = append(jUids, uids[i])
		if i == len(uids)-1 { //Last Element Encountered Add to jobs
			set, _ := imap.NewSeqSet("")
			set.AddNum(jUids[:]...)
			jobs = append(jobs, set)
			jUids = nil
		}
	}

	log.Printf("UnMarking: %d UIDs with %s total, %d jobs of size <= %d from %s\n", len(uids), imapFlag, len(jobs), jobSize, src)

	for _, jobUIDs := range jobs {
		log.Println("UnMarking ", jobUIDs)

		err = WaitResp(c.UIDStore(jobUIDs, "-FLAGS.SILENT", imap.NewFlagSet(imapFlag)))
		if err != nil {
			log.Println(err)
			continue
		}

	}
	err = WaitResp(c.Close(false))
	if err != nil {
		log.Println("Error While Closing ", err)
		return
	}
	timeelapsed := time.Since(timestarted)
	msecpermessage := timeelapsed.Seconds() / float64(len(uids)) * 1000
	messagespersec := float64(len(uids)) / timeelapsed.Seconds()
	log.Printf("Finished UnMarking %d messages in %.2fs (%.1fms per message; %.1f messages per second)\n", len(uids), timeelapsed.Seconds(), msecpermessage, messagespersec)

	return

}
コード例 #14
0
ファイル: imap.go プロジェクト: pruthvirajsinh/go-Simap
//CopyEmails copies Emails having unique identifiers uids (NOT sequence numbers) of mailbox src
//to mailbox dst by making bunches of jobsize.
//If dst mbox doesnt exist then it will create it.
//IF skipCerti is true then it will not check for the validity of the Certificate of the IMAP server,
//good only if IMAP server is using self signed certi.
//e.g. if jobsize =10 and total emails =100 then it will create 10 bunches of size 10 and then copy them.
func CopyEmails(acct *IMAPAccount, src string, dst string, uids []uint32, jobSize int, skipCerti bool) (err error) {

	imap.DefaultLogger = log.New(os.Stdout, "", 0)
	//	imap.DefaultLogMask = imap.LogConn | imap.LogRaw

	log.Printf("Starting Copying for user '%s' on IMAP server '%s:%d'", acct.Username, acct.Server.Host, acct.Server.Port)

	if jobSize <= 0 {
		jobSize = 10
	}

	// Fetch UIDs.
	c, errD := Dial(acct.Server, skipCerti)
	if errD != nil {
		err = errD
		return
	}
	_, err = login(c, acct.Username, acct.Password)
	if err != nil {
		return
	}

	defer c.Logout(-1)

	if src == "" {
		err = errors.New("No source provided")
		return
	}
	if dst == "" {
		err = errors.New("No Dst provided")
		return
	}

	//PRC Dest MBOX CHeck Start
	err = WaitResp(c.Select(dst, false))
	if err != nil { //Doesnt Exist->Create
		err = WaitResp(c.Create(dst))
		if err != nil {
			return
		}
		err = WaitResp(c.Select(dst, false))
	}
	err = WaitResp(c.Close(false))
	if err != nil {
		return
	}
	//PRC Dest MBOX Check End

	err = WaitResp(c.Select(src, true))
	if err != nil {
		return
	}

	timestarted := time.Now()

	var jobs []*imap.SeqSet

	var jUids []uint32
	for i := 0; i < len(uids); i++ {
		/*Logic
		1.If we are at last index len(uids)-1 and still have not reached jobSize limit then append that to jobs
			(In other words if set size is smaller then jobsize)
		2.if we go over index of size greater then jobsize then add all elemetns up to that index in to jobs
		3.0 mod n returns 0 hence i!=0 is checked

		*/
		if i%(jobSize) == 0 && i != 0 { //Append the new job to jobs
			set, _ := imap.NewSeqSet("")
			set.AddNum(jUids[:]...)
			jobs = append(jobs, set)
			jUids = nil
		}
		jUids = append(jUids, uids[i])
		if i == len(uids)-1 { //Last Element Encountered Add to jobs
			set, _ := imap.NewSeqSet("")
			set.AddNum(jUids[:]...)
			jobs = append(jobs, set)
			jUids = nil
		}
	}

	log.Printf("Copying: %d UIDs total, %d jobs of size <= %d to %s\n", len(uids), len(jobs), jobSize, dst)

	for _, jobUIDs := range jobs {
		log.Println("Copying ", jobUIDs)
		err1 := WaitResp(c.UIDCopy(jobUIDs, dst))
		if err1 != nil {
			log.Println(err)
			continue
		}

	}
	err = WaitResp(c.Close(false))
	timeelapsed := time.Since(timestarted)
	msecpermessage := timeelapsed.Seconds() / float64(len(uids)) * 1000
	messagespersec := float64(len(uids)) / timeelapsed.Seconds()
	log.Printf("Finished copying %d messages in %.2fs (%.1fms per message; %.1f messages per second)\n", len(uids), timeelapsed.Seconds(), msecpermessage, messagespersec)

	return

}
コード例 #15
0
ファイル: example_test.go プロジェクト: kaihendry/go-imap
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("*****@*****.**", "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)
		}
	}
}
コード例 #16
0
ファイル: main.go プロジェクト: nhooyr/OnePlusReferrer
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
		}
	}
}
コード例 #17
0
ファイル: demo1.go プロジェクト: kaihendry/go-imap
func main() {
	imap.DefaultLogger = log.New(os.Stdout, "", 0)
	imap.DefaultLogMask = imap.LogConn | imap.LogRaw

	c := Dial(Addr)
	defer func() { ReportOK(c.Logout(30 * time.Second)) }()

	if c.Caps["STARTTLS"] {
		ReportOK(c.StartTLS(nil))
	}

	if c.Caps["ID"] {
		ReportOK(c.ID("name", "goimap"))
	}

	ReportOK(c.Noop())
	ReportOK(Login(c, User, Pass))

	if c.Caps["QUOTA"] {
		ReportOK(c.GetQuotaRoot("INBOX"))
	}

	cmd := ReportOK(c.List("", ""))
	delim := cmd.Data[0].MailboxInfo().Delim

	mbox := MBox + delim + "Demo1"
	if cmd, err := imap.Wait(c.Create(mbox)); err != nil {
		if rsp, ok := err.(imap.ResponseError); ok && rsp.Status == imap.NO {
			ReportOK(c.Delete(mbox))
		}
		ReportOK(c.Create(mbox))
	} else {
		ReportOK(cmd, err)
	}
	ReportOK(c.List("", MBox))
	ReportOK(c.List("", mbox))
	ReportOK(c.Rename(mbox, mbox+"2"))
	ReportOK(c.Rename(mbox+"2", mbox))
	ReportOK(c.Subscribe(mbox))
	ReportOK(c.Unsubscribe(mbox))
	ReportOK(c.Status(mbox))
	ReportOK(c.Delete(mbox))

	ReportOK(c.Create(mbox))
	ReportOK(c.Select(mbox, true))
	ReportOK(c.Close(false))

	msg := []byte(strings.Replace(Msg[1:], "\n", "\r\n", -1))
	ReportOK(c.Append(mbox, nil, nil, imap.NewLiteral(msg)))

	ReportOK(c.Select(mbox, false))
	ReportOK(c.Check())

	fmt.Println(c.Mailbox)

	cmd = ReportOK(c.UIDSearch("SUBJECT", c.Quote("GoIMAP")))
	set, _ := imap.NewSeqSet("")
	set.AddNum(cmd.Data[0].SearchResults()...)

	ReportOK(c.Fetch(set, "FLAGS", "INTERNALDATE", "RFC822.SIZE", "BODY[]"))
	ReportOK(c.UIDStore(set, "+FLAGS.SILENT", imap.NewFlagSet(`\Deleted`)))
	ReportOK(c.Expunge(nil))
	ReportOK(c.UIDSearch("SUBJECT", c.Quote("GoIMAP")))

	fmt.Println(c.Mailbox)

	ReportOK(c.Close(true))
	ReportOK(c.Delete(mbox))
}
コード例 #18
0
ファイル: mailbox.go プロジェクト: justjake/mail
// gets all the messages on the server since the last message in the list
func (m *Mailbox) Update() (newMail []*Email, err error) {
	c, err := m.server.Connect()
	if err != nil {
		return nil, err
	}

	// sync imap command to select the mailbox for actions
	c.Select(m.Name, true)

	lastHad := m.latestMessage

	// retrieve items
	wanted := fmt.Sprintf("%d:*", lastHad)
	set, err := imap.NewSeqSet(wanted)
	if err != nil {
		return nil, err
	}
	cmd, err := c.UIDFetch(set, "RFC822.HEADER UID")
	if err != nil {
		return nil, err
	}

	// result
	newMail = make([]*Email, 0, 5)

	for cmd.InProgress() {
		// Wait for the next response (no timeout)
		c.Recv(-1)

		// Process command data

		// retrieve message UID
		// construct local Message structure from given header
		// store message in map
		// append UID to newMessages list
		for _, rsp := range cmd.Data {
			info := rsp.MessageInfo()
			if info.Attrs["UID"] != nil {
				// construct message
				header := imap.AsBytes(info.Attrs["RFC822.HEADER"])
				// TODO: catch this error
				if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
					// we could read the message and retrieve the UID
					// so this is valid to push into our storage system
					m.latestMessage = info.UID

					my_msg := &MessageNode{
						Header:      msg.Header,
						ContentType: msg.Header.Get(ContentType),
					}

					email := &Email{
						server:  m.server,
						mailbox: m,
						UID:     info.UID,
						Message: my_msg,
					}

					// store
					newMail = append(newMail, email)
					m.Mail[info.UID] = email
				} else {
					fmt.Printf("mail.ReadMessage failed on UID %d\n", info.UID)
				}
			} else {
				fmt.Printf("Message %v had no UID. Skipped.\n", info)
			}
		}

		// clear data
		cmd.Data = nil
	}

	return newMail, nil
}
コード例 #19
0
ファイル: copycat.go プロジェクト: jprobinson/copycat-imap
func AddDeletedFlag(conn *imap.Client, uid uint32) error {
	seqSet, _ := imap.NewSeqSet("")
	seqSet.AddNum(uid)
	_, err := conn.UIDStore(seqSet, "+FLAGS", imap.NewFlagSet(`\Deleted`))
	return err
}
コード例 #20
0
ファイル: readmail.go プロジェクト: llvtt/gomail
func main() {
	// Source: https://godoc.org/code.google.com/p/go-imap/go1/imap#example-Client
	// Note: most of error handling code is omitted for brevity
	//

	// Connect to the server
	c, _ = imap.DialTLS(IMAP_SERVER, nil)

	// 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(USERNAME, PASSWORD)
	}

	// 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-19, c.Mailbox.Messages)
	} else {
		set.Add("1:*")
	}
	cmd, _ = imap.Wait(c.Fetch(set, HEADER_PART_NAME))

	messages := make([]*imap.MessageInfo, 0, 0)
	for _, rsp = range cmd.Data {
		// May not be necessary to check for nil here.
		if msg := rsp.MessageInfo(); msg != nil {
			messages = append(messages, msg)
		}
	}
	listMessages(messages)

	// // 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[HEADER_PART_NAME])
	// 		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)
	// 	}
	// }

	//	render()
}
コード例 #21
0
ファイル: message.go プロジェクト: daffodil/go-mailkit
func GetMessage(folder, uid string, client *imap.Client) (messag *Message, e error) {

	cmd, err := client.Select(folder, true)
	if err != nil {
		return nil, err
	}

	uidlist, _ := imap.NewSeqSet(uid)
	//uidlist.Add(uid)

	fmt.Println("get_mess", folder, uid)
	mess := new(Message)
	mess.Folder = folder

	cmd, err = imap.Wait(client.UIDFetch(uidlist, "FLAGS", "INTERNALDATE", "RFC822.SIZE", "RFC822")) //  "RFC822.HEADER",  "BODY.PEEK[TEXT]") )
	if err != nil {
		return mess, err
	}
	fmt.Println(len(cmd.Data), cmd.Data)
	rsp := cmd.Data[0]
	minfo := rsp.MessageInfo()

	mess.Uid = minfo.UID

	msg, _ := mail.ReadMessage(bytes.NewReader(imap.AsBytes(minfo.Attrs["RFC822"])))
	mime, mime_err := enmime.ParseMIMEBody(msg)

	for flag, boo := range minfo.Flags {
		if flag == "\\Seen" && boo {
			mess.Seen = true
		}
		if flag == "\\Flagged" && boo {
			mess.Flagged = true
		}
	}
	/*
		bites := imap.AsBytes(minfo.Attrs["RFC822"])
		msg, msg_err := mail.ReadMessage(bytes.NewReader(bites))
		if msg_err != nil {
			return mess, msg_err
		}
	*/

	//fmt.Println(msg.Header.Get("Content-type"))
	//fmt.Println(msg.Header.Get("To"))
	//fmt.Println(msg.Header.Get("Delivered-To"))

	// From
	from, fro_err := mail.ParseAddress(msg.Header.Get("From"))
	if fro_err != nil {
		fmt.Println("address ettot")
	} else {
		mess.FromName = from.Name
		mess.FromEmail = from.Address
	}

	//for i, m := range minfo.Attrs {

	//fmt.Println(i,m)
	//}
	// Date
	dat := imap.AsDateTime(minfo.Attrs["INTERNALDATE"])
	mess.Date = dat.Format("2006-01-02 15:04:05")

	mess.Subject = msg.Header.Get("Subject")
	mess.ContentType = msg.Header.Get("Content-Type")
	//fmt.Println("body=", cmd.Data[0].String)

	//bodyb := imap.AsBytes(minfo.Attrs["BODY[TEXT]"])
	//bb := 	bytes.NewReader(bytes.NewReader(header + bodyb))

	//fmt.Println("bodyb=", string(msg.Body))

	//fmt.Printf("----\n%v\n", mime.Html == nil)
	//mess.Body = mime.Text
	if mime_err != nil {
		fmt.Println("err=", mime_err, mime)
	}
	//*/
	//fmt.Println("body=", body)

	mess.BodyText = mime.Text
	mess.BodyHtml = mime.Html //imap.AsString(minfo.Attrs["RFC822"])

	return mess, nil

}