package smtp import ( "fmt" "strings" ) // parseCommand zerlegt eine Kommandozeile in Verb (großgeschrieben) und // restliches Argument. func parseCommand(line string) (verb, arg string) { parts := strings.SplitN(strings.TrimSpace(line), " ", 2) verb = strings.ToUpper(parts[0]) if len(parts) == 2 { arg = strings.TrimSpace(parts[1]) } return verb, arg } // parseMailAddressArg extrahiert die Adresse aus "FROM:" bzw. // "TO:" (RFC 5321 §4.1.1.2/4.1.1.3). SMTP-Parameter wie SIZE=... // werden für diese kleinste Lösung ignoriert. func parseMailAddressArg(arg, keyword string) (string, error) { trimmed := strings.TrimSpace(arg) upper := strings.ToUpper(trimmed) prefix := keyword + ":" if !strings.HasPrefix(upper, prefix) { return "", fmt.Errorf("smtp: erwartete %q am anfang von %q", prefix, arg) } rest := strings.TrimSpace(trimmed[len(prefix):]) if sp := strings.IndexByte(rest, ' '); sp >= 0 { rest = rest[:sp] } rest = strings.TrimPrefix(rest, "<") rest = strings.TrimSuffix(rest, ">") if rest == "" { return "", fmt.Errorf("smtp: leere adresse") } return rest, nil } // validateAddress prüft eine E-Mail-Adresse defensiv gegen // Steuerzeichen und offensichtlich falsche Form (Akzeptanzkriterium 3: // ungültige Empfänger-/Absenderdaten führen zu sauberer Fehlermeldung // statt Absturz). func validateAddress(addr string) error { for _, r := range addr { if r < 0x20 || r == 0x7f { return fmt.Errorf("smtp: steuerzeichen in adresse") } } at := strings.IndexByte(addr, '@') if at <= 0 || at == len(addr)-1 { return fmt.Errorf("smtp: ungültige adresse %q", addr) } if strings.IndexByte(addr[at+1:], '@') >= 0 { return fmt.Errorf("smtp: ungültige adresse %q", addr) } return nil }