forked from aksdb/CalAnonSync
		
	Compare commits
	
		
			5 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 73a7754742 | |||
| 8d8cc94213 | |||
| 4d93b99cad | |||
| 10b96ec705 | |||
| cf04126d27 | 
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							@ -41,7 +41,12 @@ A config file named `calanonsync.json` is opened from the working directory. It
 | 
				
			|||||||
    "Password": ""
 | 
					    "Password": ""
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "Anonymize": {
 | 
					  "Anonymize": {
 | 
				
			||||||
    "Title": "#Work"
 | 
					    "Title": {
 | 
				
			||||||
 | 
					      "ReplaceWith": "#Work",
 | 
				
			||||||
 | 
					      "Whitelist": [
 | 
				
			||||||
 | 
					        "Something"
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
@ -49,3 +54,22 @@ A config file named `calanonsync.json` is opened from the working directory. It
 | 
				
			|||||||
Both passwords are optional. If they are left blank, CalAnonSync will prompt for the password upon startup. (Recommended for security reasons!)
 | 
					Both passwords are optional. If they are left blank, CalAnonSync will prompt for the password upon startup. (Recommended for security reasons!)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The CalDAV URL should point to the URL of a dedicated calendar. Beware that CalAnonSync will remove **all** events from that calendar that are not known to Exchange.
 | 
					The CalDAV URL should point to the URL of a dedicated calendar. Beware that CalAnonSync will remove **all** events from that calendar that are not known to Exchange.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Whitelist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If words (or phrases) are whitelisted, matches within the title for these words (or phrases) will be used as the
 | 
				
			||||||
 | 
					new title instead of the replacement. The order of these matches within the original title is kept, all non matching
 | 
				
			||||||
 | 
					parts of the title are simply stripped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Encryption
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to automate the sync process your probably have not much of a choice but storing the passwords
 | 
				
			||||||
 | 
					in the config file. Since plaintext passwords are always a big risk, CalAnonSync at least provides a simple
 | 
				
			||||||
 | 
					layer of eavesdropping security.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Using `calanonsync settings encrypt` you can encrypt all passwords in the config file. With `calanonsync settings decrypt`
 | 
				
			||||||
 | 
					you can revert that process.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Beware, that the encryption key is simply stored in a file alongside the config so it is really easy to decrypt.
 | 
				
			||||||
 | 
					It doesn't provide any security against a real attack and is only meant to prevent someone from getting access
 | 
				
			||||||
 | 
					to the password by looking over your shoulder.
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										22
									
								
								build.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								build.go
									
									
									
									
									
								
							@ -3,23 +3,37 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"flag"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var reproducible = flag.Bool("r", false, "If set, the build will remove local directories from the debug infos.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
 | 
						flag.Parse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	env := os.Environ()
 | 
						env := os.Environ()
 | 
				
			||||||
	wd, err := os.Getwd()
 | 
						wd, err := os.Getwd()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	env = append(env, "GOPATH="+wd)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	args := []string{"build"}
 | 
						env = append(env, "GOPATH="+wd, "CGO_ENABLED=0")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(os.Args) == 2 {
 | 
						args := []string{"build", "-ldflags=-s -w"}
 | 
				
			||||||
		target := os.Args[1]
 | 
					
 | 
				
			||||||
 | 
						if *reproducible {
 | 
				
			||||||
 | 
							args = append(args,
 | 
				
			||||||
 | 
								"-asmflags=all=-trimpath="+wd,
 | 
				
			||||||
 | 
								"-gcflags=all=-trimpath="+wd,
 | 
				
			||||||
 | 
								"-a",
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(flag.Args()) == 1 {
 | 
				
			||||||
 | 
							target := flag.Arg(0)
 | 
				
			||||||
		targetParts := strings.Split(target, "/")
 | 
							targetParts := strings.Split(target, "/")
 | 
				
			||||||
		if len(targetParts) != 2 {
 | 
							if len(targetParts) != 2 {
 | 
				
			||||||
			println("Invalid target specification. Example: windows/386")
 | 
								println("Invalid target specification. Example: windows/386")
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								src/calanonsync/Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										17
									
								
								src/calanonsync/Gopkg.lock
									
									
									
										generated
									
									
									
								
							@ -1,15 +1,6 @@
 | 
				
			|||||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
 | 
					# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[projects]]
 | 
					 | 
				
			||||||
  branch = "master"
 | 
					 | 
				
			||||||
  name = "github.com/ThomsonReutersEikon/go-ntlm"
 | 
					 | 
				
			||||||
  packages = [
 | 
					 | 
				
			||||||
    "ntlm",
 | 
					 | 
				
			||||||
    "ntlm/md4"
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
  revision = "2a7c173f9e18233a4ae29891da6a0a63637e2d8d"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[projects]]
 | 
					[[projects]]
 | 
				
			||||||
  name = "github.com/inconshreveable/mousetrap"
 | 
					  name = "github.com/inconshreveable/mousetrap"
 | 
				
			||||||
  packages = ["."]
 | 
					  packages = ["."]
 | 
				
			||||||
@ -28,12 +19,6 @@
 | 
				
			|||||||
  revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
 | 
					  revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
 | 
				
			||||||
  version = "v1.0.0"
 | 
					  version = "v1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[projects]]
 | 
					 | 
				
			||||||
  branch = "master"
 | 
					 | 
				
			||||||
  name = "github.com/vadimi/go-http-ntlm"
 | 
					 | 
				
			||||||
  packages = ["."]
 | 
					 | 
				
			||||||
  revision = "bc5a8d8d91a12dd386d3fa1019abb8bb681bdd41"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[projects]]
 | 
					[[projects]]
 | 
				
			||||||
  branch = "master"
 | 
					  branch = "master"
 | 
				
			||||||
  name = "golang.org/x/crypto"
 | 
					  name = "golang.org/x/crypto"
 | 
				
			||||||
@ -52,6 +37,6 @@
 | 
				
			|||||||
[solve-meta]
 | 
					[solve-meta]
 | 
				
			||||||
  analyzer-name = "dep"
 | 
					  analyzer-name = "dep"
 | 
				
			||||||
  analyzer-version = 1
 | 
					  analyzer-version = 1
 | 
				
			||||||
  inputs-digest = "8a1421bb063ff7faff2c4276042f954d7965c60c6a51afc95b658ac721cfcea0"
 | 
					  inputs-digest = "d2f5b5a67e95e173cd0d93a24576cdc1e5384e2bc0246f8cbed88838514b8ec0"
 | 
				
			||||||
  solver-name = "gps-cdcl"
 | 
					  solver-name = "gps-cdcl"
 | 
				
			||||||
  solver-version = 1
 | 
					  solver-version = 1
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,7 @@
 | 
				
			|||||||
#   go-tests = true
 | 
					#   go-tests = true
 | 
				
			||||||
#   unused-packages = true
 | 
					#   unused-packages = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ignored = ["github.com/vadimi/go-http-ntlm"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[prune]
 | 
					[prune]
 | 
				
			||||||
  go-tests = true
 | 
					  go-tests = true
 | 
				
			||||||
@ -33,14 +34,6 @@
 | 
				
			|||||||
  branch = "master"
 | 
					  branch = "master"
 | 
				
			||||||
  name = "golang.org/x/crypto"
 | 
					  name = "golang.org/x/crypto"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[constraint]]
 | 
					 | 
				
			||||||
  branch = "master"
 | 
					 | 
				
			||||||
  name = "github.com/vadimi/go-http-ntlm"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[constraint]]
 | 
					 | 
				
			||||||
  branch = "master"
 | 
					 | 
				
			||||||
  name = "github.com/Azure/go-ntlmssp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[constraint]]
 | 
					[[constraint]]
 | 
				
			||||||
  name = "github.com/spf13/cobra"
 | 
					  name = "github.com/spf13/cobra"
 | 
				
			||||||
  version = "0.0.2"
 | 
					  version = "0.0.2"
 | 
				
			||||||
 | 
				
			|||||||
@ -8,12 +8,17 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var syncSettings = struct {
 | 
				
			||||||
 | 
						rebuild bool
 | 
				
			||||||
 | 
					}{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	rootCmd := &cobra.Command{
 | 
						rootCmd := &cobra.Command{
 | 
				
			||||||
		Use:   "calanonsync",
 | 
							Use:   "calanonsync",
 | 
				
			||||||
		Short: "Synchronize a calendar from EWS to CalDAV by event time and an anonymized title only.",
 | 
							Short: "Synchronize a calendar from EWS to CalDAV by event time and an anonymized title only.",
 | 
				
			||||||
		Run:   runSynchronization,
 | 
							Run:   runSynchronization,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						rootCmd.Flags().BoolVar(&syncSettings.rebuild, "rebuild", false, "Rebuild all calendar items, no matter if they already exist.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rootCmd.AddCommand(InitSettingsCmd())
 | 
						rootCmd.AddCommand(InitSettingsCmd())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -66,6 +71,13 @@ func runSynchronization(cmd *cobra.Command, args []string) {
 | 
				
			|||||||
	for uid, calDavItem := range calDavItemMap {
 | 
						for uid, calDavItem := range calDavItemMap {
 | 
				
			||||||
		if ewsItem, ok := relevantEWSItems[uid]; ok {
 | 
							if ewsItem, ok := relevantEWSItems[uid]; ok {
 | 
				
			||||||
			// Good, so we still know the item at least.
 | 
								// Good, so we still know the item at least.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// If we want a full rebuild, we can skip this step
 | 
				
			||||||
 | 
								// since we will create new items anyway.
 | 
				
			||||||
 | 
								if syncSettings.rebuild {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !ewsItem.Start.Equal(calDavItem.Start()) ||
 | 
								if !ewsItem.Start.Equal(calDavItem.Start()) ||
 | 
				
			||||||
				!ewsItem.End.Equal(calDavItem.End()) {
 | 
									!ewsItem.End.Equal(calDavItem.End()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -92,9 +104,9 @@ func runSynchronization(cmd *cobra.Command, args []string) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find items we don't know so far and create them.
 | 
						// Find items we don't know so far and create them. Also recreate them if we want to rebuild all.
 | 
				
			||||||
	for uid, ewsItem := range relevantEWSItems {
 | 
						for uid, ewsItem := range relevantEWSItems {
 | 
				
			||||||
		if _, ok := calDavItemMap[uid]; !ok {
 | 
							if _, ok := calDavItemMap[uid]; !ok || syncSettings.rebuild {
 | 
				
			||||||
			title := s.Anonymize.Title.Apply(ewsItem.Subject)
 | 
								title := s.Anonymize.Title.Apply(ewsItem.Subject)
 | 
				
			||||||
			ical := CreateICal(ewsItem.Hash(), title, ewsItem.Start, ewsItem.End, ewsItem.IsAllDayEvent)
 | 
								ical := CreateICal(ewsItem.Hash(), title, ewsItem.Start, ewsItem.End, ewsItem.IsAllDayEvent)
 | 
				
			||||||
			calDavItem := CalDAVItem{HRef: uid + ".ics", ICal: ical}
 | 
								calDavItem := CalDAVItem{HRef: uid + ".ics", ICal: ical}
 | 
				
			||||||
 | 
				
			|||||||
@ -131,7 +131,13 @@ over-the-shoulder "attacks".`,
 | 
				
			|||||||
		Run:   runSettingsDecryption,
 | 
							Run:   runSettingsDecryption,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	settingsCmd.AddCommand(encryptCmd, decryptCmd)
 | 
						initCmd := &cobra.Command{
 | 
				
			||||||
 | 
							Use:   "init",
 | 
				
			||||||
 | 
							Short: "Initialize an empty but valid settings file.",
 | 
				
			||||||
 | 
							Run:   runSettingsInit,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						settingsCmd.AddCommand(encryptCmd, decryptCmd, initCmd)
 | 
				
			||||||
	return settingsCmd
 | 
						return settingsCmd
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -225,6 +231,30 @@ func runSettingsDecryption(cmd *cobra.Command, args []string) {
 | 
				
			|||||||
	log.Println("Settings decrypted")
 | 
						log.Println("Settings decrypted")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func runSettingsInit(cmd *cobra.Command, args []string) {
 | 
				
			||||||
 | 
						if _, err := os.Stat(settingsName); err == nil || os.IsExist(err) {
 | 
				
			||||||
 | 
							log.Fatalln("You already have a settings file! Remove that first if you really want a new blank one!")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s := Settings{}
 | 
				
			||||||
 | 
						s.Anonymize.Title = &StringAnonSettings{ReplaceWith: "Replacement", Whitelist: []string{}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Rewrite the settings file.
 | 
				
			||||||
 | 
						f, err := os.OpenFile(settingsName, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatalf("Could not rewrite settings: %s\n", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer f.Close()
 | 
				
			||||||
 | 
						e := json.NewEncoder(f)
 | 
				
			||||||
 | 
						e.SetIndent("", "  ")
 | 
				
			||||||
 | 
						err = e.Encode(&s)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Println("Blank settings have been created.")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Apply the anonymization rule to the given string, returning the
 | 
					// Apply the anonymization rule to the given string, returning the
 | 
				
			||||||
// anonymized version.
 | 
					// anonymized version.
 | 
				
			||||||
// If the anonymization is nil or empty, the original string will
 | 
					// If the anonymization is nil or empty, the original string will
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user